@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.56
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/CHANGELOG.md +12 -0
- package/README.md +11 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,772 +1,772 @@
|
|
|
1
|
-
# Module 2: CSV Parser
|
|
2
|
-
|
|
3
|
-
**Level:** Beginner
|
|
4
|
-
**Estimated Time:** 20 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module covers the CSV Parser (`CSVParserService`), the most common parser for inventory and product data feeds. You'll learn how to parse CSV files, validate data, handle large files with streaming, and integrate with SDK transformation services.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Parse CSV files into structured JavaScript objects
|
|
14
|
-
- ✅ Configure parser options for different CSV formats
|
|
15
|
-
- ✅ Stream large CSV files efficiently
|
|
16
|
-
- ✅ Validate CSV structure and data types
|
|
17
|
-
- ✅ Transform CSV data with UniversalMapper
|
|
18
|
-
|
|
19
|
-
## What is CSV?
|
|
20
|
-
|
|
21
|
-
**CSV (Comma-Separated Values)** is a simple tabular format where:
|
|
22
|
-
- Each line represents a record
|
|
23
|
-
- Fields are separated by commas (or other delimiters)
|
|
24
|
-
- First line typically contains column headers
|
|
25
|
-
- Text values may be quoted
|
|
26
|
-
|
|
27
|
-
**Example:**
|
|
28
|
-
```csv
|
|
29
|
-
sku,name,qty,location
|
|
30
|
-
SKU001,Wireless Mouse,100,WH-01
|
|
31
|
-
SKU002,Keyboard,50,WH-01
|
|
32
|
-
SKU003,Monitor,25,WH-02
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Basic CSV Parsing
|
|
36
|
-
|
|
37
|
-
### Simple Parsing
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
41
|
-
|
|
42
|
-
const csvParser = new CSVParserService();
|
|
43
|
-
|
|
44
|
-
// Sample CSV data
|
|
45
|
-
const csvContent = `sku,qty,location
|
|
46
|
-
SKU001,100,WH-01
|
|
47
|
-
SKU002,50,WH-01
|
|
48
|
-
SKU003,75,WH-02`;
|
|
49
|
-
|
|
50
|
-
// Parse CSV
|
|
51
|
-
const records = await csvParser.parse(csvContent);
|
|
52
|
-
|
|
53
|
-
console.log(records);
|
|
54
|
-
// [
|
|
55
|
-
// { sku: 'SKU001', qty: '100', location: 'WH-01' },
|
|
56
|
-
// { sku: 'SKU002', qty: '50', location: 'WH-01' },
|
|
57
|
-
// { sku: 'SKU003', qty: '75', location: 'WH-02' }
|
|
58
|
-
// ]
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Type Safety with TypeScript
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
// Define your record structure
|
|
65
|
-
interface InventoryRecord {
|
|
66
|
-
sku: string;
|
|
67
|
-
qty: string;
|
|
68
|
-
location: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Parse with type assertion
|
|
72
|
-
const records = await csvParser.parse<InventoryRecord>(csvContent);
|
|
73
|
-
|
|
74
|
-
// Now you have full type safety
|
|
75
|
-
records.forEach(record => {
|
|
76
|
-
console.log(`${record.sku}: ${record.qty} units at ${record.location}`);
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Parser Configuration
|
|
81
|
-
|
|
82
|
-
The CSV parser supports various options to handle different CSV formats:
|
|
83
|
-
|
|
84
|
-
### Common Options
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
88
|
-
import type { Options as CSVOptions } from 'csv-parse';
|
|
89
|
-
|
|
90
|
-
const csvParser = new CSVParserService();
|
|
91
|
-
|
|
92
|
-
const options: CSVOptions = {
|
|
93
|
-
// Column headers (default: true - first row is headers)
|
|
94
|
-
columns: true,
|
|
95
|
-
|
|
96
|
-
// Skip empty lines (default: true)
|
|
97
|
-
skip_empty_lines: true,
|
|
98
|
-
|
|
99
|
-
// Trim whitespace (default: true)
|
|
100
|
-
trim: true,
|
|
101
|
-
|
|
102
|
-
// Custom delimiter (default: ',')
|
|
103
|
-
delimiter: ',',
|
|
104
|
-
|
|
105
|
-
// Quote character (default: '"')
|
|
106
|
-
quote: '"',
|
|
107
|
-
|
|
108
|
-
// Escape character (default: '"')
|
|
109
|
-
escape: '"',
|
|
110
|
-
|
|
111
|
-
// Skip first N rows
|
|
112
|
-
from_line: 1
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const records = await csvParser.parse(csvContent, options);
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Handling Different Delimiters
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// Tab-separated values (TSV)
|
|
122
|
-
const tsvContent = `sku\tqty\tlocation
|
|
123
|
-
SKU001\t100\tWH-01`;
|
|
124
|
-
|
|
125
|
-
const tsvRecords = await csvParser.parse(tsvContent, {
|
|
126
|
-
delimiter: '\t'
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Pipe-separated values
|
|
130
|
-
const pipeSeparated = `sku|qty|location
|
|
131
|
-
SKU001|100|WH-01`;
|
|
132
|
-
|
|
133
|
-
const pipeRecords = await csvParser.parse(pipeSeparated, {
|
|
134
|
-
delimiter: '|'
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Semicolon-separated (European format)
|
|
138
|
-
const europeanCSV = `sku;qty;location
|
|
139
|
-
SKU001;100;WH-01`;
|
|
140
|
-
|
|
141
|
-
const records = await csvParser.parse(europeanCSV, {
|
|
142
|
-
delimiter: ';'
|
|
143
|
-
});
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Custom Column Names
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
// CSV without headers
|
|
150
|
-
const noHeadersCSV = `SKU001,100,WH-01
|
|
151
|
-
SKU002,50,WH-01`;
|
|
152
|
-
|
|
153
|
-
// Provide custom column names
|
|
154
|
-
const records = await csvParser.parse(noHeadersCSV, {
|
|
155
|
-
columns: ['sku', 'qty', 'location']
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
console.log(records);
|
|
159
|
-
// [
|
|
160
|
-
// { sku: 'SKU001', qty: '100', location: 'WH-01' },
|
|
161
|
-
// { sku: 'SKU002', qty: '50', location: 'WH-01' }
|
|
162
|
-
// ]
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Skipping Rows
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
// Skip first 2 rows (e.g., title row + header row)
|
|
169
|
-
const csvWithTitle = `Inventory Export - 2025-01-15
|
|
170
|
-
sku,qty,location
|
|
171
|
-
SKU001,100,WH-01
|
|
172
|
-
SKU002,50,WH-01`;
|
|
173
|
-
|
|
174
|
-
const records = await csvParser.parse(csvWithTitle, {
|
|
175
|
-
from_line: 2 // Start from line 2 (headers)
|
|
176
|
-
});
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## Streaming Large Files
|
|
180
|
-
|
|
181
|
-
For large CSV files, use streaming to avoid memory issues:
|
|
182
|
-
|
|
183
|
-
### Basic Streaming
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
187
|
-
|
|
188
|
-
const csvParser = new CSVParserService();
|
|
189
|
-
|
|
190
|
-
// Large CSV content (e.g., from S3)
|
|
191
|
-
const largeCsvContent = `...`; // Thousands of rows
|
|
192
|
-
|
|
193
|
-
// Process records one by one
|
|
194
|
-
for await (const record of csvParser.parseStreaming(largeCsvContent)) {
|
|
195
|
-
console.log('Processing record:', record);
|
|
196
|
-
// Process each record individually
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Batch Streaming
|
|
201
|
-
|
|
202
|
-
Process records in batches for better performance:
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
const batchSize = 100;
|
|
206
|
-
|
|
207
|
-
// Process in batches of 100 records
|
|
208
|
-
for await (const batch of csvParser.parseStreaming(largeCsvContent, {}, batchSize)) {
|
|
209
|
-
console.log(`Processing batch of ${batch.length} records`);
|
|
210
|
-
|
|
211
|
-
// Process batch (e.g., send to Fluent Batch API)
|
|
212
|
-
await processBatch(batch);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function processBatch(records: any[]) {
|
|
216
|
-
// Transform and send to Fluent
|
|
217
|
-
console.log(`Batch processing ${records.length} records`);
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Streaming with Progress Tracking
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
async function streamWithProgress(csvContent: string) {
|
|
225
|
-
const csvParser = new CSVParserService();
|
|
226
|
-
const startTime = Date.now();
|
|
227
|
-
let recordCount = 0;
|
|
228
|
-
const batchSize = 500;
|
|
229
|
-
|
|
230
|
-
for await (const batch of csvParser.parseStreaming(csvContent, {}, batchSize)) {
|
|
231
|
-
recordCount += batch.length;
|
|
232
|
-
|
|
233
|
-
// Process batch
|
|
234
|
-
await processBatch(batch);
|
|
235
|
-
|
|
236
|
-
// Report progress every 1000 records
|
|
237
|
-
if (recordCount % 1000 === 0) {
|
|
238
|
-
const elapsed = (Date.now() - startTime) / 1000;
|
|
239
|
-
const rate = recordCount / elapsed;
|
|
240
|
-
console.log(`Processed ${recordCount} records (${rate.toFixed(2)} records/sec)`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
console.log(`Completed: ${recordCount} total records`);
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Data Validation
|
|
249
|
-
|
|
250
|
-
Validate CSV structure and data types:
|
|
251
|
-
|
|
252
|
-
### Schema Validation
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
import { CSVParserService, CSVValidationSchema } from '@fluentcommerce/fc-connect-sdk';
|
|
256
|
-
|
|
257
|
-
const csvParser = new CSVParserService();
|
|
258
|
-
|
|
259
|
-
// Define validation schema
|
|
260
|
-
const schema: CSVValidationSchema = {
|
|
261
|
-
requiredColumns: ['sku', 'qty', 'location'],
|
|
262
|
-
columnTypes: {
|
|
263
|
-
sku: 'string',
|
|
264
|
-
qty: 'number',
|
|
265
|
-
location: 'string'
|
|
266
|
-
},
|
|
267
|
-
minRows: 1,
|
|
268
|
-
maxRows: 10000
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// Validate CSV
|
|
272
|
-
const validation = await csvParser.validate(csvContent, schema);
|
|
273
|
-
|
|
274
|
-
if (validation.valid) {
|
|
275
|
-
console.log('CSV is valid');
|
|
276
|
-
const records = await csvParser.parse(csvContent);
|
|
277
|
-
} else {
|
|
278
|
-
console.error('Validation errors:', validation.errors);
|
|
279
|
-
// ['Missing required column: sku', 'Column "qty" must be number']
|
|
280
|
-
}
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
### Runtime Validation
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
// Parse and validate each record
|
|
287
|
-
const records = await csvParser.parse(csvContent);
|
|
288
|
-
|
|
289
|
-
const validRecords = [];
|
|
290
|
-
const errors = [];
|
|
291
|
-
|
|
292
|
-
for (const record of records) {
|
|
293
|
-
// Validate required fields
|
|
294
|
-
if (!record.sku || !record.qty) {
|
|
295
|
-
errors.push({
|
|
296
|
-
record,
|
|
297
|
-
error: 'Missing required fields'
|
|
298
|
-
});
|
|
299
|
-
continue;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Validate data types
|
|
303
|
-
const qty = parseInt(record.qty);
|
|
304
|
-
if (isNaN(qty) || qty < 0) {
|
|
305
|
-
errors.push({
|
|
306
|
-
record,
|
|
307
|
-
error: 'Invalid quantity'
|
|
308
|
-
});
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
validRecords.push(record);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
console.log(`Valid: ${validRecords.length}, Errors: ${errors.length}`);
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
## Transformation with UniversalMapper
|
|
319
|
-
|
|
320
|
-
Combine CSV parsing with field transformations:
|
|
321
|
-
|
|
322
|
-
### Basic Transformation
|
|
323
|
-
|
|
324
|
-
```typescript
|
|
325
|
-
import { CSVParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
326
|
-
|
|
327
|
-
const csvParser = new CSVParserService();
|
|
328
|
-
|
|
329
|
-
// CSV with different field names
|
|
330
|
-
const csvContent = `product_code,stock_level,warehouse_id,last_update
|
|
331
|
-
SKU001,100,WH-01,2025-01-15
|
|
332
|
-
SKU002,50,WH-01,2025-01-15`;
|
|
333
|
-
|
|
334
|
-
// Parse CSV
|
|
335
|
-
const records = await csvParser.parse(csvContent);
|
|
336
|
-
|
|
337
|
-
// Define field mapping
|
|
338
|
-
const mapper = new UniversalMapper({
|
|
339
|
-
fields: {
|
|
340
|
-
ref: { source: 'product_code', required: true },
|
|
341
|
-
qty: { source: 'stock_level', resolver: 'sdk.parseInt' },
|
|
342
|
-
locationRef: { source: 'warehouse_id' },
|
|
343
|
-
updatedOn: { source: 'last_update', resolver: 'sdk.formatDate' }
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// Transform records
|
|
348
|
-
const result = await mapper.map(records);
|
|
349
|
-
|
|
350
|
-
if (!result.success) {
|
|
351
|
-
console.error('Mapping errors:', result.errors);
|
|
352
|
-
throw new Error('Transformation failed');
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
console.log('Transformed data:', result.data);
|
|
356
|
-
// [
|
|
357
|
-
// {
|
|
358
|
-
// ref: 'SKU001',
|
|
359
|
-
// qty: 100,
|
|
360
|
-
// locationRef: 'WH-01',
|
|
361
|
-
// updatedOn: '2025-01-15T00:00:00.000Z'
|
|
362
|
-
// },
|
|
363
|
-
// ...
|
|
364
|
-
// ]
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Streaming + Transformation
|
|
368
|
-
|
|
369
|
-
```typescript
|
|
370
|
-
async function streamAndTransform(csvContent: string) {
|
|
371
|
-
const csvParser = new CSVParserService();
|
|
372
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
373
|
-
|
|
374
|
-
const batchSize = 500;
|
|
375
|
-
const transformedBatches = [];
|
|
376
|
-
|
|
377
|
-
// Stream CSV in batches
|
|
378
|
-
for await (const batch of csvParser.parseStreaming(csvContent, {}, batchSize)) {
|
|
379
|
-
// Transform each batch
|
|
380
|
-
const result = await mapper.map(batch);
|
|
381
|
-
|
|
382
|
-
if (result.success) {
|
|
383
|
-
transformedBatches.push(result.data);
|
|
384
|
-
} else {
|
|
385
|
-
console.error('Batch transformation failed:', result.errors);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return transformedBatches.flat();
|
|
390
|
-
}
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
## Complete Integration Example
|
|
394
|
-
|
|
395
|
-
Full workflow: CSV → Parse → Transform → Send to Fluent
|
|
396
|
-
|
|
397
|
-
```typescript
|
|
398
|
-
import {
|
|
399
|
-
createClient,
|
|
400
|
-
CSVParserService,
|
|
401
|
-
UniversalMapper
|
|
402
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
403
|
-
|
|
404
|
-
async function processInventoryCSV(csvContent: string) {
|
|
405
|
-
// 1. Create client
|
|
406
|
-
const client = await createClient({
|
|
407
|
-
config: {
|
|
408
|
-
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
409
|
-
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
410
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
411
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// 2. Parse CSV
|
|
416
|
-
const csvParser = new CSVParserService();
|
|
417
|
-
const records = await csvParser.parse(csvContent);
|
|
418
|
-
|
|
419
|
-
console.log(`Parsed ${records.length} records`);
|
|
420
|
-
|
|
421
|
-
// 3. Define field mapping
|
|
422
|
-
const mapper = new UniversalMapper({
|
|
423
|
-
fields: {
|
|
424
|
-
ref: { source: 'sku', required: true },
|
|
425
|
-
qty: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
426
|
-
locationRef: { source: 'location' },
|
|
427
|
-
type: { value: 'LAST' } // Static value
|
|
428
|
-
}
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
// 4. Transform data
|
|
432
|
-
const result = await mapper.map(records);
|
|
433
|
-
|
|
434
|
-
if (!result.success) {
|
|
435
|
-
throw new Error(`Mapping failed: ${result.errors.join(', ')}`);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
console.log(`Transformed ${result.data.length} records`);
|
|
439
|
-
|
|
440
|
-
// 5. Send to Fluent Commerce (Batch API for INVENTORY only)
|
|
441
|
-
const job = await client.createJob({
|
|
442
|
-
name: 'csv-inventory-update',
|
|
443
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
await client.sendBatch(job.id, {
|
|
447
|
-
entities: result.data
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
console.log(`✅ Successfully sent ${result.data.length} inventory positions to Fluent`);
|
|
451
|
-
}
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
## Error Handling
|
|
455
|
-
|
|
456
|
-
Handle common CSV parsing errors:
|
|
457
|
-
|
|
458
|
-
```typescript
|
|
459
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
460
|
-
|
|
461
|
-
async function robustCSVParsing(csvContent: string) {
|
|
462
|
-
const csvParser = new CSVParserService();
|
|
463
|
-
|
|
464
|
-
try {
|
|
465
|
-
// Validate first
|
|
466
|
-
const schema = {
|
|
467
|
-
requiredColumns: ['sku', 'qty'],
|
|
468
|
-
minRows: 1
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
const validation = await csvParser.validate(csvContent, schema);
|
|
472
|
-
|
|
473
|
-
if (!validation.valid) {
|
|
474
|
-
console.error('CSV validation failed:', validation.errors);
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Parse
|
|
479
|
-
const records = await csvParser.parse(csvContent);
|
|
480
|
-
return records;
|
|
481
|
-
|
|
482
|
-
} catch (error) {
|
|
483
|
-
if (error.message.includes('Invalid CSV')) {
|
|
484
|
-
console.error('Malformed CSV file');
|
|
485
|
-
} else if (error.message.includes('parse error')) {
|
|
486
|
-
console.error('CSV parsing error:', error.message);
|
|
487
|
-
} else {
|
|
488
|
-
console.error('Unexpected error:', error);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
return null;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
## Performance Tips
|
|
497
|
-
|
|
498
|
-
### 1. Use Streaming for Large Files
|
|
499
|
-
|
|
500
|
-
```typescript
|
|
501
|
-
// ❌ BAD: Load everything into memory
|
|
502
|
-
const allRecords = await csvParser.parse(hugeCsvContent);
|
|
503
|
-
|
|
504
|
-
// ✅ GOOD: Stream and process in batches
|
|
505
|
-
for await (const batch of csvParser.parseStreaming(hugeCsvContent, {}, 500)) {
|
|
506
|
-
await processBatch(batch);
|
|
507
|
-
}
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
### 2. Optimize Batch Size
|
|
511
|
-
|
|
512
|
-
```typescript
|
|
513
|
-
// Small batches (50-100): Complex transformations, API calls
|
|
514
|
-
for await (const batch of csvParser.parseStreaming(csvContent, {}, 50)) {
|
|
515
|
-
await sendToExternalAPI(batch);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Large batches (500-1000): Simple transformations, in-memory processing
|
|
519
|
-
for await (const batch of csvParser.parseStreaming(csvContent, {}, 1000)) {
|
|
520
|
-
await simpleTransformation(batch);
|
|
521
|
-
}
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
### 3. Parallel Processing
|
|
525
|
-
|
|
526
|
-
```typescript
|
|
527
|
-
async function parallelCSVProcessing(csvFiles: string[]) {
|
|
528
|
-
const csvParser = new CSVParserService();
|
|
529
|
-
|
|
530
|
-
// Process multiple CSV files in parallel
|
|
531
|
-
const promises = csvFiles.map(async (csvContent) => {
|
|
532
|
-
const records = await csvParser.parse(csvContent);
|
|
533
|
-
return transformRecords(records);
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
const results = await Promise.all(promises);
|
|
537
|
-
return results.flat();
|
|
538
|
-
}
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
## CSV Generation (Writing)
|
|
542
|
-
|
|
543
|
-
The CSV parser also supports converting JavaScript objects back to CSV format using the `stringify()` method.
|
|
544
|
-
|
|
545
|
-
### CSVParserService.stringify()
|
|
546
|
-
|
|
547
|
-
Convert array of records to CSV string.
|
|
548
|
-
|
|
549
|
-
```typescript
|
|
550
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
551
|
-
|
|
552
|
-
const csvParser = new CSVParserService();
|
|
553
|
-
|
|
554
|
-
const records = [
|
|
555
|
-
{ name: 'Alice', age: 30, city: 'NYC' },
|
|
556
|
-
{ name: 'Bob', age: 25, city: 'LA' },
|
|
557
|
-
{ name: 'Charlie', age: 35, city: 'Chicago' }
|
|
558
|
-
];
|
|
559
|
-
|
|
560
|
-
// Generate CSV with default options
|
|
561
|
-
const csvString = csvParser.stringify(records, {
|
|
562
|
-
headers: true, // Include header row
|
|
563
|
-
delimiter: ',', // Field delimiter
|
|
564
|
-
quote: '"', // Quote character
|
|
565
|
-
escape: '"' // Escape character
|
|
566
|
-
});
|
|
567
|
-
|
|
568
|
-
console.log(csvString);
|
|
569
|
-
// Output:
|
|
570
|
-
// name,age,city
|
|
571
|
-
// Alice,30,NYC
|
|
572
|
-
// Bob,25,LA
|
|
573
|
-
// Charlie,35,Chicago
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
### Stringify Options
|
|
577
|
-
|
|
578
|
-
```typescript
|
|
579
|
-
interface StringifyOptions {
|
|
580
|
-
headers?: boolean; // Include header row (default: true)
|
|
581
|
-
delimiter?: string; // Field delimiter (default: ',')
|
|
582
|
-
quote?: string; // Quote character (default: '"')
|
|
583
|
-
escape?: string; // Escape character (default: '"')
|
|
584
|
-
}
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### Different Delimiters
|
|
588
|
-
|
|
589
|
-
```typescript
|
|
590
|
-
// Tab-separated (TSV)
|
|
591
|
-
const tsv = csvParser.stringify(records, {
|
|
592
|
-
delimiter: '\t',
|
|
593
|
-
headers: true
|
|
594
|
-
});
|
|
595
|
-
// Output: name\tage\tcity\nAlice\t30\tNYC...
|
|
596
|
-
|
|
597
|
-
// Semicolon-separated (European format)
|
|
598
|
-
const europeanCsv = csvParser.stringify(records, {
|
|
599
|
-
delimiter: ';',
|
|
600
|
-
headers: true
|
|
601
|
-
});
|
|
602
|
-
// Output: name;age;city\nAlice;30;NYC...
|
|
603
|
-
|
|
604
|
-
// Pipe-separated
|
|
605
|
-
const pipeCsv = csvParser.stringify(records, {
|
|
606
|
-
delimiter: '|',
|
|
607
|
-
headers: true
|
|
608
|
-
});
|
|
609
|
-
// Output: name|age|city\nAlice|30|NYC...
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### Without Headers
|
|
613
|
-
|
|
614
|
-
```typescript
|
|
615
|
-
const csvNoHeaders = csvParser.stringify(records, {
|
|
616
|
-
headers: false // Skip header row
|
|
617
|
-
});
|
|
618
|
-
|
|
619
|
-
console.log(csvNoHeaders);
|
|
620
|
-
// Output:
|
|
621
|
-
// Alice,30,NYC
|
|
622
|
-
// Bob,25,LA
|
|
623
|
-
// Charlie,35,Chicago
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### Complete Round-Trip Example
|
|
627
|
-
|
|
628
|
-
```typescript
|
|
629
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
630
|
-
|
|
631
|
-
async function csvRoundTrip() {
|
|
632
|
-
const csvParser = new CSVParserService();
|
|
633
|
-
|
|
634
|
-
// Original CSV
|
|
635
|
-
const originalCsv = `sku,qty,location
|
|
636
|
-
SKU001,100,WH-01
|
|
637
|
-
SKU002,50,WH-02`;
|
|
638
|
-
|
|
639
|
-
// Parse
|
|
640
|
-
const records = await csvParser.parse(originalCsv);
|
|
641
|
-
console.log('Parsed:', records);
|
|
642
|
-
|
|
643
|
-
// Transform data (e.g., double quantities)
|
|
644
|
-
const transformed = records.map(r => ({
|
|
645
|
-
...r,
|
|
646
|
-
qty: parseInt(r.qty) * 2
|
|
647
|
-
}));
|
|
648
|
-
|
|
649
|
-
// Convert back to CSV
|
|
650
|
-
const newCsv = csvParser.stringify(transformed, {
|
|
651
|
-
headers: true,
|
|
652
|
-
delimiter: ','
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
console.log('Generated CSV:');
|
|
656
|
-
console.log(newCsv);
|
|
657
|
-
// Output:
|
|
658
|
-
// sku,qty,location
|
|
659
|
-
// SKU001,200,WH-01
|
|
660
|
-
// SKU002,100,WH-02
|
|
661
|
-
}
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
### Practical Use Case: Export to CSV File
|
|
665
|
-
|
|
666
|
-
```typescript
|
|
667
|
-
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
668
|
-
import * as fs from 'fs/promises';
|
|
669
|
-
|
|
670
|
-
async function exportToCsv(data: any[], outputPath: string) {
|
|
671
|
-
const csvParser = new CSVParserService();
|
|
672
|
-
|
|
673
|
-
// Convert records to CSV
|
|
674
|
-
const csvContent = csvParser.stringify(data, {
|
|
675
|
-
headers: true,
|
|
676
|
-
delimiter: ','
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
// Write to file
|
|
680
|
-
await fs.writeFile(outputPath, csvContent, 'utf-8');
|
|
681
|
-
|
|
682
|
-
console.log(`✅ Exported ${data.length} records to ${outputPath}`);
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// Usage
|
|
686
|
-
const inventoryData = [
|
|
687
|
-
{ sku: 'SKU001', qty: 100, location: 'WH-01' },
|
|
688
|
-
{ sku: 'SKU002', qty: 50, location: 'WH-02' }
|
|
689
|
-
];
|
|
690
|
-
|
|
691
|
-
await exportToCsv(inventoryData, 'inventory-export.csv');
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
### Integration with S3
|
|
695
|
-
|
|
696
|
-
```typescript
|
|
697
|
-
import { CSVParserService, S3DataSource, createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
698
|
-
|
|
699
|
-
async function exportToS3(data: any[], s3Key: string) {
|
|
700
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'CSVExport' });
|
|
701
|
-
const csvParser = new CSVParserService();
|
|
702
|
-
|
|
703
|
-
// Convert to CSV
|
|
704
|
-
const csvContent = csvParser.stringify(data, { headers: true });
|
|
705
|
-
|
|
706
|
-
// Setup S3
|
|
707
|
-
const s3 = new S3DataSource(
|
|
708
|
-
{
|
|
709
|
-
type: 'S3_CSV',
|
|
710
|
-
connectionId: 's3-csv-export',
|
|
711
|
-
name: 'S3 CSV Export',
|
|
712
|
-
s3Config: {
|
|
713
|
-
bucket: process.env.S3_BUCKET!,
|
|
714
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
715
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
716
|
-
region: process.env.AWS_REGION!
|
|
717
|
-
}
|
|
718
|
-
},
|
|
719
|
-
logger
|
|
720
|
-
);
|
|
721
|
-
|
|
722
|
-
// Upload to S3
|
|
723
|
-
await s3.uploadFile(s3Key, Buffer.from(csvContent), {
|
|
724
|
-
contentType: 'text/csv'
|
|
725
|
-
});
|
|
726
|
-
|
|
727
|
-
console.log(`✅ Exported to s3://${process.env.S3_BUCKET}/${s3Key}`);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
// Usage
|
|
731
|
-
await exportToS3(inventoryData, 'exports/inventory-2025-10-30.csv');
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
---
|
|
735
|
-
|
|
736
|
-
## Key Takeaways
|
|
737
|
-
|
|
738
|
-
- 🎯 CSV Parser handles tabular data with headers
|
|
739
|
-
- 🎯 Use `parse()` for small files, `parseStreaming()` for large files
|
|
740
|
-
- 🎯 Use `stringify()` to convert objects back to CSV format
|
|
741
|
-
- 🎯 Configure delimiter, quotes, and column options for different formats
|
|
742
|
-
- 🎯 Validate structure with `validate()` before parsing
|
|
743
|
-
- 🎯 Combine with `UniversalMapper` for field transformations
|
|
744
|
-
- 🎯 Stream in batches for memory-efficient processing
|
|
745
|
-
- 🎯 Handle errors gracefully with validation and try-catch
|
|
746
|
-
|
|
747
|
-
## Practice Exercise
|
|
748
|
-
|
|
749
|
-
**Challenge:** Parse this CSV and transform it for Fluent Commerce:
|
|
750
|
-
|
|
751
|
-
```csv
|
|
752
|
-
product_id,available_qty,warehouse,last_updated
|
|
753
|
-
PROD-001,150,DC-EAST,2025-01-15T10:30:00Z
|
|
754
|
-
PROD-002,75,DC-WEST,2025-01-15T11:00:00Z
|
|
755
|
-
PROD-003,200,DC-CENTRAL,2025-01-15T11:30:00Z
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
**Requirements:**
|
|
759
|
-
1. Parse the CSV
|
|
760
|
-
2. Transform to Fluent format: `{ ref, qty, locationRef, updatedOn }`
|
|
761
|
-
3. Validate that qty is a positive number
|
|
762
|
-
4. Format the date properly
|
|
763
|
-
|
|
764
|
-
**Solution:** See [CSV Examples](../examples/csv-parser-examples.ts)
|
|
765
|
-
|
|
766
|
-
## Next Steps
|
|
767
|
-
|
|
768
|
-
Continue to [Module 3: JSON Parser →](./02-core-guides-parsers-03-json-parser.md) to learn JSON and JSONL parsing.
|
|
769
|
-
|
|
770
|
-
---
|
|
771
|
-
|
|
772
|
-
**Module 2 Complete!** ✅
|
|
1
|
+
# Module 2: CSV Parser
|
|
2
|
+
|
|
3
|
+
**Level:** Beginner
|
|
4
|
+
**Estimated Time:** 20 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module covers the CSV Parser (`CSVParserService`), the most common parser for inventory and product data feeds. You'll learn how to parse CSV files, validate data, handle large files with streaming, and integrate with SDK transformation services.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Parse CSV files into structured JavaScript objects
|
|
14
|
+
- ✅ Configure parser options for different CSV formats
|
|
15
|
+
- ✅ Stream large CSV files efficiently
|
|
16
|
+
- ✅ Validate CSV structure and data types
|
|
17
|
+
- ✅ Transform CSV data with UniversalMapper
|
|
18
|
+
|
|
19
|
+
## What is CSV?
|
|
20
|
+
|
|
21
|
+
**CSV (Comma-Separated Values)** is a simple tabular format where:
|
|
22
|
+
- Each line represents a record
|
|
23
|
+
- Fields are separated by commas (or other delimiters)
|
|
24
|
+
- First line typically contains column headers
|
|
25
|
+
- Text values may be quoted
|
|
26
|
+
|
|
27
|
+
**Example:**
|
|
28
|
+
```csv
|
|
29
|
+
sku,name,qty,location
|
|
30
|
+
SKU001,Wireless Mouse,100,WH-01
|
|
31
|
+
SKU002,Keyboard,50,WH-01
|
|
32
|
+
SKU003,Monitor,25,WH-02
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Basic CSV Parsing
|
|
36
|
+
|
|
37
|
+
### Simple Parsing
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
41
|
+
|
|
42
|
+
const csvParser = new CSVParserService();
|
|
43
|
+
|
|
44
|
+
// Sample CSV data
|
|
45
|
+
const csvContent = `sku,qty,location
|
|
46
|
+
SKU001,100,WH-01
|
|
47
|
+
SKU002,50,WH-01
|
|
48
|
+
SKU003,75,WH-02`;
|
|
49
|
+
|
|
50
|
+
// Parse CSV
|
|
51
|
+
const records = await csvParser.parse(csvContent);
|
|
52
|
+
|
|
53
|
+
console.log(records);
|
|
54
|
+
// [
|
|
55
|
+
// { sku: 'SKU001', qty: '100', location: 'WH-01' },
|
|
56
|
+
// { sku: 'SKU002', qty: '50', location: 'WH-01' },
|
|
57
|
+
// { sku: 'SKU003', qty: '75', location: 'WH-02' }
|
|
58
|
+
// ]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Type Safety with TypeScript
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// Define your record structure
|
|
65
|
+
interface InventoryRecord {
|
|
66
|
+
sku: string;
|
|
67
|
+
qty: string;
|
|
68
|
+
location: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Parse with type assertion
|
|
72
|
+
const records = await csvParser.parse<InventoryRecord>(csvContent);
|
|
73
|
+
|
|
74
|
+
// Now you have full type safety
|
|
75
|
+
records.forEach(record => {
|
|
76
|
+
console.log(`${record.sku}: ${record.qty} units at ${record.location}`);
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Parser Configuration
|
|
81
|
+
|
|
82
|
+
The CSV parser supports various options to handle different CSV formats:
|
|
83
|
+
|
|
84
|
+
### Common Options
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
88
|
+
import type { Options as CSVOptions } from 'csv-parse';
|
|
89
|
+
|
|
90
|
+
const csvParser = new CSVParserService();
|
|
91
|
+
|
|
92
|
+
const options: CSVOptions = {
|
|
93
|
+
// Column headers (default: true - first row is headers)
|
|
94
|
+
columns: true,
|
|
95
|
+
|
|
96
|
+
// Skip empty lines (default: true)
|
|
97
|
+
skip_empty_lines: true,
|
|
98
|
+
|
|
99
|
+
// Trim whitespace (default: true)
|
|
100
|
+
trim: true,
|
|
101
|
+
|
|
102
|
+
// Custom delimiter (default: ',')
|
|
103
|
+
delimiter: ',',
|
|
104
|
+
|
|
105
|
+
// Quote character (default: '"')
|
|
106
|
+
quote: '"',
|
|
107
|
+
|
|
108
|
+
// Escape character (default: '"')
|
|
109
|
+
escape: '"',
|
|
110
|
+
|
|
111
|
+
// Skip first N rows
|
|
112
|
+
from_line: 1
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const records = await csvParser.parse(csvContent, options);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Handling Different Delimiters
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Tab-separated values (TSV)
|
|
122
|
+
const tsvContent = `sku\tqty\tlocation
|
|
123
|
+
SKU001\t100\tWH-01`;
|
|
124
|
+
|
|
125
|
+
const tsvRecords = await csvParser.parse(tsvContent, {
|
|
126
|
+
delimiter: '\t'
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Pipe-separated values
|
|
130
|
+
const pipeSeparated = `sku|qty|location
|
|
131
|
+
SKU001|100|WH-01`;
|
|
132
|
+
|
|
133
|
+
const pipeRecords = await csvParser.parse(pipeSeparated, {
|
|
134
|
+
delimiter: '|'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Semicolon-separated (European format)
|
|
138
|
+
const europeanCSV = `sku;qty;location
|
|
139
|
+
SKU001;100;WH-01`;
|
|
140
|
+
|
|
141
|
+
const records = await csvParser.parse(europeanCSV, {
|
|
142
|
+
delimiter: ';'
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Custom Column Names
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// CSV without headers
|
|
150
|
+
const noHeadersCSV = `SKU001,100,WH-01
|
|
151
|
+
SKU002,50,WH-01`;
|
|
152
|
+
|
|
153
|
+
// Provide custom column names
|
|
154
|
+
const records = await csvParser.parse(noHeadersCSV, {
|
|
155
|
+
columns: ['sku', 'qty', 'location']
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
console.log(records);
|
|
159
|
+
// [
|
|
160
|
+
// { sku: 'SKU001', qty: '100', location: 'WH-01' },
|
|
161
|
+
// { sku: 'SKU002', qty: '50', location: 'WH-01' }
|
|
162
|
+
// ]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Skipping Rows
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Skip first 2 rows (e.g., title row + header row)
|
|
169
|
+
const csvWithTitle = `Inventory Export - 2025-01-15
|
|
170
|
+
sku,qty,location
|
|
171
|
+
SKU001,100,WH-01
|
|
172
|
+
SKU002,50,WH-01`;
|
|
173
|
+
|
|
174
|
+
const records = await csvParser.parse(csvWithTitle, {
|
|
175
|
+
from_line: 2 // Start from line 2 (headers)
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Streaming Large Files
|
|
180
|
+
|
|
181
|
+
For large CSV files, use streaming to avoid memory issues:
|
|
182
|
+
|
|
183
|
+
### Basic Streaming
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
187
|
+
|
|
188
|
+
const csvParser = new CSVParserService();
|
|
189
|
+
|
|
190
|
+
// Large CSV content (e.g., from S3)
|
|
191
|
+
const largeCsvContent = `...`; // Thousands of rows
|
|
192
|
+
|
|
193
|
+
// Process records one by one
|
|
194
|
+
for await (const record of csvParser.parseStreaming(largeCsvContent)) {
|
|
195
|
+
console.log('Processing record:', record);
|
|
196
|
+
// Process each record individually
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Batch Streaming
|
|
201
|
+
|
|
202
|
+
Process records in batches for better performance:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
const batchSize = 100;
|
|
206
|
+
|
|
207
|
+
// Process in batches of 100 records
|
|
208
|
+
for await (const batch of csvParser.parseStreaming(largeCsvContent, {}, batchSize)) {
|
|
209
|
+
console.log(`Processing batch of ${batch.length} records`);
|
|
210
|
+
|
|
211
|
+
// Process batch (e.g., send to Fluent Batch API)
|
|
212
|
+
await processBatch(batch);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function processBatch(records: any[]) {
|
|
216
|
+
// Transform and send to Fluent
|
|
217
|
+
console.log(`Batch processing ${records.length} records`);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Streaming with Progress Tracking
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
async function streamWithProgress(csvContent: string) {
|
|
225
|
+
const csvParser = new CSVParserService();
|
|
226
|
+
const startTime = Date.now();
|
|
227
|
+
let recordCount = 0;
|
|
228
|
+
const batchSize = 500;
|
|
229
|
+
|
|
230
|
+
for await (const batch of csvParser.parseStreaming(csvContent, {}, batchSize)) {
|
|
231
|
+
recordCount += batch.length;
|
|
232
|
+
|
|
233
|
+
// Process batch
|
|
234
|
+
await processBatch(batch);
|
|
235
|
+
|
|
236
|
+
// Report progress every 1000 records
|
|
237
|
+
if (recordCount % 1000 === 0) {
|
|
238
|
+
const elapsed = (Date.now() - startTime) / 1000;
|
|
239
|
+
const rate = recordCount / elapsed;
|
|
240
|
+
console.log(`Processed ${recordCount} records (${rate.toFixed(2)} records/sec)`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log(`Completed: ${recordCount} total records`);
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Data Validation
|
|
249
|
+
|
|
250
|
+
Validate CSV structure and data types:
|
|
251
|
+
|
|
252
|
+
### Schema Validation
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { CSVParserService, CSVValidationSchema } from '@fluentcommerce/fc-connect-sdk';
|
|
256
|
+
|
|
257
|
+
const csvParser = new CSVParserService();
|
|
258
|
+
|
|
259
|
+
// Define validation schema
|
|
260
|
+
const schema: CSVValidationSchema = {
|
|
261
|
+
requiredColumns: ['sku', 'qty', 'location'],
|
|
262
|
+
columnTypes: {
|
|
263
|
+
sku: 'string',
|
|
264
|
+
qty: 'number',
|
|
265
|
+
location: 'string'
|
|
266
|
+
},
|
|
267
|
+
minRows: 1,
|
|
268
|
+
maxRows: 10000
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// Validate CSV
|
|
272
|
+
const validation = await csvParser.validate(csvContent, schema);
|
|
273
|
+
|
|
274
|
+
if (validation.valid) {
|
|
275
|
+
console.log('CSV is valid');
|
|
276
|
+
const records = await csvParser.parse(csvContent);
|
|
277
|
+
} else {
|
|
278
|
+
console.error('Validation errors:', validation.errors);
|
|
279
|
+
// ['Missing required column: sku', 'Column "qty" must be number']
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Runtime Validation
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// Parse and validate each record
|
|
287
|
+
const records = await csvParser.parse(csvContent);
|
|
288
|
+
|
|
289
|
+
const validRecords = [];
|
|
290
|
+
const errors = [];
|
|
291
|
+
|
|
292
|
+
for (const record of records) {
|
|
293
|
+
// Validate required fields
|
|
294
|
+
if (!record.sku || !record.qty) {
|
|
295
|
+
errors.push({
|
|
296
|
+
record,
|
|
297
|
+
error: 'Missing required fields'
|
|
298
|
+
});
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Validate data types
|
|
303
|
+
const qty = parseInt(record.qty);
|
|
304
|
+
if (isNaN(qty) || qty < 0) {
|
|
305
|
+
errors.push({
|
|
306
|
+
record,
|
|
307
|
+
error: 'Invalid quantity'
|
|
308
|
+
});
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
validRecords.push(record);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
console.log(`Valid: ${validRecords.length}, Errors: ${errors.length}`);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Transformation with UniversalMapper
|
|
319
|
+
|
|
320
|
+
Combine CSV parsing with field transformations:
|
|
321
|
+
|
|
322
|
+
### Basic Transformation
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { CSVParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
326
|
+
|
|
327
|
+
const csvParser = new CSVParserService();
|
|
328
|
+
|
|
329
|
+
// CSV with different field names
|
|
330
|
+
const csvContent = `product_code,stock_level,warehouse_id,last_update
|
|
331
|
+
SKU001,100,WH-01,2025-01-15
|
|
332
|
+
SKU002,50,WH-01,2025-01-15`;
|
|
333
|
+
|
|
334
|
+
// Parse CSV
|
|
335
|
+
const records = await csvParser.parse(csvContent);
|
|
336
|
+
|
|
337
|
+
// Define field mapping
|
|
338
|
+
const mapper = new UniversalMapper({
|
|
339
|
+
fields: {
|
|
340
|
+
ref: { source: 'product_code', required: true },
|
|
341
|
+
qty: { source: 'stock_level', resolver: 'sdk.parseInt' },
|
|
342
|
+
locationRef: { source: 'warehouse_id' },
|
|
343
|
+
updatedOn: { source: 'last_update', resolver: 'sdk.formatDate' }
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// Transform records
|
|
348
|
+
const result = await mapper.map(records);
|
|
349
|
+
|
|
350
|
+
if (!result.success) {
|
|
351
|
+
console.error('Mapping errors:', result.errors);
|
|
352
|
+
throw new Error('Transformation failed');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
console.log('Transformed data:', result.data);
|
|
356
|
+
// [
|
|
357
|
+
// {
|
|
358
|
+
// ref: 'SKU001',
|
|
359
|
+
// qty: 100,
|
|
360
|
+
// locationRef: 'WH-01',
|
|
361
|
+
// updatedOn: '2025-01-15T00:00:00.000Z'
|
|
362
|
+
// },
|
|
363
|
+
// ...
|
|
364
|
+
// ]
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Streaming + Transformation
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
async function streamAndTransform(csvContent: string) {
|
|
371
|
+
const csvParser = new CSVParserService();
|
|
372
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
373
|
+
|
|
374
|
+
const batchSize = 500;
|
|
375
|
+
const transformedBatches = [];
|
|
376
|
+
|
|
377
|
+
// Stream CSV in batches
|
|
378
|
+
for await (const batch of csvParser.parseStreaming(csvContent, {}, batchSize)) {
|
|
379
|
+
// Transform each batch
|
|
380
|
+
const result = await mapper.map(batch);
|
|
381
|
+
|
|
382
|
+
if (result.success) {
|
|
383
|
+
transformedBatches.push(result.data);
|
|
384
|
+
} else {
|
|
385
|
+
console.error('Batch transformation failed:', result.errors);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return transformedBatches.flat();
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Complete Integration Example
|
|
394
|
+
|
|
395
|
+
Full workflow: CSV → Parse → Transform → Send to Fluent
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import {
|
|
399
|
+
createClient,
|
|
400
|
+
CSVParserService,
|
|
401
|
+
UniversalMapper
|
|
402
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
403
|
+
|
|
404
|
+
async function processInventoryCSV(csvContent: string) {
|
|
405
|
+
// 1. Create client
|
|
406
|
+
const client = await createClient({
|
|
407
|
+
config: {
|
|
408
|
+
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
409
|
+
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
410
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
411
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// 2. Parse CSV
|
|
416
|
+
const csvParser = new CSVParserService();
|
|
417
|
+
const records = await csvParser.parse(csvContent);
|
|
418
|
+
|
|
419
|
+
console.log(`Parsed ${records.length} records`);
|
|
420
|
+
|
|
421
|
+
// 3. Define field mapping
|
|
422
|
+
const mapper = new UniversalMapper({
|
|
423
|
+
fields: {
|
|
424
|
+
ref: { source: 'sku', required: true },
|
|
425
|
+
qty: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
426
|
+
locationRef: { source: 'location' },
|
|
427
|
+
type: { value: 'LAST' } // Static value
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// 4. Transform data
|
|
432
|
+
const result = await mapper.map(records);
|
|
433
|
+
|
|
434
|
+
if (!result.success) {
|
|
435
|
+
throw new Error(`Mapping failed: ${result.errors.join(', ')}`);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
console.log(`Transformed ${result.data.length} records`);
|
|
439
|
+
|
|
440
|
+
// 5. Send to Fluent Commerce (Batch API for INVENTORY only)
|
|
441
|
+
const job = await client.createJob({
|
|
442
|
+
name: 'csv-inventory-update',
|
|
443
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
await client.sendBatch(job.id, {
|
|
447
|
+
entities: result.data
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
console.log(`✅ Successfully sent ${result.data.length} inventory positions to Fluent`);
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Error Handling
|
|
455
|
+
|
|
456
|
+
Handle common CSV parsing errors:
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
460
|
+
|
|
461
|
+
async function robustCSVParsing(csvContent: string) {
|
|
462
|
+
const csvParser = new CSVParserService();
|
|
463
|
+
|
|
464
|
+
try {
|
|
465
|
+
// Validate first
|
|
466
|
+
const schema = {
|
|
467
|
+
requiredColumns: ['sku', 'qty'],
|
|
468
|
+
minRows: 1
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const validation = await csvParser.validate(csvContent, schema);
|
|
472
|
+
|
|
473
|
+
if (!validation.valid) {
|
|
474
|
+
console.error('CSV validation failed:', validation.errors);
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Parse
|
|
479
|
+
const records = await csvParser.parse(csvContent);
|
|
480
|
+
return records;
|
|
481
|
+
|
|
482
|
+
} catch (error) {
|
|
483
|
+
if (error.message.includes('Invalid CSV')) {
|
|
484
|
+
console.error('Malformed CSV file');
|
|
485
|
+
} else if (error.message.includes('parse error')) {
|
|
486
|
+
console.error('CSV parsing error:', error.message);
|
|
487
|
+
} else {
|
|
488
|
+
console.error('Unexpected error:', error);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## Performance Tips
|
|
497
|
+
|
|
498
|
+
### 1. Use Streaming for Large Files
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// ❌ BAD: Load everything into memory
|
|
502
|
+
const allRecords = await csvParser.parse(hugeCsvContent);
|
|
503
|
+
|
|
504
|
+
// ✅ GOOD: Stream and process in batches
|
|
505
|
+
for await (const batch of csvParser.parseStreaming(hugeCsvContent, {}, 500)) {
|
|
506
|
+
await processBatch(batch);
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### 2. Optimize Batch Size
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
// Small batches (50-100): Complex transformations, API calls
|
|
514
|
+
for await (const batch of csvParser.parseStreaming(csvContent, {}, 50)) {
|
|
515
|
+
await sendToExternalAPI(batch);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Large batches (500-1000): Simple transformations, in-memory processing
|
|
519
|
+
for await (const batch of csvParser.parseStreaming(csvContent, {}, 1000)) {
|
|
520
|
+
await simpleTransformation(batch);
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### 3. Parallel Processing
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
async function parallelCSVProcessing(csvFiles: string[]) {
|
|
528
|
+
const csvParser = new CSVParserService();
|
|
529
|
+
|
|
530
|
+
// Process multiple CSV files in parallel
|
|
531
|
+
const promises = csvFiles.map(async (csvContent) => {
|
|
532
|
+
const records = await csvParser.parse(csvContent);
|
|
533
|
+
return transformRecords(records);
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
const results = await Promise.all(promises);
|
|
537
|
+
return results.flat();
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## CSV Generation (Writing)
|
|
542
|
+
|
|
543
|
+
The CSV parser also supports converting JavaScript objects back to CSV format using the `stringify()` method.
|
|
544
|
+
|
|
545
|
+
### CSVParserService.stringify()
|
|
546
|
+
|
|
547
|
+
Convert array of records to CSV string.
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
551
|
+
|
|
552
|
+
const csvParser = new CSVParserService();
|
|
553
|
+
|
|
554
|
+
const records = [
|
|
555
|
+
{ name: 'Alice', age: 30, city: 'NYC' },
|
|
556
|
+
{ name: 'Bob', age: 25, city: 'LA' },
|
|
557
|
+
{ name: 'Charlie', age: 35, city: 'Chicago' }
|
|
558
|
+
];
|
|
559
|
+
|
|
560
|
+
// Generate CSV with default options
|
|
561
|
+
const csvString = csvParser.stringify(records, {
|
|
562
|
+
headers: true, // Include header row
|
|
563
|
+
delimiter: ',', // Field delimiter
|
|
564
|
+
quote: '"', // Quote character
|
|
565
|
+
escape: '"' // Escape character
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
console.log(csvString);
|
|
569
|
+
// Output:
|
|
570
|
+
// name,age,city
|
|
571
|
+
// Alice,30,NYC
|
|
572
|
+
// Bob,25,LA
|
|
573
|
+
// Charlie,35,Chicago
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Stringify Options
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
interface StringifyOptions {
|
|
580
|
+
headers?: boolean; // Include header row (default: true)
|
|
581
|
+
delimiter?: string; // Field delimiter (default: ',')
|
|
582
|
+
quote?: string; // Quote character (default: '"')
|
|
583
|
+
escape?: string; // Escape character (default: '"')
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Different Delimiters
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
// Tab-separated (TSV)
|
|
591
|
+
const tsv = csvParser.stringify(records, {
|
|
592
|
+
delimiter: '\t',
|
|
593
|
+
headers: true
|
|
594
|
+
});
|
|
595
|
+
// Output: name\tage\tcity\nAlice\t30\tNYC...
|
|
596
|
+
|
|
597
|
+
// Semicolon-separated (European format)
|
|
598
|
+
const europeanCsv = csvParser.stringify(records, {
|
|
599
|
+
delimiter: ';',
|
|
600
|
+
headers: true
|
|
601
|
+
});
|
|
602
|
+
// Output: name;age;city\nAlice;30;NYC...
|
|
603
|
+
|
|
604
|
+
// Pipe-separated
|
|
605
|
+
const pipeCsv = csvParser.stringify(records, {
|
|
606
|
+
delimiter: '|',
|
|
607
|
+
headers: true
|
|
608
|
+
});
|
|
609
|
+
// Output: name|age|city\nAlice|30|NYC...
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Without Headers
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
const csvNoHeaders = csvParser.stringify(records, {
|
|
616
|
+
headers: false // Skip header row
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
console.log(csvNoHeaders);
|
|
620
|
+
// Output:
|
|
621
|
+
// Alice,30,NYC
|
|
622
|
+
// Bob,25,LA
|
|
623
|
+
// Charlie,35,Chicago
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Complete Round-Trip Example
|
|
627
|
+
|
|
628
|
+
```typescript
|
|
629
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
630
|
+
|
|
631
|
+
async function csvRoundTrip() {
|
|
632
|
+
const csvParser = new CSVParserService();
|
|
633
|
+
|
|
634
|
+
// Original CSV
|
|
635
|
+
const originalCsv = `sku,qty,location
|
|
636
|
+
SKU001,100,WH-01
|
|
637
|
+
SKU002,50,WH-02`;
|
|
638
|
+
|
|
639
|
+
// Parse
|
|
640
|
+
const records = await csvParser.parse(originalCsv);
|
|
641
|
+
console.log('Parsed:', records);
|
|
642
|
+
|
|
643
|
+
// Transform data (e.g., double quantities)
|
|
644
|
+
const transformed = records.map(r => ({
|
|
645
|
+
...r,
|
|
646
|
+
qty: parseInt(r.qty) * 2
|
|
647
|
+
}));
|
|
648
|
+
|
|
649
|
+
// Convert back to CSV
|
|
650
|
+
const newCsv = csvParser.stringify(transformed, {
|
|
651
|
+
headers: true,
|
|
652
|
+
delimiter: ','
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
console.log('Generated CSV:');
|
|
656
|
+
console.log(newCsv);
|
|
657
|
+
// Output:
|
|
658
|
+
// sku,qty,location
|
|
659
|
+
// SKU001,200,WH-01
|
|
660
|
+
// SKU002,100,WH-02
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### Practical Use Case: Export to CSV File
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
import { CSVParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
668
|
+
import * as fs from 'fs/promises';
|
|
669
|
+
|
|
670
|
+
async function exportToCsv(data: any[], outputPath: string) {
|
|
671
|
+
const csvParser = new CSVParserService();
|
|
672
|
+
|
|
673
|
+
// Convert records to CSV
|
|
674
|
+
const csvContent = csvParser.stringify(data, {
|
|
675
|
+
headers: true,
|
|
676
|
+
delimiter: ','
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// Write to file
|
|
680
|
+
await fs.writeFile(outputPath, csvContent, 'utf-8');
|
|
681
|
+
|
|
682
|
+
console.log(`✅ Exported ${data.length} records to ${outputPath}`);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Usage
|
|
686
|
+
const inventoryData = [
|
|
687
|
+
{ sku: 'SKU001', qty: 100, location: 'WH-01' },
|
|
688
|
+
{ sku: 'SKU002', qty: 50, location: 'WH-02' }
|
|
689
|
+
];
|
|
690
|
+
|
|
691
|
+
await exportToCsv(inventoryData, 'inventory-export.csv');
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Integration with S3
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
import { CSVParserService, S3DataSource, createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
698
|
+
|
|
699
|
+
async function exportToS3(data: any[], s3Key: string) {
|
|
700
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'CSVExport' });
|
|
701
|
+
const csvParser = new CSVParserService();
|
|
702
|
+
|
|
703
|
+
// Convert to CSV
|
|
704
|
+
const csvContent = csvParser.stringify(data, { headers: true });
|
|
705
|
+
|
|
706
|
+
// Setup S3
|
|
707
|
+
const s3 = new S3DataSource(
|
|
708
|
+
{
|
|
709
|
+
type: 'S3_CSV',
|
|
710
|
+
connectionId: 's3-csv-export',
|
|
711
|
+
name: 'S3 CSV Export',
|
|
712
|
+
s3Config: {
|
|
713
|
+
bucket: process.env.S3_BUCKET!,
|
|
714
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
715
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
716
|
+
region: process.env.AWS_REGION!
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
logger
|
|
720
|
+
);
|
|
721
|
+
|
|
722
|
+
// Upload to S3
|
|
723
|
+
await s3.uploadFile(s3Key, Buffer.from(csvContent), {
|
|
724
|
+
contentType: 'text/csv'
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
console.log(`✅ Exported to s3://${process.env.S3_BUCKET}/${s3Key}`);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// Usage
|
|
731
|
+
await exportToS3(inventoryData, 'exports/inventory-2025-10-30.csv');
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
---
|
|
735
|
+
|
|
736
|
+
## Key Takeaways
|
|
737
|
+
|
|
738
|
+
- 🎯 CSV Parser handles tabular data with headers
|
|
739
|
+
- 🎯 Use `parse()` for small files, `parseStreaming()` for large files
|
|
740
|
+
- 🎯 Use `stringify()` to convert objects back to CSV format
|
|
741
|
+
- 🎯 Configure delimiter, quotes, and column options for different formats
|
|
742
|
+
- 🎯 Validate structure with `validate()` before parsing
|
|
743
|
+
- 🎯 Combine with `UniversalMapper` for field transformations
|
|
744
|
+
- 🎯 Stream in batches for memory-efficient processing
|
|
745
|
+
- 🎯 Handle errors gracefully with validation and try-catch
|
|
746
|
+
|
|
747
|
+
## Practice Exercise
|
|
748
|
+
|
|
749
|
+
**Challenge:** Parse this CSV and transform it for Fluent Commerce:
|
|
750
|
+
|
|
751
|
+
```csv
|
|
752
|
+
product_id,available_qty,warehouse,last_updated
|
|
753
|
+
PROD-001,150,DC-EAST,2025-01-15T10:30:00Z
|
|
754
|
+
PROD-002,75,DC-WEST,2025-01-15T11:00:00Z
|
|
755
|
+
PROD-003,200,DC-CENTRAL,2025-01-15T11:30:00Z
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
**Requirements:**
|
|
759
|
+
1. Parse the CSV
|
|
760
|
+
2. Transform to Fluent format: `{ ref, qty, locationRef, updatedOn }`
|
|
761
|
+
3. Validate that qty is a positive number
|
|
762
|
+
4. Format the date properly
|
|
763
|
+
|
|
764
|
+
**Solution:** See [CSV Examples](../examples/csv-parser-examples.ts)
|
|
765
|
+
|
|
766
|
+
## Next Steps
|
|
767
|
+
|
|
768
|
+
Continue to [Module 3: JSON Parser →](./02-core-guides-parsers-03-json-parser.md) to learn JSON and JSONL parsing.
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
**Module 2 Complete!** ✅
|