@solidstarters/solid-core 1.2.88 → 1.2.90
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.
- package/dist/controllers/export-template.controller.d.ts +3 -2
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.js +23 -10
- package/dist/controllers/export-template.controller.js.map +1 -1
- package/dist/controllers/import-transaction-error-log.controller.d.ts +41 -0
- package/dist/controllers/import-transaction-error-log.controller.d.ts.map +1 -0
- package/dist/controllers/import-transaction-error-log.controller.js +179 -0
- package/dist/controllers/import-transaction-error-log.controller.js.map +1 -0
- package/dist/controllers/import-transaction.controller.d.ts +46 -0
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -0
- package/dist/controllers/import-transaction.controller.js +236 -0
- package/dist/controllers/import-transaction.controller.js.map +1 -0
- package/dist/dtos/create-import-transaction-error-log.dto.d.ts +10 -0
- package/dist/dtos/create-import-transaction-error-log.dto.d.ts.map +1 -0
- package/dist/dtos/create-import-transaction-error-log.dto.js +65 -0
- package/dist/dtos/create-import-transaction-error-log.dto.js.map +1 -0
- package/dist/dtos/create-import-transaction.dto.d.ts +14 -0
- package/dist/dtos/create-import-transaction.dto.d.ts.map +1 -0
- package/dist/dtos/create-import-transaction.dto.js +90 -0
- package/dist/dtos/create-import-transaction.dto.js.map +1 -0
- package/dist/dtos/export.dto.d.ts +5 -0
- package/dist/dtos/export.dto.d.ts.map +1 -0
- package/dist/dtos/export.dto.js +12 -0
- package/dist/dtos/export.dto.js.map +1 -0
- package/dist/dtos/import-instructions.dto.d.ts +19 -0
- package/dist/dtos/import-instructions.dto.d.ts.map +1 -0
- package/dist/dtos/import-instructions.dto.js +110 -0
- package/dist/dtos/import-instructions.dto.js.map +1 -0
- package/dist/dtos/update-import-transaction-error-log.dto.d.ts +11 -0
- package/dist/dtos/update-import-transaction-error-log.dto.d.ts.map +1 -0
- package/dist/dtos/update-import-transaction-error-log.dto.js +72 -0
- package/dist/dtos/update-import-transaction-error-log.dto.js.map +1 -0
- package/dist/dtos/update-import-transaction.dto.d.ts +15 -0
- package/dist/dtos/update-import-transaction.dto.d.ts.map +1 -0
- package/dist/dtos/update-import-transaction.dto.js +91 -0
- package/dist/dtos/update-import-transaction.dto.js.map +1 -0
- package/dist/entities/export-transaction.entity.js +1 -1
- package/dist/entities/export-transaction.entity.js.map +1 -1
- package/dist/entities/import-transaction-error-log.entity.d.ts +11 -0
- package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -0
- package/dist/entities/import-transaction-error-log.entity.js +53 -0
- package/dist/entities/import-transaction-error-log.entity.js.map +1 -0
- package/dist/entities/import-transaction.entity.d.ts +11 -0
- package/dist/entities/import-transaction.entity.d.ts.map +1 -0
- package/dist/entities/import-transaction.entity.js +55 -0
- package/dist/entities/import-transaction.entity.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +317 -1
- package/dist/services/csv.service.d.ts +11 -1
- package/dist/services/csv.service.d.ts.map +1 -1
- package/dist/services/csv.service.js +72 -5
- package/dist/services/csv.service.js.map +1 -1
- package/dist/services/excel.service.d.ts +11 -1
- package/dist/services/excel.service.d.ts.map +1 -1
- package/dist/services/excel.service.js +68 -10
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/export-template.service.d.ts +3 -2
- package/dist/services/export-template.service.d.ts.map +1 -1
- package/dist/services/export-template.service.js +6 -6
- package/dist/services/export-template.service.js.map +1 -1
- package/dist/services/export-transaction.service.d.ts +6 -3
- package/dist/services/export-transaction.service.d.ts.map +1 -1
- package/dist/services/export-transaction.service.js +101 -22
- package/dist/services/export-transaction.service.js.map +1 -1
- package/dist/services/import-transaction-error-log.service.d.ts +22 -0
- package/dist/services/import-transaction-error-log.service.d.ts.map +1 -0
- package/dist/services/import-transaction-error-log.service.js +56 -0
- package/dist/services/import-transaction-error-log.service.js.map +1 -0
- package/dist/services/import-transaction.service.d.ts +64 -0
- package/dist/services/import-transaction.service.d.ts.map +1 -0
- package/dist/services/import-transaction.service.js +231 -0
- package/dist/services/import-transaction.service.js.map +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +13 -1
- package/dist/solid-core.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/controllers/export-template.controller.ts +20 -7
- package/src/controllers/import-transaction-error-log.controller.ts +93 -0
- package/src/controllers/import-transaction.controller.ts +128 -0
- package/src/dtos/create-import-transaction-error-log.dto.ts +34 -0
- package/src/dtos/create-import-transaction.dto.ts +50 -0
- package/src/dtos/export.dto.ts +5 -0
- package/src/dtos/import-instructions.dto.ts +66 -0
- package/src/dtos/update-import-transaction-error-log.dto.ts +39 -0
- package/src/dtos/update-import-transaction.dto.ts +52 -0
- package/src/entities/export-transaction.entity.ts +1 -1
- package/src/entities/import-transaction-error-log.entity.ts +22 -0
- package/src/entities/import-transaction.entity.ts +22 -0
- package/src/index.ts +2 -0
- package/src/seeders/seed-data/solid-core-metadata.json +319 -3
- package/src/services/csv.service.ts +116 -7
- package/src/services/excel.service.ts +109 -64
- package/src/services/export-template.service.ts +7 -6
- package/src/services/export-transaction.service.ts +136 -25
- package/src/services/export_issues.txt +5 -1
- package/src/services/import-transaction-error-log.service.ts +34 -0
- package/src/services/import-transaction.service.ts +281 -0
- package/src/solid-core.module.ts +13 -1
|
@@ -3414,7 +3414,7 @@
|
|
|
3414
3414
|
"ormType": "varchar",
|
|
3415
3415
|
"length": 256,
|
|
3416
3416
|
"required": true,
|
|
3417
|
-
"unique": true,
|
|
3417
|
+
"unique": true,
|
|
3418
3418
|
"index": true,
|
|
3419
3419
|
"private": false,
|
|
3420
3420
|
"encrypt": false,
|
|
@@ -3506,7 +3506,7 @@
|
|
|
3506
3506
|
{
|
|
3507
3507
|
"name": "exportTransactionId",
|
|
3508
3508
|
"displayName": "Transaction Id",
|
|
3509
|
-
"type":"computed",
|
|
3509
|
+
"type": "computed",
|
|
3510
3510
|
"ormType": "varchar",
|
|
3511
3511
|
"length": 128,
|
|
3512
3512
|
"required": true,
|
|
@@ -3564,7 +3564,7 @@
|
|
|
3564
3564
|
"displayName": "Related Export Template",
|
|
3565
3565
|
"type": "relation",
|
|
3566
3566
|
"ormType": "int",
|
|
3567
|
-
"required":
|
|
3567
|
+
"required": false,
|
|
3568
3568
|
"unique": false,
|
|
3569
3569
|
"index": true,
|
|
3570
3570
|
"private": false,
|
|
@@ -3577,6 +3577,201 @@
|
|
|
3577
3577
|
"isSystem": true
|
|
3578
3578
|
}
|
|
3579
3579
|
]
|
|
3580
|
+
},
|
|
3581
|
+
{
|
|
3582
|
+
"singularName": "importTransaction",
|
|
3583
|
+
"tableName": "ss_import_transaction",
|
|
3584
|
+
"pluralName": "importTransactions",
|
|
3585
|
+
"displayName": "Import Transactions",
|
|
3586
|
+
"description": "Model to capture all information related to a file import transaction",
|
|
3587
|
+
"dataSource": "default",
|
|
3588
|
+
"dataSourceType": "postgres",
|
|
3589
|
+
"isSystem": true,
|
|
3590
|
+
"userKeyFieldUserKey": "importTransactionId",
|
|
3591
|
+
"fields": [
|
|
3592
|
+
{
|
|
3593
|
+
"name": "status",
|
|
3594
|
+
"displayName": "Status",
|
|
3595
|
+
"type": "selectionStatic",
|
|
3596
|
+
"ormType": "varchar",
|
|
3597
|
+
"length": 25,
|
|
3598
|
+
"required": false,
|
|
3599
|
+
"index": true,
|
|
3600
|
+
"isSystem": true,
|
|
3601
|
+
"selectionValueType": "string",
|
|
3602
|
+
"selectionStaticValues": [
|
|
3603
|
+
"draft:draft",
|
|
3604
|
+
"mapping_created:mapping_created",
|
|
3605
|
+
"import_started:import_started",
|
|
3606
|
+
"import_succeeded:import_succeeded",
|
|
3607
|
+
"import_failed:import_failed"
|
|
3608
|
+
],
|
|
3609
|
+
"defaultValue": "draft"
|
|
3610
|
+
},
|
|
3611
|
+
{
|
|
3612
|
+
"name": "importTransactionId",
|
|
3613
|
+
"displayName": "Transaction Id",
|
|
3614
|
+
"type": "shortText",
|
|
3615
|
+
"ormType": "varchar",
|
|
3616
|
+
"length": 128,
|
|
3617
|
+
"required": false,
|
|
3618
|
+
"unique": true,
|
|
3619
|
+
"index": true,
|
|
3620
|
+
"private": false,
|
|
3621
|
+
"encrypt": false,
|
|
3622
|
+
"isSystem": true
|
|
3623
|
+
},
|
|
3624
|
+
{
|
|
3625
|
+
"name": "fileLocation",
|
|
3626
|
+
"displayName": "File Location",
|
|
3627
|
+
"type": "mediaSingle",
|
|
3628
|
+
"required": true,
|
|
3629
|
+
"unique": true,
|
|
3630
|
+
"index": false,
|
|
3631
|
+
"private": false,
|
|
3632
|
+
"encrypt": false,
|
|
3633
|
+
"isSystem": true,
|
|
3634
|
+
"mediaStorageProviderUserKey": "default-filesystem"
|
|
3635
|
+
},
|
|
3636
|
+
{
|
|
3637
|
+
"name": "mapping",
|
|
3638
|
+
"displayName": "Mapping",
|
|
3639
|
+
"type": "json",
|
|
3640
|
+
"ormType": "text",
|
|
3641
|
+
"required": false,
|
|
3642
|
+
"unique": false,
|
|
3643
|
+
"index": false,
|
|
3644
|
+
"private": false,
|
|
3645
|
+
"encrypt": false,
|
|
3646
|
+
"isSystem": true
|
|
3647
|
+
},
|
|
3648
|
+
{
|
|
3649
|
+
"name": "modelMetadata",
|
|
3650
|
+
"displayName": "Related Model Metadata",
|
|
3651
|
+
"type": "relation",
|
|
3652
|
+
"ormType": "int",
|
|
3653
|
+
"required": false,
|
|
3654
|
+
"unique": false,
|
|
3655
|
+
"index": true,
|
|
3656
|
+
"private": false,
|
|
3657
|
+
"encrypt": false,
|
|
3658
|
+
"relationType": "many-to-one",
|
|
3659
|
+
"relationCoModelSingularName": "modelMetadata",
|
|
3660
|
+
"relationCreateInverse": false,
|
|
3661
|
+
"relationCascade": "cascade",
|
|
3662
|
+
"relationModelModuleName": "solid-core",
|
|
3663
|
+
"isSystem": true
|
|
3664
|
+
},
|
|
3665
|
+
{
|
|
3666
|
+
"name": "importTransactionErrorLog",
|
|
3667
|
+
"displayName": "Related Import Transaction Error Log",
|
|
3668
|
+
"type": "relation",
|
|
3669
|
+
"required": false,
|
|
3670
|
+
"unique": false,
|
|
3671
|
+
"index": true,
|
|
3672
|
+
"private": false,
|
|
3673
|
+
"encrypt": false,
|
|
3674
|
+
"relationType": "one-to-many",
|
|
3675
|
+
"relationCoModelFieldName": "importTransaction",
|
|
3676
|
+
"relationCreateInverse": true,
|
|
3677
|
+
"relationCoModelSingularName": "importTransactionErrorLog",
|
|
3678
|
+
"relationCoModelColumnName": "",
|
|
3679
|
+
"relationModelModuleName": "solid-core"
|
|
3680
|
+
}
|
|
3681
|
+
]
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
"singularName": "importTransactionErrorLog",
|
|
3685
|
+
"tableName": "ss_import_transaction_error_log",
|
|
3686
|
+
"pluralName": "importTransactionErrorLogs",
|
|
3687
|
+
"displayName": "Import Transaction Error Logs",
|
|
3688
|
+
"description": "Model to capture all information related to a file import transaction error log",
|
|
3689
|
+
"dataSource": "default",
|
|
3690
|
+
"dataSourceType": "postgres",
|
|
3691
|
+
"isSystem": true,
|
|
3692
|
+
"userKeyFieldUserKey": "importTransactionErrorLogId",
|
|
3693
|
+
"fields": [
|
|
3694
|
+
{
|
|
3695
|
+
"name": "importTransactionErrorLogId",
|
|
3696
|
+
"displayName": "Import Transaction Error Log Id",
|
|
3697
|
+
"type": "shortText",
|
|
3698
|
+
"ormType": "varchar",
|
|
3699
|
+
"length": 256,
|
|
3700
|
+
"required": true,
|
|
3701
|
+
"unique": true,
|
|
3702
|
+
"index": true,
|
|
3703
|
+
"private": false,
|
|
3704
|
+
"encrypt": false,
|
|
3705
|
+
"isSystem": true
|
|
3706
|
+
},
|
|
3707
|
+
{
|
|
3708
|
+
"name": "rowNumber",
|
|
3709
|
+
"displayName": "Row Number",
|
|
3710
|
+
"type": "int",
|
|
3711
|
+
"ormType": "integer",
|
|
3712
|
+
"required": true,
|
|
3713
|
+
"unique": false,
|
|
3714
|
+
"index": false,
|
|
3715
|
+
"private": false,
|
|
3716
|
+
"encrypt": false,
|
|
3717
|
+
"isSystem": true
|
|
3718
|
+
},
|
|
3719
|
+
{
|
|
3720
|
+
"name": "rowData",
|
|
3721
|
+
"displayName": "Row Data",
|
|
3722
|
+
"type": "json",
|
|
3723
|
+
"ormType": "text",
|
|
3724
|
+
"required": false,
|
|
3725
|
+
"unique": false,
|
|
3726
|
+
"index": false,
|
|
3727
|
+
"private": false,
|
|
3728
|
+
"encrypt": false,
|
|
3729
|
+
"isSystem": true
|
|
3730
|
+
},
|
|
3731
|
+
{
|
|
3732
|
+
"name": "importTransaction",
|
|
3733
|
+
"displayName": "Related Import Transaction",
|
|
3734
|
+
"type": "relation",
|
|
3735
|
+
"ormType": "int",
|
|
3736
|
+
"required": true,
|
|
3737
|
+
"unique": false,
|
|
3738
|
+
"index": true,
|
|
3739
|
+
"private": false,
|
|
3740
|
+
"encrypt": false,
|
|
3741
|
+
"relationType": "many-to-one",
|
|
3742
|
+
"relationCoModelFieldName": "importTransactionErrorLogs",
|
|
3743
|
+
"relationCreateInverse": true,
|
|
3744
|
+
"relationCoModelSingularName": "importTransaction",
|
|
3745
|
+
"relationCoModelColumnName": "",
|
|
3746
|
+
"relationModelModuleName": "solid-core",
|
|
3747
|
+
"relationCascade": "cascade"
|
|
3748
|
+
},
|
|
3749
|
+
{
|
|
3750
|
+
"name": "errorMessage",
|
|
3751
|
+
"displayName": "Error Message",
|
|
3752
|
+
"type": "shortText",
|
|
3753
|
+
"ormType": "varchar",
|
|
3754
|
+
"length": 512,
|
|
3755
|
+
"required": true,
|
|
3756
|
+
"unique": false,
|
|
3757
|
+
"index": false,
|
|
3758
|
+
"private": false,
|
|
3759
|
+
"encrypt": false,
|
|
3760
|
+
"isSystem": true
|
|
3761
|
+
},
|
|
3762
|
+
{
|
|
3763
|
+
"name": "errorTrace",
|
|
3764
|
+
"displayName": "Error Trace",
|
|
3765
|
+
"type": "longText",
|
|
3766
|
+
"ormType": "text",
|
|
3767
|
+
"required": false,
|
|
3768
|
+
"unique": false,
|
|
3769
|
+
"index": false,
|
|
3770
|
+
"private": false,
|
|
3771
|
+
"encrypt": false,
|
|
3772
|
+
"isSystem": true
|
|
3773
|
+
}
|
|
3774
|
+
]
|
|
3580
3775
|
}
|
|
3581
3776
|
]
|
|
3582
3777
|
},
|
|
@@ -3915,6 +4110,19 @@
|
|
|
3915
4110
|
"viewUserKey": "listOfValues-list-view",
|
|
3916
4111
|
"moduleUserKey": "solid-core",
|
|
3917
4112
|
"modelUserKey": "listOfValues"
|
|
4113
|
+
},
|
|
4114
|
+
{
|
|
4115
|
+
"displayName": "Import Transactions List View",
|
|
4116
|
+
"name": "importTransaction-list-view",
|
|
4117
|
+
"type": "solid",
|
|
4118
|
+
"domain": "",
|
|
4119
|
+
"context": "",
|
|
4120
|
+
"customComponent": "/admin/address-master/importTransaction/all",
|
|
4121
|
+
"customIsModal": true,
|
|
4122
|
+
"serverEndpoint": "",
|
|
4123
|
+
"viewUserKey": "importTransaction-list-view",
|
|
4124
|
+
"moduleUserKey": "solid-core",
|
|
4125
|
+
"modelUserKey": "importTransaction"
|
|
3918
4126
|
}
|
|
3919
4127
|
],
|
|
3920
4128
|
"menus": [
|
|
@@ -4149,6 +4357,14 @@
|
|
|
4149
4357
|
"actionUserKey": "chatter-message-details-list-action",
|
|
4150
4358
|
"moduleUserKey": "solid-core",
|
|
4151
4359
|
"parentMenuItemUserKey": "other-menu-item"
|
|
4360
|
+
},
|
|
4361
|
+
{
|
|
4362
|
+
"displayName": "Import Transactions",
|
|
4363
|
+
"name": "importTransaction-menu-item",
|
|
4364
|
+
"sequenceNumber": 1,
|
|
4365
|
+
"actionUserKey": "importTransaction-list-view",
|
|
4366
|
+
"moduleUserKey": "solid-core",
|
|
4367
|
+
"parentMenuItemUserKey": ""
|
|
4152
4368
|
}
|
|
4153
4369
|
],
|
|
4154
4370
|
"views": [
|
|
@@ -8750,6 +8966,106 @@
|
|
|
8750
8966
|
}
|
|
8751
8967
|
]
|
|
8752
8968
|
}
|
|
8969
|
+
},
|
|
8970
|
+
{
|
|
8971
|
+
"name": "importTransaction-list-view",
|
|
8972
|
+
"displayName": "Import Transactions",
|
|
8973
|
+
"type": "list",
|
|
8974
|
+
"context": "{}",
|
|
8975
|
+
"moduleUserKey": "solid-core",
|
|
8976
|
+
"modelUserKey": "importTransaction",
|
|
8977
|
+
"layout": {
|
|
8978
|
+
"type": "list",
|
|
8979
|
+
"attrs": {
|
|
8980
|
+
"pagination": true,
|
|
8981
|
+
"pageSizeOptions": [
|
|
8982
|
+
10,
|
|
8983
|
+
25,
|
|
8984
|
+
50
|
|
8985
|
+
],
|
|
8986
|
+
"enableGlobalSearch": true,
|
|
8987
|
+
"create": true,
|
|
8988
|
+
"edit": true,
|
|
8989
|
+
"delete": true
|
|
8990
|
+
},
|
|
8991
|
+
"children": [
|
|
8992
|
+
{
|
|
8993
|
+
"type": "field",
|
|
8994
|
+
"attrs": {
|
|
8995
|
+
"name": "id",
|
|
8996
|
+
"sortable": true,
|
|
8997
|
+
"filterable": true
|
|
8998
|
+
}
|
|
8999
|
+
},
|
|
9000
|
+
{
|
|
9001
|
+
"type": "field",
|
|
9002
|
+
"attrs": {
|
|
9003
|
+
"name": "importTransactionErrorLog",
|
|
9004
|
+
"sortable": true,
|
|
9005
|
+
"filterable": true
|
|
9006
|
+
}
|
|
9007
|
+
}
|
|
9008
|
+
]
|
|
9009
|
+
}
|
|
9010
|
+
},
|
|
9011
|
+
{
|
|
9012
|
+
"name": "importTransaction-form-view",
|
|
9013
|
+
"displayName": "Import Transactions",
|
|
9014
|
+
"type": "form",
|
|
9015
|
+
"context": "{}",
|
|
9016
|
+
"moduleUserKey": "solid-core",
|
|
9017
|
+
"modelUserKey": "importTransaction",
|
|
9018
|
+
"layout": {
|
|
9019
|
+
"type": "form",
|
|
9020
|
+
"attrs": {
|
|
9021
|
+
"name": "form-1",
|
|
9022
|
+
"label": "Import Transactions",
|
|
9023
|
+
"className": "grid"
|
|
9024
|
+
},
|
|
9025
|
+
"children": [
|
|
9026
|
+
{
|
|
9027
|
+
"type": "sheet",
|
|
9028
|
+
"attrs": {
|
|
9029
|
+
"name": "sheet-1"
|
|
9030
|
+
},
|
|
9031
|
+
"children": [
|
|
9032
|
+
{
|
|
9033
|
+
"type": "row",
|
|
9034
|
+
"attrs": {
|
|
9035
|
+
"name": "sheet-1"
|
|
9036
|
+
},
|
|
9037
|
+
"children": [
|
|
9038
|
+
{
|
|
9039
|
+
"type": "column",
|
|
9040
|
+
"attrs": {
|
|
9041
|
+
"name": "group-1",
|
|
9042
|
+
"label": "",
|
|
9043
|
+
"className": "col-6"
|
|
9044
|
+
},
|
|
9045
|
+
"children": [
|
|
9046
|
+
{
|
|
9047
|
+
"type": "field",
|
|
9048
|
+
"attrs": {
|
|
9049
|
+
"name": "importTransactionErrorLog"
|
|
9050
|
+
}
|
|
9051
|
+
}
|
|
9052
|
+
]
|
|
9053
|
+
},
|
|
9054
|
+
{
|
|
9055
|
+
"type": "column",
|
|
9056
|
+
"attrs": {
|
|
9057
|
+
"name": "group-2",
|
|
9058
|
+
"label": "",
|
|
9059
|
+
"className": "col-6"
|
|
9060
|
+
},
|
|
9061
|
+
"children": []
|
|
9062
|
+
}
|
|
9063
|
+
]
|
|
9064
|
+
}
|
|
9065
|
+
]
|
|
9066
|
+
}
|
|
9067
|
+
]
|
|
9068
|
+
}
|
|
8753
9069
|
}
|
|
8754
9070
|
],
|
|
8755
9071
|
"emailTemplates": [
|
|
@@ -1,22 +1,59 @@
|
|
|
1
|
-
import { PassThrough, Readable } from 'stream';
|
|
2
|
-
import { format } from 'fast-csv';
|
|
3
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
import { format, parse } from 'fast-csv';
|
|
3
|
+
import { PassThrough, Readable } from 'stream';
|
|
4
|
+
|
|
5
|
+
export interface CsvReadOptions {
|
|
6
|
+
pageSize?: number; // Number of records per page
|
|
7
|
+
hasHeaderRow?: boolean;
|
|
8
|
+
providedHeaders?: string[]
|
|
9
|
+
};
|
|
10
|
+
const DEFAULT_PAGE_SIZE = 100; // Default page size if not provided
|
|
11
|
+
export interface CsvReadResult {
|
|
12
|
+
headers: string[]; // Headers of the CSV file
|
|
13
|
+
data: Record<string, any>[]; // Data records in the current page
|
|
14
|
+
}
|
|
4
15
|
|
|
5
16
|
@Injectable()
|
|
6
17
|
export class CsvService {
|
|
7
18
|
private logger = new Logger(CsvService.name);
|
|
8
19
|
public async createCsvStream(
|
|
9
|
-
getDataRecords: (chunkIndex: number, chunkSize: number) => Promise<any[]
|
|
10
|
-
chunkSize: number
|
|
20
|
+
getDataRecords: (chunkIndex: number, chunkSize: number) => Promise<any[]> = null,
|
|
21
|
+
chunkSize: number = 100,
|
|
22
|
+
headers: string[] = []
|
|
11
23
|
): Promise<Readable> {
|
|
24
|
+
// Validations
|
|
25
|
+
// If neither headers nor data records function is provided, throw an error
|
|
26
|
+
if (headers.length === 0 && typeof getDataRecords !== 'function') {
|
|
27
|
+
throw new Error('Either headers or data records function must be provided.');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// If data records function is provided, chunkSize must be greater than 0
|
|
31
|
+
if (getDataRecords && chunkSize <= 0) {
|
|
32
|
+
throw new Error('Chunk size must be greater than 0 when data records function is provided.');
|
|
33
|
+
}
|
|
34
|
+
|
|
12
35
|
const passThrough = new PassThrough(); // ✅ Create a streaming pipe
|
|
13
|
-
const csvStream =
|
|
36
|
+
const csvStream = headers.length
|
|
37
|
+
? format({ headers })
|
|
38
|
+
: format({ headers: true });
|
|
14
39
|
|
|
15
40
|
csvStream.pipe(passThrough); // ✅ Pipe CSV output to PassThrough stream
|
|
16
41
|
|
|
17
|
-
let chunkIndex = 0;
|
|
18
|
-
|
|
19
42
|
try {
|
|
43
|
+
// 🧠 If no data retrieval logic is provided, just write headers and close
|
|
44
|
+
if (typeof getDataRecords !== 'function') {
|
|
45
|
+
|
|
46
|
+
const dummyRow = headers.reduce((acc, header) => {
|
|
47
|
+
acc[header] = '';
|
|
48
|
+
return acc;
|
|
49
|
+
}, {} as Record<string, string>);
|
|
50
|
+
csvStream.write(dummyRow);
|
|
51
|
+
csvStream.end();
|
|
52
|
+
return passThrough;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Write the data records in chunks
|
|
56
|
+
let chunkIndex = 0;
|
|
20
57
|
while (true) {
|
|
21
58
|
const records = await getDataRecords(chunkIndex, chunkSize); // ✅ Fetch chunked data
|
|
22
59
|
if (records.length === 0) break; // ✅ Stop if no more records
|
|
@@ -38,4 +75,76 @@ export class CsvService {
|
|
|
38
75
|
|
|
39
76
|
return passThrough; // ✅ Return the streaming response
|
|
40
77
|
}
|
|
78
|
+
|
|
79
|
+
public async *readCsvInPagesFromStream(
|
|
80
|
+
stream: Readable,
|
|
81
|
+
options?: CsvReadOptions
|
|
82
|
+
): AsyncGenerator<CsvReadResult> {
|
|
83
|
+
const { pageSize = DEFAULT_PAGE_SIZE, hasHeaderRow = true, providedHeaders = [] } = options || {};
|
|
84
|
+
let headers: string[] = [];
|
|
85
|
+
let page: Record<string, any>[] = [];
|
|
86
|
+
let isFirstRow = true;
|
|
87
|
+
let hasYieldedData = false;
|
|
88
|
+
|
|
89
|
+
// Create parser
|
|
90
|
+
const parser = parse({ headers: hasHeaderRow, renameHeaders: false, trim: true });
|
|
91
|
+
|
|
92
|
+
// Pipe the input stream into the parser
|
|
93
|
+
const parsingStream = stream.pipe(parser);
|
|
94
|
+
|
|
95
|
+
for await (const row of parsingStream) {
|
|
96
|
+
if (isFirstRow && !hasHeaderRow) {
|
|
97
|
+
isFirstRow = false;
|
|
98
|
+
|
|
99
|
+
if (providedHeaders.length) {
|
|
100
|
+
headers = providedHeaders;
|
|
101
|
+
} else {
|
|
102
|
+
// If no header row and no provided headers, generate index-based headers
|
|
103
|
+
headers = Object.keys(row).length > 0 ? Object.keys(row).map((_, i) => i.toString()) : [];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// If hasHeaderRow = true, fast-csv already assigns keys as headers, so capture once
|
|
108
|
+
if (hasHeaderRow && isFirstRow) {
|
|
109
|
+
headers = Object.keys(row);
|
|
110
|
+
isFirstRow = false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// When headers are not set yet (edge case), set them now
|
|
114
|
+
if (!headers.length) {
|
|
115
|
+
headers = providedHeaders.length ? providedHeaders : Object.keys(row);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Map row fields to headers - if keys mismatch, fallback to index-based mapping
|
|
119
|
+
const record: Record<string, any> = {};
|
|
120
|
+
for (let i = 0; i < headers.length; i++) {
|
|
121
|
+
// For safety, access by header name or fallback by index
|
|
122
|
+
const key = headers[i];
|
|
123
|
+
const value = row[key] ?? Object.values(row)[i] ?? null;
|
|
124
|
+
record[key] = value;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Skip empty rows
|
|
128
|
+
if (Object.values(record).every(v => v === null || v === '')) continue;
|
|
129
|
+
|
|
130
|
+
page.push(record);
|
|
131
|
+
|
|
132
|
+
if (page.length === pageSize) {
|
|
133
|
+
yield { headers, data: page };
|
|
134
|
+
hasYieldedData = true;
|
|
135
|
+
page = [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (page.length > 0) {
|
|
140
|
+
yield { headers, data: page };
|
|
141
|
+
hasYieldedData = true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// If only headers present but no data, yield headers with empty data array
|
|
145
|
+
if (!hasYieldedData && headers.length > 0) {
|
|
146
|
+
yield { headers, data: [] };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
41
150
|
}
|