@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
package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md
CHANGED
|
@@ -1,676 +1,676 @@
|
|
|
1
|
-
# Module 5: Advanced Parsers
|
|
2
|
-
|
|
3
|
-
**Level:** Intermediate
|
|
4
|
-
**Estimated Time:** 25 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module covers advanced file parsing capabilities beyond CSV, including Parquet for large datasets, XML for B2B systems, and JSON for API integrations.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Parse Parquet files for efficient large dataset processing
|
|
14
|
-
- ✅ Parse XML files from B2B systems and feeds
|
|
15
|
-
- ✅ Parse JSON from APIs and web services
|
|
16
|
-
- ✅ Choose the optimal parser for your use case
|
|
17
|
-
- ✅ Handle streaming for memory-efficient processing
|
|
18
|
-
|
|
19
|
-
## Parquet Parser
|
|
20
|
-
|
|
21
|
-
### Why Parquet?
|
|
22
|
-
|
|
23
|
-
Parquet is a columnar storage format ideal for:
|
|
24
|
-
|
|
25
|
-
| Feature | Benefit |
|
|
26
|
-
|---------|---------|
|
|
27
|
-
| **Compression** | 5-10x smaller than CSV |
|
|
28
|
-
| **Speed** | Faster reads for analytics |
|
|
29
|
-
| **Schema** | Built-in type validation |
|
|
30
|
-
| **Large Files** | Efficient memory usage |
|
|
31
|
-
|
|
32
|
-
### Basic Parquet Parsing
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import {
|
|
36
|
-
ParquetParserService,
|
|
37
|
-
S3DataSource,
|
|
38
|
-
UniversalMapper,
|
|
39
|
-
createConsoleLogger
|
|
40
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
41
|
-
|
|
42
|
-
async function parseParquetFile() {
|
|
43
|
-
// Initialize services
|
|
44
|
-
const logger = createConsoleLogger();
|
|
45
|
-
const s3 = new S3DataSource(
|
|
46
|
-
{
|
|
47
|
-
type: 'S3_PARQUET',
|
|
48
|
-
connectionId: 's3-parquet',
|
|
49
|
-
name: 'S3 Parquet',
|
|
50
|
-
s3Config: {
|
|
51
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
52
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
53
|
-
region: process.env.AWS_REGION!,
|
|
54
|
-
bucket: 'inventory-bucket'
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
logger
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const parquetParser = new ParquetParserService(logger);
|
|
61
|
-
|
|
62
|
-
// Read Parquet file from S3
|
|
63
|
-
const buffer = await s3.downloadFile('data/inventory-positions.parquet', { encoding: 'binary' }) as Buffer;
|
|
64
|
-
|
|
65
|
-
// Parse Parquet
|
|
66
|
-
const records = await parquetParser.parse(buffer);
|
|
67
|
-
console.log(`Parsed ${records.length} records from Parquet file`);
|
|
68
|
-
|
|
69
|
-
// Records are already typed based on Parquet schema
|
|
70
|
-
return records;
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Streaming Large Parquet Files
|
|
75
|
-
|
|
76
|
-
For files larger than available memory:
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
import { ParquetParserService, S3DataSource, UniversalMapper, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
80
|
-
|
|
81
|
-
async function streamParquetFile() {
|
|
82
|
-
const logger = createConsoleLogger();
|
|
83
|
-
const s3 = new S3DataSource(
|
|
84
|
-
{
|
|
85
|
-
type: 'S3_PARQUET',
|
|
86
|
-
connectionId: 's3-parquet-stream',
|
|
87
|
-
name: 'S3 Parquet Stream',
|
|
88
|
-
s3Config: {
|
|
89
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
90
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
91
|
-
region: process.env.AWS_REGION!,
|
|
92
|
-
bucket: 'inventory-bucket'
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
logger
|
|
96
|
-
);
|
|
97
|
-
const parquetParser = new ParquetParserService(logger);
|
|
98
|
-
|
|
99
|
-
// Download Parquet file from S3 (full file download)
|
|
100
|
-
const buffer = await s3.downloadFile('data/large-inventory.parquet', { encoding: 'binary' }) as Buffer;
|
|
101
|
-
|
|
102
|
-
// Parse Parquet (parser handles large files efficiently)
|
|
103
|
-
const records = await parquetParser.parse(buffer);
|
|
104
|
-
|
|
105
|
-
// Process records in chunks
|
|
106
|
-
const batchSize = 1000;
|
|
107
|
-
for (let i = 0; i < records.length; i += batchSize) {
|
|
108
|
-
const batch = records.slice(i, i + batchSize);
|
|
109
|
-
await processBatch(batch);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function processBatch(records: any[]) {
|
|
114
|
-
// Map fields
|
|
115
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
116
|
-
const result = await mapper.map(records);
|
|
117
|
-
|
|
118
|
-
if (result.success) {
|
|
119
|
-
// Send to Fluent
|
|
120
|
-
await sendToFluent(result.data);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Parquet Schema Validation
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { ParquetParserService, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
129
|
-
|
|
130
|
-
async function validateParquetSchema(file: Buffer) {
|
|
131
|
-
const logger = createConsoleLogger();
|
|
132
|
-
const parquetParser = new ParquetParserService(logger);
|
|
133
|
-
|
|
134
|
-
// Extract schema information
|
|
135
|
-
const metadata = await parquetParser.getMetadata(file);
|
|
136
|
-
|
|
137
|
-
console.log('Parquet Schema:', {
|
|
138
|
-
numRows: metadata.numRows,
|
|
139
|
-
columns: metadata.schema.fields.map(f => ({
|
|
140
|
-
name: f.name,
|
|
141
|
-
type: f.type,
|
|
142
|
-
optional: f.optional
|
|
143
|
-
})),
|
|
144
|
-
compression: metadata.compression,
|
|
145
|
-
createdBy: metadata.createdBy
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// Validate expected columns exist
|
|
149
|
-
const requiredColumns = ['sku', 'location', 'quantity'];
|
|
150
|
-
const schemaColumns = metadata.schema.fields.map(f => f.name);
|
|
151
|
-
|
|
152
|
-
const missingColumns = requiredColumns.filter(
|
|
153
|
-
col => !schemaColumns.includes(col)
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
if (missingColumns.length > 0) {
|
|
157
|
-
throw new Error(`Missing required columns: ${missingColumns.join(', ')}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return metadata;
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## XML Parser
|
|
165
|
-
|
|
166
|
-
### Why XML?
|
|
167
|
-
|
|
168
|
-
XML parsing is essential for:
|
|
169
|
-
|
|
170
|
-
| Use Case | Example |
|
|
171
|
-
|----------|---------|
|
|
172
|
-
| **Enterprise Systems** | ERP exports, warehouse management systems |
|
|
173
|
-
| **Standard Formats** | EDI, SOAP, RSS feeds |
|
|
174
|
-
| **Nested Data** | Complex hierarchical structures |
|
|
175
|
-
| **SFCC Orders** | Salesforce Commerce Cloud integrations |
|
|
176
|
-
|
|
177
|
-
### Basic XML Parsing
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
181
|
-
|
|
182
|
-
async function parseXMLFile() {
|
|
183
|
-
const xmlParser = new XMLParserService();
|
|
184
|
-
|
|
185
|
-
const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
|
|
186
|
-
<inventory>
|
|
187
|
-
<position>
|
|
188
|
-
<sku>SKU-WM-001</sku>
|
|
189
|
-
<location>WH-001</location>
|
|
190
|
-
<quantity>500</quantity>
|
|
191
|
-
<status>available</status>
|
|
192
|
-
</position>
|
|
193
|
-
<position>
|
|
194
|
-
<sku>SKU-WM-002</sku>
|
|
195
|
-
<location>WH-001</location>
|
|
196
|
-
<quantity>150</quantity>
|
|
197
|
-
<status>reserved</status>
|
|
198
|
-
</position>
|
|
199
|
-
</inventory>`;
|
|
200
|
-
|
|
201
|
-
// Parse XML to JavaScript object
|
|
202
|
-
const parsed = await xmlParser.parse(xmlData);
|
|
203
|
-
|
|
204
|
-
// Access nested data
|
|
205
|
-
const positions = parsed.inventory.position;
|
|
206
|
-
|
|
207
|
-
console.log(`Parsed ${positions.length} positions from XML`);
|
|
208
|
-
return positions;
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### XML with Path Resolution
|
|
213
|
-
|
|
214
|
-
For complex XML structures, use path-based field mapping:
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
async function parseComplexXML() {
|
|
218
|
-
const xmlParser = new XMLParserService();
|
|
219
|
-
|
|
220
|
-
const complexXML = `<?xml version="1.0" encoding="UTF-8"?>
|
|
221
|
-
<warehouse-export>
|
|
222
|
-
<metadata>
|
|
223
|
-
<export-date>2024-01-15</export-date>
|
|
224
|
-
<warehouse>WH-001</warehouse>
|
|
225
|
-
</metadata>
|
|
226
|
-
<inventory-positions>
|
|
227
|
-
<position id="1">
|
|
228
|
-
<product>
|
|
229
|
-
<sku>SKU-WM-001</sku>
|
|
230
|
-
<name>Widget Master 3000</name>
|
|
231
|
-
</product>
|
|
232
|
-
<location>
|
|
233
|
-
<zone>A</zone>
|
|
234
|
-
<aisle>12</aisle>
|
|
235
|
-
<bin>45</bin>
|
|
236
|
-
</location>
|
|
237
|
-
<quantities>
|
|
238
|
-
<on-hand>500</on-hand>
|
|
239
|
-
<available>450</available>
|
|
240
|
-
<reserved>50</reserved>
|
|
241
|
-
</quantities>
|
|
242
|
-
<status>AVAILABLE</status>
|
|
243
|
-
</position>
|
|
244
|
-
</inventory-positions>
|
|
245
|
-
</warehouse-export>`;
|
|
246
|
-
|
|
247
|
-
const parsed = await xmlParser.parse(complexXML);
|
|
248
|
-
|
|
249
|
-
// Extract with path notation
|
|
250
|
-
const mapper = new UniversalMapper({
|
|
251
|
-
fields: {
|
|
252
|
-
ref: {
|
|
253
|
-
source: 'product.sku',
|
|
254
|
-
required: true
|
|
255
|
-
},
|
|
256
|
-
productRef: {
|
|
257
|
-
source: 'product.sku',
|
|
258
|
-
required: true
|
|
259
|
-
},
|
|
260
|
-
locationRef: {
|
|
261
|
-
source: 'warehouse', // From root metadata
|
|
262
|
-
resolver: (value, data) => {
|
|
263
|
-
// Combine location parts
|
|
264
|
-
return `${data.location.zone}-${data.location.aisle}-${data.location.bin}`;
|
|
265
|
-
},
|
|
266
|
-
required: true
|
|
267
|
-
},
|
|
268
|
-
qty: {
|
|
269
|
-
source: 'quantities.on-hand',
|
|
270
|
-
resolver: 'sdk.parseInt',
|
|
271
|
-
required: true
|
|
272
|
-
},
|
|
273
|
-
status: {
|
|
274
|
-
source: 'status',
|
|
275
|
-
resolver: 'sdk.uppercase',
|
|
276
|
-
required: true
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
// Map each position
|
|
282
|
-
const positions = parsed['warehouse-export']['inventory-positions'].position;
|
|
283
|
-
const result = await mapper.map(positions);
|
|
284
|
-
|
|
285
|
-
return result.data;
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### XML Namespace Handling
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
async function parseXMLWithNamespaces() {
|
|
293
|
-
const xmlParser = new XMLParserService({
|
|
294
|
-
ignoreAttributes: false,
|
|
295
|
-
attributeNamePrefix: '@_',
|
|
296
|
-
parseAttributeValue: true
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
const nsXML = `<?xml version="1.0" encoding="UTF-8"?>
|
|
300
|
-
<inv:inventory xmlns:inv="http://example.com/inventory" xmlns:prod="http://example.com/product">
|
|
301
|
-
<inv:position inv:id="1">
|
|
302
|
-
<prod:sku>SKU-WM-001</prod:sku>
|
|
303
|
-
<inv:location>WH-001</inv:location>
|
|
304
|
-
<inv:quantity>500</inv:quantity>
|
|
305
|
-
</inv:position>
|
|
306
|
-
</inv:inventory>`;
|
|
307
|
-
|
|
308
|
-
const parsed = await xmlParser.parse(nsXML);
|
|
309
|
-
|
|
310
|
-
// Access namespaced elements
|
|
311
|
-
console.log('Parsed with namespaces:', parsed);
|
|
312
|
-
return parsed;
|
|
313
|
-
}
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
## JSON Parser
|
|
317
|
-
|
|
318
|
-
### Why JSON?
|
|
319
|
-
|
|
320
|
-
JSON parsing is ideal for:
|
|
321
|
-
|
|
322
|
-
| Use Case | Example |
|
|
323
|
-
|----------|---------|
|
|
324
|
-
| **REST APIs** | Third-party inventory services |
|
|
325
|
-
| **Web Services** | Cloud-based systems |
|
|
326
|
-
| **Modern Exports** | Contemporary systems |
|
|
327
|
-
| **Nested Objects** | Complex data structures |
|
|
328
|
-
|
|
329
|
-
### Basic JSON Parsing
|
|
330
|
-
|
|
331
|
-
```typescript
|
|
332
|
-
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
333
|
-
|
|
334
|
-
async function parseJSONFile() {
|
|
335
|
-
const jsonParser = new JSONParserService();
|
|
336
|
-
|
|
337
|
-
const jsonData = {
|
|
338
|
-
"metadata": {
|
|
339
|
-
"export_date": "2024-01-15",
|
|
340
|
-
"total_records": 2
|
|
341
|
-
},
|
|
342
|
-
"inventory_positions": [
|
|
343
|
-
{
|
|
344
|
-
"sku": "SKU-WM-001",
|
|
345
|
-
"location": "WH-001",
|
|
346
|
-
"quantity": 500,
|
|
347
|
-
"status": "available"
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
"sku": "SKU-WM-002",
|
|
351
|
-
"location": "WH-001",
|
|
352
|
-
"quantity": 150,
|
|
353
|
-
"status": "reserved"
|
|
354
|
-
}
|
|
355
|
-
]
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
// Parse JSON (validates structure)
|
|
359
|
-
const parsed = await jsonParser.parse(JSON.stringify(jsonData));
|
|
360
|
-
|
|
361
|
-
const positions = parsed.inventory_positions;
|
|
362
|
-
console.log(`Parsed ${positions.length} positions from JSON`);
|
|
363
|
-
|
|
364
|
-
return positions;
|
|
365
|
-
}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### JSON Array Streaming
|
|
369
|
-
|
|
370
|
-
For large JSON arrays, use streaming to avoid memory issues:
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
import { S3DataSource, JSONParserService, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
374
|
-
|
|
375
|
-
async function streamLargeJSONArray() {
|
|
376
|
-
const logger = createConsoleLogger();
|
|
377
|
-
const s3 = new S3DataSource(
|
|
378
|
-
{
|
|
379
|
-
type: 'S3_JSON',
|
|
380
|
-
connectionId: 's3-json-stream',
|
|
381
|
-
name: 'S3 JSON Stream',
|
|
382
|
-
s3Config: {
|
|
383
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
384
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
385
|
-
region: process.env.AWS_REGION!,
|
|
386
|
-
bucket: 'inventory-bucket'
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
logger
|
|
390
|
-
);
|
|
391
|
-
const jsonParser = new JSONParserService();
|
|
392
|
-
|
|
393
|
-
// Download JSON file from S3
|
|
394
|
-
const jsonContent = await s3.downloadFile('data/large-inventory.json') as string;
|
|
395
|
-
|
|
396
|
-
// Parse JSON array
|
|
397
|
-
const parsed = await jsonParser.parse(jsonContent);
|
|
398
|
-
const positions = parsed.inventory_positions || [];
|
|
399
|
-
|
|
400
|
-
// Process records in batches
|
|
401
|
-
const batchSize = 1000;
|
|
402
|
-
let count = 0;
|
|
403
|
-
for (let i = 0; i < positions.length; i += batchSize) {
|
|
404
|
-
const batch = positions.slice(i, i + batchSize);
|
|
405
|
-
for (const record of batch) {
|
|
406
|
-
await processRecord(record);
|
|
407
|
-
count++;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (count % 1000 === 0) {
|
|
411
|
-
console.log(`Processed ${count} records...`);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
console.log(`Total records processed: ${count}`);
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
### JSON Schema Validation
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
async function validateJSONSchema(data: any) {
|
|
423
|
-
const schema = {
|
|
424
|
-
type: 'object',
|
|
425
|
-
required: ['inventory_positions'],
|
|
426
|
-
properties: {
|
|
427
|
-
metadata: {
|
|
428
|
-
type: 'object',
|
|
429
|
-
properties: {
|
|
430
|
-
export_date: { type: 'string' },
|
|
431
|
-
total_records: { type: 'number' }
|
|
432
|
-
}
|
|
433
|
-
},
|
|
434
|
-
inventory_positions: {
|
|
435
|
-
type: 'array',
|
|
436
|
-
items: {
|
|
437
|
-
type: 'object',
|
|
438
|
-
required: ['sku', 'location', 'quantity'],
|
|
439
|
-
properties: {
|
|
440
|
-
sku: { type: 'string' },
|
|
441
|
-
location: { type: 'string' },
|
|
442
|
-
quantity: { type: 'number' },
|
|
443
|
-
status: { type: 'string' }
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
const jsonParser = new JSONParserService({ schema });
|
|
451
|
-
|
|
452
|
-
// Validate and parse
|
|
453
|
-
const result = await jsonParser.parseWithValidation(data);
|
|
454
|
-
|
|
455
|
-
if (!result.valid) {
|
|
456
|
-
throw new Error(`JSON validation failed: ${result.errors.join(', ')}`);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
return result.data;
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
## Parser Comparison
|
|
464
|
-
|
|
465
|
-
### When to Use Which Parser
|
|
466
|
-
|
|
467
|
-
| Parser | Best For | Pros | Cons | File Size Limit |
|
|
468
|
-
|--------|----------|------|------|-----------------|
|
|
469
|
-
| **CSV** | Simple tabular data, exports, integrations | Universal, easy to inspect | No schema, flat structure | < 1 GB with streaming |
|
|
470
|
-
| **Parquet** | Large datasets, analytics, data lakes | Fast, compressed, typed | Binary, needs tools | Unlimited with streaming |
|
|
471
|
-
| **XML** | Enterprise systems, SOAP, hierarchical data | Structured, validated, nested | Verbose, complex parsing | < 500 MB |
|
|
472
|
-
| **JSON** | REST APIs, modern systems, web services | Flexible, nested, readable | Can be large, no schema | < 500 MB with streaming |
|
|
473
|
-
|
|
474
|
-
### Performance Comparison
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
async function benchmarkParsers() {
|
|
478
|
-
const testData = generateTestData(10000); // 10K records
|
|
479
|
-
|
|
480
|
-
// CSV Performance
|
|
481
|
-
const csvStart = Date.now();
|
|
482
|
-
const csvParser = new CSVParserService();
|
|
483
|
-
const csvData = await csvParser.parse(toCSV(testData), { columns: true });
|
|
484
|
-
console.log(`CSV: ${Date.now() - csvStart}ms`);
|
|
485
|
-
|
|
486
|
-
// Parquet Performance
|
|
487
|
-
const parquetStart = Date.now();
|
|
488
|
-
const logger = createConsoleLogger();
|
|
489
|
-
const parquetParser = new ParquetParserService(logger);
|
|
490
|
-
const parquetData = await parquetParser.parse(toParquet(testData));
|
|
491
|
-
console.log(`Parquet: ${Date.now() - parquetStart}ms`);
|
|
492
|
-
|
|
493
|
-
// XML Performance
|
|
494
|
-
const xmlStart = Date.now();
|
|
495
|
-
const xmlParser = new XMLParserService();
|
|
496
|
-
const xmlData = await xmlParser.parse(toXML(testData));
|
|
497
|
-
console.log(`XML: ${Date.now() - xmlStart}ms`);
|
|
498
|
-
|
|
499
|
-
// JSON Performance
|
|
500
|
-
const jsonStart = Date.now();
|
|
501
|
-
const jsonParser = new JSONParserService();
|
|
502
|
-
const jsonData = await jsonParser.parse(toJSON(testData));
|
|
503
|
-
console.log(`JSON: ${Date.now() - jsonStart}ms`);
|
|
504
|
-
}
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
## Complete Example: Multi-Format Ingestion
|
|
508
|
-
|
|
509
|
-
```typescript
|
|
510
|
-
import {
|
|
511
|
-
createClient,
|
|
512
|
-
S3DataSource,
|
|
513
|
-
CSVParserService,
|
|
514
|
-
ParquetParserService,
|
|
515
|
-
XMLParserService,
|
|
516
|
-
JSONParserService,
|
|
517
|
-
UniversalMapper,
|
|
518
|
-
createConsoleLogger
|
|
519
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
520
|
-
|
|
521
|
-
async function ingestMultiFormat() {
|
|
522
|
-
const logger = createConsoleLogger();
|
|
523
|
-
|
|
524
|
-
const client = await createClient({
|
|
525
|
-
config: {
|
|
526
|
-
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
527
|
-
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
528
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
529
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
const s3 = new S3DataSource(
|
|
534
|
-
{
|
|
535
|
-
type: 'S3_CSV',
|
|
536
|
-
connectionId: 's3-multi-format',
|
|
537
|
-
name: 'S3 Multi-Format',
|
|
538
|
-
s3Config: {
|
|
539
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
540
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
541
|
-
region: process.env.AWS_REGION!,
|
|
542
|
-
bucket: 'inventory-bucket'
|
|
543
|
-
}
|
|
544
|
-
},
|
|
545
|
-
logger
|
|
546
|
-
);
|
|
547
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
548
|
-
|
|
549
|
-
// List all files
|
|
550
|
-
const files = await s3.listFiles({ prefix: 'data/' });
|
|
551
|
-
|
|
552
|
-
for (const file of files) {
|
|
553
|
-
let records: any[];
|
|
554
|
-
|
|
555
|
-
// Choose parser based on file extension
|
|
556
|
-
if (file.name.endsWith('.csv')) {
|
|
557
|
-
const csvParser = new CSVParserService();
|
|
558
|
-
const data = await s3.downloadFile(file.path) as string;
|
|
559
|
-
records = await csvParser.parse(data);
|
|
560
|
-
|
|
561
|
-
} else if (file.name.endsWith('.parquet')) {
|
|
562
|
-
const parquetParser = new ParquetParserService(logger);
|
|
563
|
-
const data = await s3.downloadFile(file.path, { encoding: 'binary' }) as Buffer;
|
|
564
|
-
records = await parquetParser.parse(data);
|
|
565
|
-
|
|
566
|
-
} else if (file.name.endsWith('.xml')) {
|
|
567
|
-
const xmlParser = new XMLParserService(logger);
|
|
568
|
-
const data = await s3.downloadFile(file.path) as string;
|
|
569
|
-
const parsed = await xmlParser.parse(data);
|
|
570
|
-
records = extractInventoryFromXML(parsed);
|
|
571
|
-
|
|
572
|
-
} else if (file.name.endsWith('.json')) {
|
|
573
|
-
const jsonParser = new JSONParserService();
|
|
574
|
-
const data = await s3.downloadFile(file.path) as string;
|
|
575
|
-
const parsed = await jsonParser.parse(data);
|
|
576
|
-
records = parsed.inventory_positions || [];
|
|
577
|
-
|
|
578
|
-
} else {
|
|
579
|
-
console.log(`Skipping unsupported file: ${file.name}`);
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Transform with UniversalMapper
|
|
584
|
-
const result = await mapper.map(records);
|
|
585
|
-
|
|
586
|
-
if (!result.success) {
|
|
587
|
-
console.error(`Mapping failed for ${file.name}:`, result.errors);
|
|
588
|
-
continue;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// Send to Fluent
|
|
592
|
-
const job = await client.createJob({
|
|
593
|
-
name: `Import - ${file.name}`,
|
|
594
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
await client.sendBatch(job.id, {
|
|
598
|
-
action: 'UPSERT',
|
|
599
|
-
entityType: 'INVENTORY',
|
|
600
|
-
source: 'S3_CSV',
|
|
601
|
-
event: 'INVENTORY_SYNC',
|
|
602
|
-
entities: result.data
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
console.log(`Processed ${result.data.length} records from ${file.name}`);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function extractInventoryFromXML(parsed: any): any[] {
|
|
610
|
-
// Extract inventory positions from XML structure
|
|
611
|
-
const positions = parsed.inventory?.position || [];
|
|
612
|
-
return Array.isArray(positions) ? positions : [positions];
|
|
613
|
-
}
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
## Practice Exercise
|
|
617
|
-
|
|
618
|
-
### Challenge
|
|
619
|
-
|
|
620
|
-
Parse a multi-format dataset and ingest into Fluent Commerce:
|
|
621
|
-
|
|
622
|
-
1. Download sample files (CSV, Parquet, XML, JSON) from S3
|
|
623
|
-
2. Parse each format using the appropriate parser
|
|
624
|
-
3. Validate data structure and required fields
|
|
625
|
-
4. Transform using UniversalMapper
|
|
626
|
-
5. Send to Fluent via Batch API
|
|
627
|
-
6. Track processing metrics (time, records, errors)
|
|
628
|
-
|
|
629
|
-
### Solution Template
|
|
630
|
-
|
|
631
|
-
```typescript
|
|
632
|
-
async function multiFormatIngestionChallenge() {
|
|
633
|
-
const metrics = {
|
|
634
|
-
totalFiles: 0,
|
|
635
|
-
totalRecords: 0,
|
|
636
|
-
successfulFiles: 0,
|
|
637
|
-
failedFiles: 0,
|
|
638
|
-
processingTime: 0
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
const startTime = Date.now();
|
|
642
|
-
|
|
643
|
-
try {
|
|
644
|
-
// Your implementation here
|
|
645
|
-
// 1. List files
|
|
646
|
-
// 2. Parse by format
|
|
647
|
-
// 3. Transform data
|
|
648
|
-
// 4. Send to Fluent
|
|
649
|
-
// 5. Track metrics
|
|
650
|
-
|
|
651
|
-
} finally {
|
|
652
|
-
metrics.processingTime = Date.now() - startTime;
|
|
653
|
-
console.log('Ingestion Metrics:', metrics);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
```
|
|
657
|
-
|
|
658
|
-
## Key Takeaways
|
|
659
|
-
|
|
660
|
-
- 🎯 **Parquet** - Best for large datasets, compressed, typed, fastest
|
|
661
|
-
- 🎯 **XML** - Required for B2B systems, hierarchical data, namespaces
|
|
662
|
-
- 🎯 **JSON** - Modern APIs, flexible, nested structures
|
|
663
|
-
- 🎯 **Streaming** - Essential for memory-efficient processing of large files
|
|
664
|
-
- 🎯 **UniversalMapper** - One mapping config works across ALL formats
|
|
665
|
-
|
|
666
|
-
## Next Steps
|
|
667
|
-
|
|
668
|
-
Continue to [Module 6: Batch API →](./02-core-guides-ingestion-06-batch-api.md) to learn about job creation, batch sending, and status monitoring.
|
|
669
|
-
|
|
670
|
-
---
|
|
671
|
-
|
|
672
|
-
**Need help choosing a parser?**
|
|
673
|
-
- 📊 Large datasets (> 1 GB) → Use Parquet with streaming
|
|
674
|
-
- 🏢 B2B systems → Use XML with namespace handling
|
|
675
|
-
- 🌐 REST APIs → Use JSON with schema validation
|
|
676
|
-
- 📈 Simple exports → Use CSV (Module 3)
|
|
1
|
+
# Module 5: Advanced Parsers
|
|
2
|
+
|
|
3
|
+
**Level:** Intermediate
|
|
4
|
+
**Estimated Time:** 25 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module covers advanced file parsing capabilities beyond CSV, including Parquet for large datasets, XML for B2B systems, and JSON for API integrations.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Parse Parquet files for efficient large dataset processing
|
|
14
|
+
- ✅ Parse XML files from B2B systems and feeds
|
|
15
|
+
- ✅ Parse JSON from APIs and web services
|
|
16
|
+
- ✅ Choose the optimal parser for your use case
|
|
17
|
+
- ✅ Handle streaming for memory-efficient processing
|
|
18
|
+
|
|
19
|
+
## Parquet Parser
|
|
20
|
+
|
|
21
|
+
### Why Parquet?
|
|
22
|
+
|
|
23
|
+
Parquet is a columnar storage format ideal for:
|
|
24
|
+
|
|
25
|
+
| Feature | Benefit |
|
|
26
|
+
|---------|---------|
|
|
27
|
+
| **Compression** | 5-10x smaller than CSV |
|
|
28
|
+
| **Speed** | Faster reads for analytics |
|
|
29
|
+
| **Schema** | Built-in type validation |
|
|
30
|
+
| **Large Files** | Efficient memory usage |
|
|
31
|
+
|
|
32
|
+
### Basic Parquet Parsing
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import {
|
|
36
|
+
ParquetParserService,
|
|
37
|
+
S3DataSource,
|
|
38
|
+
UniversalMapper,
|
|
39
|
+
createConsoleLogger
|
|
40
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
41
|
+
|
|
42
|
+
async function parseParquetFile() {
|
|
43
|
+
// Initialize services
|
|
44
|
+
const logger = createConsoleLogger();
|
|
45
|
+
const s3 = new S3DataSource(
|
|
46
|
+
{
|
|
47
|
+
type: 'S3_PARQUET',
|
|
48
|
+
connectionId: 's3-parquet',
|
|
49
|
+
name: 'S3 Parquet',
|
|
50
|
+
s3Config: {
|
|
51
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
52
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
53
|
+
region: process.env.AWS_REGION!,
|
|
54
|
+
bucket: 'inventory-bucket'
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
logger
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const parquetParser = new ParquetParserService(logger);
|
|
61
|
+
|
|
62
|
+
// Read Parquet file from S3
|
|
63
|
+
const buffer = await s3.downloadFile('data/inventory-positions.parquet', { encoding: 'binary' }) as Buffer;
|
|
64
|
+
|
|
65
|
+
// Parse Parquet
|
|
66
|
+
const records = await parquetParser.parse(buffer);
|
|
67
|
+
console.log(`Parsed ${records.length} records from Parquet file`);
|
|
68
|
+
|
|
69
|
+
// Records are already typed based on Parquet schema
|
|
70
|
+
return records;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Streaming Large Parquet Files
|
|
75
|
+
|
|
76
|
+
For files larger than available memory:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { ParquetParserService, S3DataSource, UniversalMapper, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
80
|
+
|
|
81
|
+
async function streamParquetFile() {
|
|
82
|
+
const logger = createConsoleLogger();
|
|
83
|
+
const s3 = new S3DataSource(
|
|
84
|
+
{
|
|
85
|
+
type: 'S3_PARQUET',
|
|
86
|
+
connectionId: 's3-parquet-stream',
|
|
87
|
+
name: 'S3 Parquet Stream',
|
|
88
|
+
s3Config: {
|
|
89
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
90
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
91
|
+
region: process.env.AWS_REGION!,
|
|
92
|
+
bucket: 'inventory-bucket'
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
logger
|
|
96
|
+
);
|
|
97
|
+
const parquetParser = new ParquetParserService(logger);
|
|
98
|
+
|
|
99
|
+
// Download Parquet file from S3 (full file download)
|
|
100
|
+
const buffer = await s3.downloadFile('data/large-inventory.parquet', { encoding: 'binary' }) as Buffer;
|
|
101
|
+
|
|
102
|
+
// Parse Parquet (parser handles large files efficiently)
|
|
103
|
+
const records = await parquetParser.parse(buffer);
|
|
104
|
+
|
|
105
|
+
// Process records in chunks
|
|
106
|
+
const batchSize = 1000;
|
|
107
|
+
for (let i = 0; i < records.length; i += batchSize) {
|
|
108
|
+
const batch = records.slice(i, i + batchSize);
|
|
109
|
+
await processBatch(batch);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function processBatch(records: any[]) {
|
|
114
|
+
// Map fields
|
|
115
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
116
|
+
const result = await mapper.map(records);
|
|
117
|
+
|
|
118
|
+
if (result.success) {
|
|
119
|
+
// Send to Fluent
|
|
120
|
+
await sendToFluent(result.data);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Parquet Schema Validation
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { ParquetParserService, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
129
|
+
|
|
130
|
+
async function validateParquetSchema(file: Buffer) {
|
|
131
|
+
const logger = createConsoleLogger();
|
|
132
|
+
const parquetParser = new ParquetParserService(logger);
|
|
133
|
+
|
|
134
|
+
// Extract schema information
|
|
135
|
+
const metadata = await parquetParser.getMetadata(file);
|
|
136
|
+
|
|
137
|
+
console.log('Parquet Schema:', {
|
|
138
|
+
numRows: metadata.numRows,
|
|
139
|
+
columns: metadata.schema.fields.map(f => ({
|
|
140
|
+
name: f.name,
|
|
141
|
+
type: f.type,
|
|
142
|
+
optional: f.optional
|
|
143
|
+
})),
|
|
144
|
+
compression: metadata.compression,
|
|
145
|
+
createdBy: metadata.createdBy
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Validate expected columns exist
|
|
149
|
+
const requiredColumns = ['sku', 'location', 'quantity'];
|
|
150
|
+
const schemaColumns = metadata.schema.fields.map(f => f.name);
|
|
151
|
+
|
|
152
|
+
const missingColumns = requiredColumns.filter(
|
|
153
|
+
col => !schemaColumns.includes(col)
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
if (missingColumns.length > 0) {
|
|
157
|
+
throw new Error(`Missing required columns: ${missingColumns.join(', ')}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return metadata;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## XML Parser
|
|
165
|
+
|
|
166
|
+
### Why XML?
|
|
167
|
+
|
|
168
|
+
XML parsing is essential for:
|
|
169
|
+
|
|
170
|
+
| Use Case | Example |
|
|
171
|
+
|----------|---------|
|
|
172
|
+
| **Enterprise Systems** | ERP exports, warehouse management systems |
|
|
173
|
+
| **Standard Formats** | EDI, SOAP, RSS feeds |
|
|
174
|
+
| **Nested Data** | Complex hierarchical structures |
|
|
175
|
+
| **SFCC Orders** | Salesforce Commerce Cloud integrations |
|
|
176
|
+
|
|
177
|
+
### Basic XML Parsing
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
181
|
+
|
|
182
|
+
async function parseXMLFile() {
|
|
183
|
+
const xmlParser = new XMLParserService();
|
|
184
|
+
|
|
185
|
+
const xmlData = `<?xml version="1.0" encoding="UTF-8"?>
|
|
186
|
+
<inventory>
|
|
187
|
+
<position>
|
|
188
|
+
<sku>SKU-WM-001</sku>
|
|
189
|
+
<location>WH-001</location>
|
|
190
|
+
<quantity>500</quantity>
|
|
191
|
+
<status>available</status>
|
|
192
|
+
</position>
|
|
193
|
+
<position>
|
|
194
|
+
<sku>SKU-WM-002</sku>
|
|
195
|
+
<location>WH-001</location>
|
|
196
|
+
<quantity>150</quantity>
|
|
197
|
+
<status>reserved</status>
|
|
198
|
+
</position>
|
|
199
|
+
</inventory>`;
|
|
200
|
+
|
|
201
|
+
// Parse XML to JavaScript object
|
|
202
|
+
const parsed = await xmlParser.parse(xmlData);
|
|
203
|
+
|
|
204
|
+
// Access nested data
|
|
205
|
+
const positions = parsed.inventory.position;
|
|
206
|
+
|
|
207
|
+
console.log(`Parsed ${positions.length} positions from XML`);
|
|
208
|
+
return positions;
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### XML with Path Resolution
|
|
213
|
+
|
|
214
|
+
For complex XML structures, use path-based field mapping:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
async function parseComplexXML() {
|
|
218
|
+
const xmlParser = new XMLParserService();
|
|
219
|
+
|
|
220
|
+
const complexXML = `<?xml version="1.0" encoding="UTF-8"?>
|
|
221
|
+
<warehouse-export>
|
|
222
|
+
<metadata>
|
|
223
|
+
<export-date>2024-01-15</export-date>
|
|
224
|
+
<warehouse>WH-001</warehouse>
|
|
225
|
+
</metadata>
|
|
226
|
+
<inventory-positions>
|
|
227
|
+
<position id="1">
|
|
228
|
+
<product>
|
|
229
|
+
<sku>SKU-WM-001</sku>
|
|
230
|
+
<name>Widget Master 3000</name>
|
|
231
|
+
</product>
|
|
232
|
+
<location>
|
|
233
|
+
<zone>A</zone>
|
|
234
|
+
<aisle>12</aisle>
|
|
235
|
+
<bin>45</bin>
|
|
236
|
+
</location>
|
|
237
|
+
<quantities>
|
|
238
|
+
<on-hand>500</on-hand>
|
|
239
|
+
<available>450</available>
|
|
240
|
+
<reserved>50</reserved>
|
|
241
|
+
</quantities>
|
|
242
|
+
<status>AVAILABLE</status>
|
|
243
|
+
</position>
|
|
244
|
+
</inventory-positions>
|
|
245
|
+
</warehouse-export>`;
|
|
246
|
+
|
|
247
|
+
const parsed = await xmlParser.parse(complexXML);
|
|
248
|
+
|
|
249
|
+
// Extract with path notation
|
|
250
|
+
const mapper = new UniversalMapper({
|
|
251
|
+
fields: {
|
|
252
|
+
ref: {
|
|
253
|
+
source: 'product.sku',
|
|
254
|
+
required: true
|
|
255
|
+
},
|
|
256
|
+
productRef: {
|
|
257
|
+
source: 'product.sku',
|
|
258
|
+
required: true
|
|
259
|
+
},
|
|
260
|
+
locationRef: {
|
|
261
|
+
source: 'warehouse', // From root metadata
|
|
262
|
+
resolver: (value, data) => {
|
|
263
|
+
// Combine location parts
|
|
264
|
+
return `${data.location.zone}-${data.location.aisle}-${data.location.bin}`;
|
|
265
|
+
},
|
|
266
|
+
required: true
|
|
267
|
+
},
|
|
268
|
+
qty: {
|
|
269
|
+
source: 'quantities.on-hand',
|
|
270
|
+
resolver: 'sdk.parseInt',
|
|
271
|
+
required: true
|
|
272
|
+
},
|
|
273
|
+
status: {
|
|
274
|
+
source: 'status',
|
|
275
|
+
resolver: 'sdk.uppercase',
|
|
276
|
+
required: true
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Map each position
|
|
282
|
+
const positions = parsed['warehouse-export']['inventory-positions'].position;
|
|
283
|
+
const result = await mapper.map(positions);
|
|
284
|
+
|
|
285
|
+
return result.data;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### XML Namespace Handling
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
async function parseXMLWithNamespaces() {
|
|
293
|
+
const xmlParser = new XMLParserService({
|
|
294
|
+
ignoreAttributes: false,
|
|
295
|
+
attributeNamePrefix: '@_',
|
|
296
|
+
parseAttributeValue: true
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
const nsXML = `<?xml version="1.0" encoding="UTF-8"?>
|
|
300
|
+
<inv:inventory xmlns:inv="http://example.com/inventory" xmlns:prod="http://example.com/product">
|
|
301
|
+
<inv:position inv:id="1">
|
|
302
|
+
<prod:sku>SKU-WM-001</prod:sku>
|
|
303
|
+
<inv:location>WH-001</inv:location>
|
|
304
|
+
<inv:quantity>500</inv:quantity>
|
|
305
|
+
</inv:position>
|
|
306
|
+
</inv:inventory>`;
|
|
307
|
+
|
|
308
|
+
const parsed = await xmlParser.parse(nsXML);
|
|
309
|
+
|
|
310
|
+
// Access namespaced elements
|
|
311
|
+
console.log('Parsed with namespaces:', parsed);
|
|
312
|
+
return parsed;
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## JSON Parser
|
|
317
|
+
|
|
318
|
+
### Why JSON?
|
|
319
|
+
|
|
320
|
+
JSON parsing is ideal for:
|
|
321
|
+
|
|
322
|
+
| Use Case | Example |
|
|
323
|
+
|----------|---------|
|
|
324
|
+
| **REST APIs** | Third-party inventory services |
|
|
325
|
+
| **Web Services** | Cloud-based systems |
|
|
326
|
+
| **Modern Exports** | Contemporary systems |
|
|
327
|
+
| **Nested Objects** | Complex data structures |
|
|
328
|
+
|
|
329
|
+
### Basic JSON Parsing
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
333
|
+
|
|
334
|
+
async function parseJSONFile() {
|
|
335
|
+
const jsonParser = new JSONParserService();
|
|
336
|
+
|
|
337
|
+
const jsonData = {
|
|
338
|
+
"metadata": {
|
|
339
|
+
"export_date": "2024-01-15",
|
|
340
|
+
"total_records": 2
|
|
341
|
+
},
|
|
342
|
+
"inventory_positions": [
|
|
343
|
+
{
|
|
344
|
+
"sku": "SKU-WM-001",
|
|
345
|
+
"location": "WH-001",
|
|
346
|
+
"quantity": 500,
|
|
347
|
+
"status": "available"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"sku": "SKU-WM-002",
|
|
351
|
+
"location": "WH-001",
|
|
352
|
+
"quantity": 150,
|
|
353
|
+
"status": "reserved"
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
// Parse JSON (validates structure)
|
|
359
|
+
const parsed = await jsonParser.parse(JSON.stringify(jsonData));
|
|
360
|
+
|
|
361
|
+
const positions = parsed.inventory_positions;
|
|
362
|
+
console.log(`Parsed ${positions.length} positions from JSON`);
|
|
363
|
+
|
|
364
|
+
return positions;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### JSON Array Streaming
|
|
369
|
+
|
|
370
|
+
For large JSON arrays, use streaming to avoid memory issues:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import { S3DataSource, JSONParserService, createConsoleLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
374
|
+
|
|
375
|
+
async function streamLargeJSONArray() {
|
|
376
|
+
const logger = createConsoleLogger();
|
|
377
|
+
const s3 = new S3DataSource(
|
|
378
|
+
{
|
|
379
|
+
type: 'S3_JSON',
|
|
380
|
+
connectionId: 's3-json-stream',
|
|
381
|
+
name: 'S3 JSON Stream',
|
|
382
|
+
s3Config: {
|
|
383
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
384
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
385
|
+
region: process.env.AWS_REGION!,
|
|
386
|
+
bucket: 'inventory-bucket'
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
logger
|
|
390
|
+
);
|
|
391
|
+
const jsonParser = new JSONParserService();
|
|
392
|
+
|
|
393
|
+
// Download JSON file from S3
|
|
394
|
+
const jsonContent = await s3.downloadFile('data/large-inventory.json') as string;
|
|
395
|
+
|
|
396
|
+
// Parse JSON array
|
|
397
|
+
const parsed = await jsonParser.parse(jsonContent);
|
|
398
|
+
const positions = parsed.inventory_positions || [];
|
|
399
|
+
|
|
400
|
+
// Process records in batches
|
|
401
|
+
const batchSize = 1000;
|
|
402
|
+
let count = 0;
|
|
403
|
+
for (let i = 0; i < positions.length; i += batchSize) {
|
|
404
|
+
const batch = positions.slice(i, i + batchSize);
|
|
405
|
+
for (const record of batch) {
|
|
406
|
+
await processRecord(record);
|
|
407
|
+
count++;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (count % 1000 === 0) {
|
|
411
|
+
console.log(`Processed ${count} records...`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
console.log(`Total records processed: ${count}`);
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### JSON Schema Validation
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
async function validateJSONSchema(data: any) {
|
|
423
|
+
const schema = {
|
|
424
|
+
type: 'object',
|
|
425
|
+
required: ['inventory_positions'],
|
|
426
|
+
properties: {
|
|
427
|
+
metadata: {
|
|
428
|
+
type: 'object',
|
|
429
|
+
properties: {
|
|
430
|
+
export_date: { type: 'string' },
|
|
431
|
+
total_records: { type: 'number' }
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
inventory_positions: {
|
|
435
|
+
type: 'array',
|
|
436
|
+
items: {
|
|
437
|
+
type: 'object',
|
|
438
|
+
required: ['sku', 'location', 'quantity'],
|
|
439
|
+
properties: {
|
|
440
|
+
sku: { type: 'string' },
|
|
441
|
+
location: { type: 'string' },
|
|
442
|
+
quantity: { type: 'number' },
|
|
443
|
+
status: { type: 'string' }
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const jsonParser = new JSONParserService({ schema });
|
|
451
|
+
|
|
452
|
+
// Validate and parse
|
|
453
|
+
const result = await jsonParser.parseWithValidation(data);
|
|
454
|
+
|
|
455
|
+
if (!result.valid) {
|
|
456
|
+
throw new Error(`JSON validation failed: ${result.errors.join(', ')}`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return result.data;
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Parser Comparison
|
|
464
|
+
|
|
465
|
+
### When to Use Which Parser
|
|
466
|
+
|
|
467
|
+
| Parser | Best For | Pros | Cons | File Size Limit |
|
|
468
|
+
|--------|----------|------|------|-----------------|
|
|
469
|
+
| **CSV** | Simple tabular data, exports, integrations | Universal, easy to inspect | No schema, flat structure | < 1 GB with streaming |
|
|
470
|
+
| **Parquet** | Large datasets, analytics, data lakes | Fast, compressed, typed | Binary, needs tools | Unlimited with streaming |
|
|
471
|
+
| **XML** | Enterprise systems, SOAP, hierarchical data | Structured, validated, nested | Verbose, complex parsing | < 500 MB |
|
|
472
|
+
| **JSON** | REST APIs, modern systems, web services | Flexible, nested, readable | Can be large, no schema | < 500 MB with streaming |
|
|
473
|
+
|
|
474
|
+
### Performance Comparison
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
async function benchmarkParsers() {
|
|
478
|
+
const testData = generateTestData(10000); // 10K records
|
|
479
|
+
|
|
480
|
+
// CSV Performance
|
|
481
|
+
const csvStart = Date.now();
|
|
482
|
+
const csvParser = new CSVParserService();
|
|
483
|
+
const csvData = await csvParser.parse(toCSV(testData), { columns: true });
|
|
484
|
+
console.log(`CSV: ${Date.now() - csvStart}ms`);
|
|
485
|
+
|
|
486
|
+
// Parquet Performance
|
|
487
|
+
const parquetStart = Date.now();
|
|
488
|
+
const logger = createConsoleLogger();
|
|
489
|
+
const parquetParser = new ParquetParserService(logger);
|
|
490
|
+
const parquetData = await parquetParser.parse(toParquet(testData));
|
|
491
|
+
console.log(`Parquet: ${Date.now() - parquetStart}ms`);
|
|
492
|
+
|
|
493
|
+
// XML Performance
|
|
494
|
+
const xmlStart = Date.now();
|
|
495
|
+
const xmlParser = new XMLParserService();
|
|
496
|
+
const xmlData = await xmlParser.parse(toXML(testData));
|
|
497
|
+
console.log(`XML: ${Date.now() - xmlStart}ms`);
|
|
498
|
+
|
|
499
|
+
// JSON Performance
|
|
500
|
+
const jsonStart = Date.now();
|
|
501
|
+
const jsonParser = new JSONParserService();
|
|
502
|
+
const jsonData = await jsonParser.parse(toJSON(testData));
|
|
503
|
+
console.log(`JSON: ${Date.now() - jsonStart}ms`);
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Complete Example: Multi-Format Ingestion
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
import {
|
|
511
|
+
createClient,
|
|
512
|
+
S3DataSource,
|
|
513
|
+
CSVParserService,
|
|
514
|
+
ParquetParserService,
|
|
515
|
+
XMLParserService,
|
|
516
|
+
JSONParserService,
|
|
517
|
+
UniversalMapper,
|
|
518
|
+
createConsoleLogger
|
|
519
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
520
|
+
|
|
521
|
+
async function ingestMultiFormat() {
|
|
522
|
+
const logger = createConsoleLogger();
|
|
523
|
+
|
|
524
|
+
const client = await createClient({
|
|
525
|
+
config: {
|
|
526
|
+
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
527
|
+
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
528
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
529
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
const s3 = new S3DataSource(
|
|
534
|
+
{
|
|
535
|
+
type: 'S3_CSV',
|
|
536
|
+
connectionId: 's3-multi-format',
|
|
537
|
+
name: 'S3 Multi-Format',
|
|
538
|
+
s3Config: {
|
|
539
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
540
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
541
|
+
region: process.env.AWS_REGION!,
|
|
542
|
+
bucket: 'inventory-bucket'
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
logger
|
|
546
|
+
);
|
|
547
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
548
|
+
|
|
549
|
+
// List all files
|
|
550
|
+
const files = await s3.listFiles({ prefix: 'data/' });
|
|
551
|
+
|
|
552
|
+
for (const file of files) {
|
|
553
|
+
let records: any[];
|
|
554
|
+
|
|
555
|
+
// Choose parser based on file extension
|
|
556
|
+
if (file.name.endsWith('.csv')) {
|
|
557
|
+
const csvParser = new CSVParserService();
|
|
558
|
+
const data = await s3.downloadFile(file.path) as string;
|
|
559
|
+
records = await csvParser.parse(data);
|
|
560
|
+
|
|
561
|
+
} else if (file.name.endsWith('.parquet')) {
|
|
562
|
+
const parquetParser = new ParquetParserService(logger);
|
|
563
|
+
const data = await s3.downloadFile(file.path, { encoding: 'binary' }) as Buffer;
|
|
564
|
+
records = await parquetParser.parse(data);
|
|
565
|
+
|
|
566
|
+
} else if (file.name.endsWith('.xml')) {
|
|
567
|
+
const xmlParser = new XMLParserService(logger);
|
|
568
|
+
const data = await s3.downloadFile(file.path) as string;
|
|
569
|
+
const parsed = await xmlParser.parse(data);
|
|
570
|
+
records = extractInventoryFromXML(parsed);
|
|
571
|
+
|
|
572
|
+
} else if (file.name.endsWith('.json')) {
|
|
573
|
+
const jsonParser = new JSONParserService();
|
|
574
|
+
const data = await s3.downloadFile(file.path) as string;
|
|
575
|
+
const parsed = await jsonParser.parse(data);
|
|
576
|
+
records = parsed.inventory_positions || [];
|
|
577
|
+
|
|
578
|
+
} else {
|
|
579
|
+
console.log(`Skipping unsupported file: ${file.name}`);
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Transform with UniversalMapper
|
|
584
|
+
const result = await mapper.map(records);
|
|
585
|
+
|
|
586
|
+
if (!result.success) {
|
|
587
|
+
console.error(`Mapping failed for ${file.name}:`, result.errors);
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Send to Fluent
|
|
592
|
+
const job = await client.createJob({
|
|
593
|
+
name: `Import - ${file.name}`,
|
|
594
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
await client.sendBatch(job.id, {
|
|
598
|
+
action: 'UPSERT',
|
|
599
|
+
entityType: 'INVENTORY',
|
|
600
|
+
source: 'S3_CSV',
|
|
601
|
+
event: 'INVENTORY_SYNC',
|
|
602
|
+
entities: result.data
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
console.log(`Processed ${result.data.length} records from ${file.name}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
function extractInventoryFromXML(parsed: any): any[] {
|
|
610
|
+
// Extract inventory positions from XML structure
|
|
611
|
+
const positions = parsed.inventory?.position || [];
|
|
612
|
+
return Array.isArray(positions) ? positions : [positions];
|
|
613
|
+
}
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## Practice Exercise
|
|
617
|
+
|
|
618
|
+
### Challenge
|
|
619
|
+
|
|
620
|
+
Parse a multi-format dataset and ingest into Fluent Commerce:
|
|
621
|
+
|
|
622
|
+
1. Download sample files (CSV, Parquet, XML, JSON) from S3
|
|
623
|
+
2. Parse each format using the appropriate parser
|
|
624
|
+
3. Validate data structure and required fields
|
|
625
|
+
4. Transform using UniversalMapper
|
|
626
|
+
5. Send to Fluent via Batch API
|
|
627
|
+
6. Track processing metrics (time, records, errors)
|
|
628
|
+
|
|
629
|
+
### Solution Template
|
|
630
|
+
|
|
631
|
+
```typescript
|
|
632
|
+
async function multiFormatIngestionChallenge() {
|
|
633
|
+
const metrics = {
|
|
634
|
+
totalFiles: 0,
|
|
635
|
+
totalRecords: 0,
|
|
636
|
+
successfulFiles: 0,
|
|
637
|
+
failedFiles: 0,
|
|
638
|
+
processingTime: 0
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
const startTime = Date.now();
|
|
642
|
+
|
|
643
|
+
try {
|
|
644
|
+
// Your implementation here
|
|
645
|
+
// 1. List files
|
|
646
|
+
// 2. Parse by format
|
|
647
|
+
// 3. Transform data
|
|
648
|
+
// 4. Send to Fluent
|
|
649
|
+
// 5. Track metrics
|
|
650
|
+
|
|
651
|
+
} finally {
|
|
652
|
+
metrics.processingTime = Date.now() - startTime;
|
|
653
|
+
console.log('Ingestion Metrics:', metrics);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
## Key Takeaways
|
|
659
|
+
|
|
660
|
+
- 🎯 **Parquet** - Best for large datasets, compressed, typed, fastest
|
|
661
|
+
- 🎯 **XML** - Required for B2B systems, hierarchical data, namespaces
|
|
662
|
+
- 🎯 **JSON** - Modern APIs, flexible, nested structures
|
|
663
|
+
- 🎯 **Streaming** - Essential for memory-efficient processing of large files
|
|
664
|
+
- 🎯 **UniversalMapper** - One mapping config works across ALL formats
|
|
665
|
+
|
|
666
|
+
## Next Steps
|
|
667
|
+
|
|
668
|
+
Continue to [Module 6: Batch API →](./02-core-guides-ingestion-06-batch-api.md) to learn about job creation, batch sending, and status monitoring.
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
**Need help choosing a parser?**
|
|
673
|
+
- 📊 Large datasets (> 1 GB) → Use Parquet with streaming
|
|
674
|
+
- 🏢 B2B systems → Use XML with namespace handling
|
|
675
|
+
- 🌐 REST APIs → Use JSON with schema validation
|
|
676
|
+
- 📈 Simple exports → Use CSV (Module 3)
|