@fluentcommerce/fc-connect-sdk 0.1.53 → 0.1.55
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 +30 -2
- package/README.md +39 -0
- package/dist/cjs/auth/index.d.ts +3 -0
- package/dist/cjs/auth/index.js +13 -0
- package/dist/cjs/auth/profile-loader.d.ts +18 -0
- package/dist/cjs/auth/profile-loader.js +208 -0
- package/dist/cjs/client-factory.d.ts +4 -0
- package/dist/cjs/client-factory.js +10 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/auth/index.d.ts +3 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/profile-loader.d.ts +18 -0
- package/dist/esm/auth/profile-loader.js +169 -0
- package/dist/esm/client-factory.d.ts +4 -0
- package/dist/esm/client-factory.js +9 -0
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- 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/dist/types/auth/index.d.ts +3 -0
- package/dist/types/auth/profile-loader.d.ts +18 -0
- package/dist/types/client-factory.d.ts +4 -0
- package/dist/types/index.d.ts +3 -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 -482
- 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
|
@@ -1,857 +1,857 @@
|
|
|
1
|
-
# Module 4: XML Parser
|
|
2
|
-
|
|
3
|
-
**Level:** Intermediate
|
|
4
|
-
**Estimated Time:** 30 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module covers the XML Parser (`XMLParserService`), essential for integrating with EDI feeds, B2B systems, and platforms like SFCC. You'll learn how to parse XML, handle attributes, use path resolution, generate XML from data, and integrate with SDK services.
|
|
9
|
-
|
|
10
|
-
### Minimal Mode (start here)
|
|
11
|
-
|
|
12
|
-
If you just need to parse XML, start with the simplest call:
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
16
|
-
|
|
17
|
-
const parsed = await new XMLParserService().parse(xmlString, {
|
|
18
|
-
includeAttributes: false, // simplest shape
|
|
19
|
-
parseBooleans: true, // optional normalization
|
|
20
|
-
parseNumbers: true, // optional normalization
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Or use fast-xml-parser directly if you prefer; the SDK mapping works with any compatible shape.
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Advanced options (attributes, selectors, streaming, path resolver) are optional—use only if needed.
|
|
27
|
-
|
|
28
|
-
## Learning Objectives
|
|
29
|
-
|
|
30
|
-
By the end of this module, you will:
|
|
31
|
-
|
|
32
|
-
- ✅ Parse XML documents into JavaScript objects
|
|
33
|
-
- ✅ Access elements and attributes directly from parsed structure
|
|
34
|
-
- ✅ Generate XML from JavaScript objects using XMLBuilder
|
|
35
|
-
- ✅ Handle large XML files with streaming
|
|
36
|
-
- ✅ Transform XML data with UniversalMapper
|
|
37
|
-
- ✅ Integrate with GraphQLMutationMapper for SFCC orders
|
|
38
|
-
|
|
39
|
-
## What is XML?
|
|
40
|
-
|
|
41
|
-
**XML (eXtensible Markup Language)** is a hierarchical markup format that:
|
|
42
|
-
|
|
43
|
-
- Uses tags to define structure: `<element>value</element>`
|
|
44
|
-
- Supports attributes: `<product id="123">`
|
|
45
|
-
- Can represent complex nested data
|
|
46
|
-
- Is self-describing with optional schemas
|
|
47
|
-
|
|
48
|
-
**Example:**
|
|
49
|
-
|
|
50
|
-
```xml
|
|
51
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
52
|
-
<products>
|
|
53
|
-
<product id="P001" category="electronics">
|
|
54
|
-
<sku>SKU001</sku>
|
|
55
|
-
<name>Wireless Mouse</name>
|
|
56
|
-
<price currency="USD">29.99</price>
|
|
57
|
-
<stock warehouse="WH-01">150</stock>
|
|
58
|
-
</product>
|
|
59
|
-
</products>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Basic XML Parsing
|
|
63
|
-
|
|
64
|
-
### Simple Parsing
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
68
|
-
|
|
69
|
-
const xmlParser = new XMLParserService();
|
|
70
|
-
|
|
71
|
-
// Sample XML data
|
|
72
|
-
const xmlContent = `
|
|
73
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
74
|
-
<inventory>
|
|
75
|
-
<product>
|
|
76
|
-
<sku>SKU001</sku>
|
|
77
|
-
<name>Product 1</name>
|
|
78
|
-
<quantity>100</quantity>
|
|
79
|
-
<price>29.99</price>
|
|
80
|
-
</product>
|
|
81
|
-
<product>
|
|
82
|
-
<sku>SKU002</sku>
|
|
83
|
-
<name>Product 2</name>
|
|
84
|
-
<quantity>50</quantity>
|
|
85
|
-
<price>49.99</price>
|
|
86
|
-
</product>
|
|
87
|
-
</inventory>
|
|
88
|
-
`;
|
|
89
|
-
|
|
90
|
-
// Parse XML
|
|
91
|
-
const parsed = await xmlParser.parse(xmlContent);
|
|
92
|
-
console.log('Parsed data:', parsed);
|
|
93
|
-
|
|
94
|
-
// Access products
|
|
95
|
-
const products = parsed.inventory?.product;
|
|
96
|
-
console.log('Products:', products);
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Parsing with Attributes
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
const xmlWithAttributes = `
|
|
103
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
104
|
-
<catalog>
|
|
105
|
-
<product id="P001" category="electronics">
|
|
106
|
-
<name>Laptop</name>
|
|
107
|
-
<price currency="USD">999.99</price>
|
|
108
|
-
<stock warehouse="W01">25</stock>
|
|
109
|
-
</product>
|
|
110
|
-
</catalog>
|
|
111
|
-
`;
|
|
112
|
-
|
|
113
|
-
const parsed = await xmlParser.parse(xmlWithAttributes);
|
|
114
|
-
|
|
115
|
-
// Access attributes using @ prefix (NO underscore)
|
|
116
|
-
// For simple parsing, access parsed structure directly
|
|
117
|
-
const productId = parsed.catalog?.product?.['@id']; // 'P001'
|
|
118
|
-
const category = parsed.catalog?.product?.['@category']; // 'electronics'
|
|
119
|
-
const name = parsed.catalog?.product?.name; // 'Laptop'
|
|
120
|
-
const price = parsed.catalog?.product?.price; // 999.99
|
|
121
|
-
const currency = parsed.catalog?.product?.price?.['@currency']; // 'USD'
|
|
122
|
-
const stock = parsed.catalog?.product?.stock; // 25
|
|
123
|
-
const warehouse = parsed.catalog?.product?.stock?.['@warehouse']; // 'W01'
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## XML Parser Output Reference
|
|
127
|
-
|
|
128
|
-
### Understanding Parser Output Structure
|
|
129
|
-
|
|
130
|
-
The XML parser transforms XML into JavaScript objects following these rules:
|
|
131
|
-
|
|
132
|
-
**Root Element Becomes Top-Level Key:**
|
|
133
|
-
```xml
|
|
134
|
-
<root>
|
|
135
|
-
<data>value</data>
|
|
136
|
-
</root>
|
|
137
|
-
```
|
|
138
|
-
**Output:**
|
|
139
|
-
```javascript
|
|
140
|
-
{
|
|
141
|
-
root: {
|
|
142
|
-
data: "value"
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**Attributes Prefixed with `@` (when `includeAttributes: true`):**
|
|
148
|
-
```xml
|
|
149
|
-
<product id="123" category="electronics">
|
|
150
|
-
<name>Laptop</name>
|
|
151
|
-
</product>
|
|
152
|
-
```
|
|
153
|
-
**Output:**
|
|
154
|
-
```javascript
|
|
155
|
-
{
|
|
156
|
-
product: {
|
|
157
|
-
"@id": "123",
|
|
158
|
-
"@category": "electronics",
|
|
159
|
-
name: "Laptop"
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Single vs Multiple Elements:**
|
|
165
|
-
```xml
|
|
166
|
-
<!-- Single element = object -->
|
|
167
|
-
<products>
|
|
168
|
-
<product><sku>SKU-001</sku></product>
|
|
169
|
-
</products>
|
|
170
|
-
|
|
171
|
-
<!-- Multiple elements = array -->
|
|
172
|
-
<products>
|
|
173
|
-
<product><sku>SKU-001</sku></product>
|
|
174
|
-
<product><sku>SKU-002</sku></product>
|
|
175
|
-
</products>
|
|
176
|
-
```
|
|
177
|
-
**Output:**
|
|
178
|
-
```javascript
|
|
179
|
-
// Single
|
|
180
|
-
{ products: { product: { sku: "SKU-001" } } }
|
|
181
|
-
|
|
182
|
-
// Multiple
|
|
183
|
-
{ products: { product: [{ sku: "SKU-001" }, { sku: "SKU-002" }] } }
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**⚠️ Important:** Always normalize single elements to arrays:
|
|
187
|
-
```typescript
|
|
188
|
-
const products = parsed.products?.product;
|
|
189
|
-
const records = Array.isArray(products) ? products : products ? [products] : [];
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
**Mixed Content (Attributes + Text):**
|
|
193
|
-
```xml
|
|
194
|
-
<price currency="USD">999.99</price>
|
|
195
|
-
```
|
|
196
|
-
**Output:**
|
|
197
|
-
```javascript
|
|
198
|
-
{
|
|
199
|
-
price: {
|
|
200
|
-
"@currency": "USD",
|
|
201
|
-
"#text": "999.99" // Text content when element has attributes
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
**Auto-Parsing (Default Behavior):**
|
|
207
|
-
- Numbers: `"29.99"` → `29.99`
|
|
208
|
-
- Booleans: `"true"` → `true`
|
|
209
|
-
- Disable with: `parseNumbers: false`, `parseBooleans: false`
|
|
210
|
-
|
|
211
|
-
## Accessing Parsed XML Data
|
|
212
|
-
|
|
213
|
-
**For simple parsing:** Access the parsed structure directly using standard JavaScript property access.
|
|
214
|
-
|
|
215
|
-
**For complex mapping:** Use `XMLPathResolver` from the mapping services layer (NOT exported from parsers). See `GraphQLMutationMapper` documentation for advanced path resolution with complex queries.
|
|
216
|
-
|
|
217
|
-
### Path Syntax Reference (for reference only - use direct access for simple parsing)
|
|
218
|
-
|
|
219
|
-
| Pattern | Description | XML Example | Path | Result |
|
|
220
|
-
| ---------------------- | ------------------ | ------------------------------ | --------------------- | -------------- |
|
|
221
|
-
| `element` | Element value | `<sku>ABC123</sku>` | `sku` | `'ABC123'` |
|
|
222
|
-
| `element@attr` | Attribute value | `<order id="123">` | `order@id` | `'123'` |
|
|
223
|
-
| `parent.child` | Nested element | `<order><ref>A1</ref></order>` | `order.ref` | `'A1'` |
|
|
224
|
-
| `element[0]` | Array index | `<item>` repeated | `items.item[0]` | First item |
|
|
225
|
-
| `element.*` | All array items | `<item>` repeated | `items.item.*` | Array of all |
|
|
226
|
-
| `element[id=123]@attr` | Filter + attribute | With `id` attribute | `item[id=123]@status` | Filtered value |
|
|
227
|
-
|
|
228
|
-
### Working with Mixed Content
|
|
229
|
-
|
|
230
|
-
When XML elements have both attributes and text content:
|
|
231
|
-
|
|
232
|
-
```xml
|
|
233
|
-
<price currency="USD">999.99</price>
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
// Direct access to parsed structure (recommended for simple parsing)
|
|
238
|
-
const value = parsed.price; // 999.99
|
|
239
|
-
const currency = parsed.price?.['@_currency']; // 'USD'
|
|
240
|
-
|
|
241
|
-
// ℹ️ XMLPathResolver is part of the mapping services layer (not parsers)
|
|
242
|
-
// For advanced path resolution with complex queries, see GraphQLMutationMapper documentation
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Best Practice
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
// ✅ For simple parsing: Access parsed structure directly
|
|
249
|
-
const orderDate = parsed.order?.['order-date']; // Simple and direct
|
|
250
|
-
|
|
251
|
-
// ℹ️ For complex mapping with XMLPathResolver:
|
|
252
|
-
// XMLPathResolver is part of the mapping services (NOT exported from parsers)
|
|
253
|
-
// Import: import { GraphQLMutationMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
254
|
-
// See GraphQLMutationMapper documentation for advanced path resolution
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## Generating XML from JSON
|
|
258
|
-
|
|
259
|
-
The SDK provides `XMLBuilder` for creating XML from JavaScript objects.
|
|
260
|
-
|
|
261
|
-
### Understanding the `#text` Pattern
|
|
262
|
-
|
|
263
|
-
When generating XML, you use the `XMLBuilder` from `fast-xml-parser` with special keys:
|
|
264
|
-
|
|
265
|
-
| JSON Key | XML Output | Purpose |
|
|
266
|
-
| ----------- | ------------- | -------------------------- |
|
|
267
|
-
| `@prefix` | Attribute | `<Order id="123">` |
|
|
268
|
-
| `#text` | Text content | `<ItemId>SKU001</ItemId>` |
|
|
269
|
-
| `fieldName` | Child element | `<Customer>...</Customer>` |
|
|
270
|
-
|
|
271
|
-
**Why `#text`?** This is the standard convention used by `fast-xml-parser` to represent text content in JSON. When parsing XML, attributes use `@` prefix (e.g., `@id`), and when building XML, you use the same patterns.
|
|
272
|
-
|
|
273
|
-
### Decision Tree - When to use `#text`:
|
|
274
|
-
|
|
275
|
-
```
|
|
276
|
-
Does the element have attributes?
|
|
277
|
-
├─ NO → Just use field name: "ItemId": "SKU001"
|
|
278
|
-
│ Result: <ItemId>SKU001</ItemId>
|
|
279
|
-
│
|
|
280
|
-
└─ YES → Does it also have text content?
|
|
281
|
-
├─ NO → Just use @prefix: "@id": "123"
|
|
282
|
-
│ Result: <Order id="123"/>
|
|
283
|
-
│
|
|
284
|
-
└─ YES → Use BOTH @prefix AND #text
|
|
285
|
-
"@id": "9101", "#text": "MULTI-COLOR"
|
|
286
|
-
Result: <Color id="9101">MULTI-COLOR</Color>
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### Simple XML Generation
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
import { XMLBuilder } from 'fast-xml-parser';
|
|
293
|
-
|
|
294
|
-
const builder = new XMLBuilder({
|
|
295
|
-
ignoreAttributes: false,
|
|
296
|
-
attributeNamePrefix: '@',
|
|
297
|
-
textNodeName: '#text',
|
|
298
|
-
format: true,
|
|
299
|
-
indentBy: ' ',
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
// Simple element with text
|
|
303
|
-
const data = {
|
|
304
|
-
Order: {
|
|
305
|
-
ItemId: 'SKU001',
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
const xml = builder.build(data);
|
|
310
|
-
// Output:
|
|
311
|
-
// <Order>
|
|
312
|
-
// <ItemId>SKU001</ItemId>
|
|
313
|
-
// </Order>
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### XML with Attributes
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
// Element with attributes only
|
|
320
|
-
const data = {
|
|
321
|
-
Order: {
|
|
322
|
-
'@id': '12345',
|
|
323
|
-
'@status': 'confirmed',
|
|
324
|
-
},
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
const xml = builder.build(data);
|
|
328
|
-
// Output:
|
|
329
|
-
// <Order id="12345" status="confirmed"/>
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Mixed Content: Attributes AND Text
|
|
333
|
-
|
|
334
|
-
**This is where `#text` is essential:**
|
|
335
|
-
|
|
336
|
-
```typescript
|
|
337
|
-
// Element with BOTH attribute AND text content
|
|
338
|
-
const data = {
|
|
339
|
-
Color: {
|
|
340
|
-
'@id': '9101',
|
|
341
|
-
'#text': 'MULTI-COLOR',
|
|
342
|
-
},
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
const xml = builder.build(data);
|
|
346
|
-
// Output:
|
|
347
|
-
// <Product>
|
|
348
|
-
// <Color id="9101">MULTI-COLOR</Color>
|
|
349
|
-
// </Product>
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### Complex Example: Order with Multiple Patterns
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
const orderData = {
|
|
356
|
-
Order: {
|
|
357
|
-
// Attributes on Order element
|
|
358
|
-
'@customerOrderId': '12345',
|
|
359
|
-
'@levelOfService': 'REGULAR',
|
|
360
|
-
|
|
361
|
-
// Child elements
|
|
362
|
-
Customer: {
|
|
363
|
-
'@customerId': '232',
|
|
364
|
-
Name: {
|
|
365
|
-
FirstName: 'John',
|
|
366
|
-
LastName: 'Doe',
|
|
367
|
-
},
|
|
368
|
-
EmailAddress: 'john@example.com',
|
|
369
|
-
},
|
|
370
|
-
|
|
371
|
-
// Element with attribute AND text
|
|
372
|
-
OrderSource: {
|
|
373
|
-
'@type': 'source',
|
|
374
|
-
'#text': 'WEBSTORE',
|
|
375
|
-
},
|
|
376
|
-
|
|
377
|
-
// Array of items
|
|
378
|
-
OrderItems: {
|
|
379
|
-
OrderItem: [
|
|
380
|
-
{
|
|
381
|
-
'@id': 'item1',
|
|
382
|
-
'@webLineId': '1',
|
|
383
|
-
ItemId: 'SKU001',
|
|
384
|
-
Quantity: 2,
|
|
385
|
-
Description: {
|
|
386
|
-
Description: 'Wireless Mouse',
|
|
387
|
-
Color: {
|
|
388
|
-
'@id': '9101',
|
|
389
|
-
'#text': 'Black',
|
|
390
|
-
},
|
|
391
|
-
Size: {
|
|
392
|
-
'@id': 'M',
|
|
393
|
-
'#text': 'Medium',
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
},
|
|
397
|
-
],
|
|
398
|
-
},
|
|
399
|
-
},
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
const xml = builder.build(orderData, 'OrderDetailResponse');
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
**Generated XML:**
|
|
406
|
-
|
|
407
|
-
```xml
|
|
408
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
409
|
-
<OrderDetailResponse>
|
|
410
|
-
<Order customerOrderId="12345" levelOfService="REGULAR">
|
|
411
|
-
<Customer customerId="232">
|
|
412
|
-
<Name>
|
|
413
|
-
<FirstName>John</FirstName>
|
|
414
|
-
<LastName>Doe</LastName>
|
|
415
|
-
</Name>
|
|
416
|
-
<EmailAddress>john@example.com</EmailAddress>
|
|
417
|
-
</Customer>
|
|
418
|
-
<OrderSource type="source">WEBSTORE</OrderSource>
|
|
419
|
-
<OrderItems>
|
|
420
|
-
<OrderItem id="item1" webLineId="1">
|
|
421
|
-
<ItemId>SKU001</ItemId>
|
|
422
|
-
<Quantity>2</Quantity>
|
|
423
|
-
<Description>
|
|
424
|
-
<Description>Wireless Mouse</Description>
|
|
425
|
-
<Color id="9101">Black</Color>
|
|
426
|
-
<Size id="M">Medium</Size>
|
|
427
|
-
</Description>
|
|
428
|
-
</OrderItem>
|
|
429
|
-
</OrderItems>
|
|
430
|
-
</Order>
|
|
431
|
-
</OrderDetailResponse>
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
### Common Patterns Reference
|
|
435
|
-
|
|
436
|
-
#### Pattern 1: Simple Text Element
|
|
437
|
-
|
|
438
|
-
```typescript
|
|
439
|
-
"ItemId": "SKU001"
|
|
440
|
-
// → <ItemId>SKU001</ItemId>
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
#### Pattern 2: Attribute Only
|
|
444
|
-
|
|
445
|
-
```typescript
|
|
446
|
-
"DestinationTarget": {
|
|
447
|
-
"@ref": "dest-123"
|
|
448
|
-
}
|
|
449
|
-
// → <DestinationTarget ref="dest-123"/>
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
#### Pattern 3: Attribute + Text (`#text`)
|
|
453
|
-
|
|
454
|
-
```typescript
|
|
455
|
-
"Size": {
|
|
456
|
-
"@id": "1214",
|
|
457
|
-
"#text": "M 12.0/ W 14.0"
|
|
458
|
-
}
|
|
459
|
-
// → <Size id="1214">M 12.0/ W 14.0</Size>
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
#### Pattern 4: Nested Children
|
|
463
|
-
|
|
464
|
-
```typescript
|
|
465
|
-
"Customer": {
|
|
466
|
-
"@id": "232",
|
|
467
|
-
"Name": {
|
|
468
|
-
"FirstName": "John",
|
|
469
|
-
"LastName": "Doe"
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
// → <Customer id="232">
|
|
473
|
-
// <Name>
|
|
474
|
-
// <FirstName>John</FirstName>
|
|
475
|
-
// <LastName>Doe</LastName>
|
|
476
|
-
// </Name>
|
|
477
|
-
// </Customer>
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
#### Pattern 5: Arrays (Repeated Elements)
|
|
481
|
-
|
|
482
|
-
```typescript
|
|
483
|
-
"OrderItems": {
|
|
484
|
-
"OrderItem": [
|
|
485
|
-
{ "ItemId": "SKU001" },
|
|
486
|
-
{ "ItemId": "SKU002" }
|
|
487
|
-
]
|
|
488
|
-
}
|
|
489
|
-
// → <OrderItems>
|
|
490
|
-
// <OrderItem><ItemId>SKU001</ItemId></OrderItem>
|
|
491
|
-
// <OrderItem><ItemId>SKU002</ItemId></OrderItem>
|
|
492
|
-
// </OrderItems>
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
## Streaming for Large Files
|
|
496
|
-
|
|
497
|
-
Process large XML files efficiently:
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
const largeXMLContent = `
|
|
501
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
502
|
-
<products>
|
|
503
|
-
<product><sku>SKU001</sku><quantity>100</quantity></product>
|
|
504
|
-
<product><sku>SKU002</sku><quantity>200</quantity></product>
|
|
505
|
-
<!-- Thousands more products -->
|
|
506
|
-
</products>
|
|
507
|
-
`;
|
|
508
|
-
|
|
509
|
-
async function processLargeXML() {
|
|
510
|
-
const xmlParser = new XMLParserService();
|
|
511
|
-
|
|
512
|
-
// Stream individual product elements
|
|
513
|
-
for await (const product of xmlParser.parseStreaming(largeXMLContent, {
|
|
514
|
-
itemPath: '//product', // XPath-like selector for repeating elements
|
|
515
|
-
})) {
|
|
516
|
-
console.log('Processing product:', product);
|
|
517
|
-
|
|
518
|
-
// Process each product individually to minimize memory usage
|
|
519
|
-
await processProduct(product);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
async function processProduct(product: Record<string, unknown>) {
|
|
524
|
-
// Transform and send to Fluent Commerce
|
|
525
|
-
console.log(`Processing SKU: ${product.sku}`);
|
|
526
|
-
}
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
## Configuration Options
|
|
530
|
-
|
|
531
|
-
```typescript
|
|
532
|
-
interface XMLParseOptions {
|
|
533
|
-
// Convert element names to lowercase
|
|
534
|
-
lowercaseKeys?: boolean;
|
|
535
|
-
|
|
536
|
-
// Normalize whitespace in text content
|
|
537
|
-
normalizeWhitespace?: boolean;
|
|
538
|
-
|
|
539
|
-
// Automatically parse numeric values
|
|
540
|
-
parseNumbers?: boolean;
|
|
541
|
-
|
|
542
|
-
// Automatically parse boolean values
|
|
543
|
-
parseBooleans?: boolean;
|
|
544
|
-
|
|
545
|
-
// Automatically parse attribute values (numbers/booleans)
|
|
546
|
-
parseAttributeValues?: boolean;
|
|
547
|
-
|
|
548
|
-
// Root element to start parsing from
|
|
549
|
-
rootElement?: string;
|
|
550
|
-
|
|
551
|
-
// Elements to always treat as arrays
|
|
552
|
-
arrayElements?: string[];
|
|
553
|
-
|
|
554
|
-
// Include XML attributes in output
|
|
555
|
-
includeAttributes?: boolean;
|
|
556
|
-
|
|
557
|
-
// Prefix for attribute keys (default: '@')
|
|
558
|
-
attributePrefix?: string;
|
|
559
|
-
|
|
560
|
-
// Key name for text content (default: '#text')
|
|
561
|
-
textKey?: string;
|
|
562
|
-
|
|
563
|
-
// Maximum parsing depth (default: 100)
|
|
564
|
-
maxDepth?: number;
|
|
565
|
-
|
|
566
|
-
// Whether to remove namespace prefixes
|
|
567
|
-
// Default: false (preserves namespaces like 'ns:element')
|
|
568
|
-
// When true: 'ns:element' becomes 'element'
|
|
569
|
-
removeNamespacePrefix?: boolean;
|
|
570
|
-
}
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### Example with All Options
|
|
574
|
-
|
|
575
|
-
```typescript
|
|
576
|
-
const options: XMLParseOptions = {
|
|
577
|
-
lowercaseKeys: true,
|
|
578
|
-
normalizeWhitespace: true,
|
|
579
|
-
parseNumbers: true,
|
|
580
|
-
parseBooleans: true,
|
|
581
|
-
rootElement: 'catalog',
|
|
582
|
-
arrayElements: ['product', 'category'],
|
|
583
|
-
includeAttributes: true,
|
|
584
|
-
attributePrefix: '_',
|
|
585
|
-
textKey: 'value',
|
|
586
|
-
maxDepth: 50,
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
const parsed = await xmlParser.parse(xmlContent, options);
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
## Transformation to Fluent Commerce Format
|
|
593
|
-
|
|
594
|
-
### Inventory Update Example
|
|
595
|
-
|
|
596
|
-
```typescript
|
|
597
|
-
import { XMLParserService, UniversalMapper, createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
598
|
-
|
|
599
|
-
const xmlParser = new XMLParserService();
|
|
600
|
-
const client = await createClient({ config });
|
|
601
|
-
|
|
602
|
-
// XML from supplier
|
|
603
|
-
const supplierXML = `
|
|
604
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
605
|
-
<products>
|
|
606
|
-
<product>
|
|
607
|
-
<product_code>SUP-001</product_code>
|
|
608
|
-
<product_name>Wireless Mouse</product_name>
|
|
609
|
-
<stock_level>150</stock_level>
|
|
610
|
-
<warehouse_code>WH01</warehouse_code>
|
|
611
|
-
</product>
|
|
612
|
-
</products>
|
|
613
|
-
`;
|
|
614
|
-
|
|
615
|
-
// Field mapping configuration
|
|
616
|
-
const mappingConfig = {
|
|
617
|
-
fields: {
|
|
618
|
-
ref: {
|
|
619
|
-
source: 'product_code',
|
|
620
|
-
resolver: 'sdk.uppercase',
|
|
621
|
-
required: true,
|
|
622
|
-
},
|
|
623
|
-
name: {
|
|
624
|
-
source: 'product_name',
|
|
625
|
-
},
|
|
626
|
-
qty: {
|
|
627
|
-
source: 'stock_level',
|
|
628
|
-
resolver: 'sdk.parseInt',
|
|
629
|
-
},
|
|
630
|
-
locationRef: {
|
|
631
|
-
source: 'warehouse_code',
|
|
632
|
-
},
|
|
633
|
-
},
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
async function transformAndIngest() {
|
|
637
|
-
// Parse XML
|
|
638
|
-
const parsed = await xmlParser.parse(supplierXML);
|
|
639
|
-
const products = parsed.products?.product;
|
|
640
|
-
|
|
641
|
-
// Transform to Fluent format
|
|
642
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
643
|
-
const result = await mapper.map(products);
|
|
644
|
-
|
|
645
|
-
if (!result.success) {
|
|
646
|
-
console.error('Mapping errors:', result.errors);
|
|
647
|
-
throw new Error('Mapping failed');
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// Send to Fluent Commerce (Batch API for INVENTORY only)
|
|
651
|
-
const job = await client.createJob({
|
|
652
|
-
name: 'xml-inventory-update',
|
|
653
|
-
retailerId: process.env.FLUENT_RETAILER_ID!,
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
await client.sendBatch(job.id, {
|
|
657
|
-
entities: result.data,
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
### SFCC Order Integration with GraphQLMutationMapper
|
|
663
|
-
|
|
664
|
-
For complex transformations like SFCC orders to Fluent GraphQL mutations:
|
|
665
|
-
|
|
666
|
-
```typescript
|
|
667
|
-
import {
|
|
668
|
-
XMLParserService,
|
|
669
|
-
GraphQLMutationMapper,
|
|
670
|
-
createClient,
|
|
671
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
672
|
-
|
|
673
|
-
// SFCC order XML
|
|
674
|
-
const sfccOrderXML = `<Order>...</Order>`;
|
|
675
|
-
|
|
676
|
-
// XML → GraphQL mutation mapping
|
|
677
|
-
const mappingConfig = {
|
|
678
|
-
mutation: 'createOrder',
|
|
679
|
-
rootPath: 'Order',
|
|
680
|
-
fields: {
|
|
681
|
-
ref: { xmlPath: '@customerOrderId', required: true },
|
|
682
|
-
type: { value: 'HD' },
|
|
683
|
-
retailerId: { value: '1' },
|
|
684
|
-
customer: {
|
|
685
|
-
email: { xmlPath: 'Customer.EmailAddress' },
|
|
686
|
-
firstName: { xmlPath: 'Customer.Name.FirstName' },
|
|
687
|
-
lastName: { xmlPath: 'Customer.Name.LastName' },
|
|
688
|
-
},
|
|
689
|
-
items: {
|
|
690
|
-
arrayPath: 'OrderItems.OrderItem',
|
|
691
|
-
fields: {
|
|
692
|
-
ref: { xmlPath: 'ItemId' },
|
|
693
|
-
quantity: { xmlPath: 'Quantity', resolver: 'sdk.parseInt' },
|
|
694
|
-
price: { xmlPath: 'Price', resolver: 'sdk.parseFloat' },
|
|
695
|
-
},
|
|
696
|
-
},
|
|
697
|
-
},
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
async function processSFCCOrder() {
|
|
701
|
-
// Parse XML
|
|
702
|
-
const xmlParser = new XMLParserService();
|
|
703
|
-
const parsed = await xmlParser.parse(sfccOrderXML);
|
|
704
|
-
|
|
705
|
-
// Transform to GraphQL mutation
|
|
706
|
-
const mapper = new GraphQLMutationMapper(mappingConfig);
|
|
707
|
-
const mutation = await mapper.map(parsed);
|
|
708
|
-
|
|
709
|
-
// Send to Fluent
|
|
710
|
-
const client = await createClient({ config });
|
|
711
|
-
const result = await client.graphql({
|
|
712
|
-
query: mutation.query,
|
|
713
|
-
variables: mutation.variables,
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
console.log('Order created:', result.data);
|
|
717
|
-
}
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
## Error Handling
|
|
721
|
-
|
|
722
|
-
```typescript
|
|
723
|
-
import { FileParsingError } from '@fluentcommerce/fc-connect-sdk';
|
|
724
|
-
|
|
725
|
-
async function robustXMLParsing(xmlContent: string) {
|
|
726
|
-
const xmlParser = new XMLParserService();
|
|
727
|
-
|
|
728
|
-
try {
|
|
729
|
-
// Validate first
|
|
730
|
-
const validation = xmlParser.validate(xmlContent);
|
|
731
|
-
if (!validation.valid) {
|
|
732
|
-
console.error('XML validation failed:', validation.errors);
|
|
733
|
-
return null;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// Parse with error handling
|
|
737
|
-
const parsed = await xmlParser.parse(xmlContent);
|
|
738
|
-
return parsed;
|
|
739
|
-
} catch (error) {
|
|
740
|
-
if (error instanceof FileParsingError) {
|
|
741
|
-
console.error('Parsing error:', error.message);
|
|
742
|
-
console.error('File:', error.fileName);
|
|
743
|
-
console.error('Context:', error.context);
|
|
744
|
-
|
|
745
|
-
// Handle specific error types
|
|
746
|
-
if (error.message.includes('Maximum depth exceeded')) {
|
|
747
|
-
console.error('XML structure too deep');
|
|
748
|
-
} else if (error.message.includes('Mismatched tags')) {
|
|
749
|
-
console.error('Malformed XML structure');
|
|
750
|
-
}
|
|
751
|
-
} else {
|
|
752
|
-
console.error('Unexpected error:', error);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
return null;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
## Performance Considerations
|
|
761
|
-
|
|
762
|
-
### Memory Management
|
|
763
|
-
|
|
764
|
-
1. **Use Streaming for Large Files**: Process files over 10MB using streaming
|
|
765
|
-
2. **Batch Processing**: Process items in batches to minimize memory usage
|
|
766
|
-
3. **Selective Parsing**: Use selectors to parse only required elements
|
|
767
|
-
|
|
768
|
-
```typescript
|
|
769
|
-
// Memory-efficient processing
|
|
770
|
-
async function processLargeInventoryFile(xmlContent: string) {
|
|
771
|
-
const xmlParser = new XMLParserService();
|
|
772
|
-
|
|
773
|
-
const batchSize = 100;
|
|
774
|
-
let batch = [];
|
|
775
|
-
|
|
776
|
-
for await (const item of xmlParser.parseStreaming(xmlContent, {
|
|
777
|
-
itemPath: '//product',
|
|
778
|
-
})) {
|
|
779
|
-
batch.push(item);
|
|
780
|
-
|
|
781
|
-
if (batch.length >= batchSize) {
|
|
782
|
-
await processBatch(batch);
|
|
783
|
-
batch = [];
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
// Process remaining items
|
|
788
|
-
if (batch.length > 0) {
|
|
789
|
-
await processBatch(batch);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
```
|
|
793
|
-
|
|
794
|
-
### Optimization Tips
|
|
795
|
-
|
|
796
|
-
1. **Pre-validate XML**: Validate before parsing to avoid processing invalid data
|
|
797
|
-
2. **Use Specific Selectors**: Target specific elements instead of parsing entire document
|
|
798
|
-
3. **Disable Unused Features**: Turn off attribute parsing if not needed
|
|
799
|
-
4. **Limit Parsing Depth**: Set maxDepth to prevent excessive recursion
|
|
800
|
-
|
|
801
|
-
```typescript
|
|
802
|
-
// Optimized parsing
|
|
803
|
-
const optimizedOptions: XMLParseOptions = {
|
|
804
|
-
includeAttributes: false, // Skip if not needed
|
|
805
|
-
parseNumbers: false, // Skip automatic conversion
|
|
806
|
-
maxDepth: 10, // Limit recursion
|
|
807
|
-
normalizeWhitespace: false, // Skip if preserving formatting
|
|
808
|
-
};
|
|
809
|
-
```
|
|
810
|
-
|
|
811
|
-
## Key Takeaways
|
|
812
|
-
|
|
813
|
-
- 🎯 XML Parser handles hierarchical, tag-based data
|
|
814
|
-
- 🎯 Access parsed structure directly for simple parsing (no special tools needed)
|
|
815
|
-
- 🎯 Use `#text` key for elements with both attributes and text content
|
|
816
|
-
- 🎯 Generate XML with `XMLBuilder` using `@prefix` for attributes
|
|
817
|
-
- 🎯 Stream large files with `parseStreaming()` for memory efficiency
|
|
818
|
-
- 🎯 Combine with `UniversalMapper` for simple transformations
|
|
819
|
-
- 🎯 Use `GraphQLMutationMapper` (with XMLPathResolver) for complex SFCC order transformations
|
|
820
|
-
|
|
821
|
-
## Practice Exercise
|
|
822
|
-
|
|
823
|
-
**Challenge:** Parse this SFCC-style XML and transform it for Fluent:
|
|
824
|
-
|
|
825
|
-
```xml
|
|
826
|
-
<Order customerOrderId="ORD-12345">
|
|
827
|
-
<Customer>
|
|
828
|
-
<EmailAddress>customer@example.com</EmailAddress>
|
|
829
|
-
<Name>
|
|
830
|
-
<FirstName>John</FirstName>
|
|
831
|
-
<LastName>Doe</LastName>
|
|
832
|
-
</Name>
|
|
833
|
-
</Customer>
|
|
834
|
-
<OrderItems>
|
|
835
|
-
<OrderItem webLineId="1">
|
|
836
|
-
<ItemId>SKU001</ItemId>
|
|
837
|
-
<Quantity>2</Quantity>
|
|
838
|
-
</OrderItem>
|
|
839
|
-
</OrderItems>
|
|
840
|
-
</Order>
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
**Requirements:**
|
|
844
|
-
|
|
845
|
-
1. Parse the XML
|
|
846
|
-
2. Extract orderId, customer email/name, items (using direct property access or GraphQLMutationMapper)
|
|
847
|
-
3. Transform to Fluent format
|
|
848
|
-
|
|
849
|
-
**Solution:** See [XML Examples](../examples/xml-parser-examples.ts)
|
|
850
|
-
|
|
851
|
-
## Next Steps
|
|
852
|
-
|
|
853
|
-
Continue to [Module 5: Parquet Parser →](./02-core-guides-parsers-05-parquet-parser.md) to learn columnar data parsing.
|
|
854
|
-
|
|
855
|
-
---
|
|
856
|
-
|
|
857
|
-
**Module 4 Complete!** ✅
|
|
1
|
+
# Module 4: XML Parser
|
|
2
|
+
|
|
3
|
+
**Level:** Intermediate
|
|
4
|
+
**Estimated Time:** 30 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module covers the XML Parser (`XMLParserService`), essential for integrating with EDI feeds, B2B systems, and platforms like SFCC. You'll learn how to parse XML, handle attributes, use path resolution, generate XML from data, and integrate with SDK services.
|
|
9
|
+
|
|
10
|
+
### Minimal Mode (start here)
|
|
11
|
+
|
|
12
|
+
If you just need to parse XML, start with the simplest call:
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
16
|
+
|
|
17
|
+
const parsed = await new XMLParserService().parse(xmlString, {
|
|
18
|
+
includeAttributes: false, // simplest shape
|
|
19
|
+
parseBooleans: true, // optional normalization
|
|
20
|
+
parseNumbers: true, // optional normalization
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Or use fast-xml-parser directly if you prefer; the SDK mapping works with any compatible shape.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Advanced options (attributes, selectors, streaming, path resolver) are optional—use only if needed.
|
|
27
|
+
|
|
28
|
+
## Learning Objectives
|
|
29
|
+
|
|
30
|
+
By the end of this module, you will:
|
|
31
|
+
|
|
32
|
+
- ✅ Parse XML documents into JavaScript objects
|
|
33
|
+
- ✅ Access elements and attributes directly from parsed structure
|
|
34
|
+
- ✅ Generate XML from JavaScript objects using XMLBuilder
|
|
35
|
+
- ✅ Handle large XML files with streaming
|
|
36
|
+
- ✅ Transform XML data with UniversalMapper
|
|
37
|
+
- ✅ Integrate with GraphQLMutationMapper for SFCC orders
|
|
38
|
+
|
|
39
|
+
## What is XML?
|
|
40
|
+
|
|
41
|
+
**XML (eXtensible Markup Language)** is a hierarchical markup format that:
|
|
42
|
+
|
|
43
|
+
- Uses tags to define structure: `<element>value</element>`
|
|
44
|
+
- Supports attributes: `<product id="123">`
|
|
45
|
+
- Can represent complex nested data
|
|
46
|
+
- Is self-describing with optional schemas
|
|
47
|
+
|
|
48
|
+
**Example:**
|
|
49
|
+
|
|
50
|
+
```xml
|
|
51
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
52
|
+
<products>
|
|
53
|
+
<product id="P001" category="electronics">
|
|
54
|
+
<sku>SKU001</sku>
|
|
55
|
+
<name>Wireless Mouse</name>
|
|
56
|
+
<price currency="USD">29.99</price>
|
|
57
|
+
<stock warehouse="WH-01">150</stock>
|
|
58
|
+
</product>
|
|
59
|
+
</products>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Basic XML Parsing
|
|
63
|
+
|
|
64
|
+
### Simple Parsing
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { XMLParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
68
|
+
|
|
69
|
+
const xmlParser = new XMLParserService();
|
|
70
|
+
|
|
71
|
+
// Sample XML data
|
|
72
|
+
const xmlContent = `
|
|
73
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
74
|
+
<inventory>
|
|
75
|
+
<product>
|
|
76
|
+
<sku>SKU001</sku>
|
|
77
|
+
<name>Product 1</name>
|
|
78
|
+
<quantity>100</quantity>
|
|
79
|
+
<price>29.99</price>
|
|
80
|
+
</product>
|
|
81
|
+
<product>
|
|
82
|
+
<sku>SKU002</sku>
|
|
83
|
+
<name>Product 2</name>
|
|
84
|
+
<quantity>50</quantity>
|
|
85
|
+
<price>49.99</price>
|
|
86
|
+
</product>
|
|
87
|
+
</inventory>
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
// Parse XML
|
|
91
|
+
const parsed = await xmlParser.parse(xmlContent);
|
|
92
|
+
console.log('Parsed data:', parsed);
|
|
93
|
+
|
|
94
|
+
// Access products
|
|
95
|
+
const products = parsed.inventory?.product;
|
|
96
|
+
console.log('Products:', products);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Parsing with Attributes
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const xmlWithAttributes = `
|
|
103
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
104
|
+
<catalog>
|
|
105
|
+
<product id="P001" category="electronics">
|
|
106
|
+
<name>Laptop</name>
|
|
107
|
+
<price currency="USD">999.99</price>
|
|
108
|
+
<stock warehouse="W01">25</stock>
|
|
109
|
+
</product>
|
|
110
|
+
</catalog>
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
const parsed = await xmlParser.parse(xmlWithAttributes);
|
|
114
|
+
|
|
115
|
+
// Access attributes using @ prefix (NO underscore)
|
|
116
|
+
// For simple parsing, access parsed structure directly
|
|
117
|
+
const productId = parsed.catalog?.product?.['@id']; // 'P001'
|
|
118
|
+
const category = parsed.catalog?.product?.['@category']; // 'electronics'
|
|
119
|
+
const name = parsed.catalog?.product?.name; // 'Laptop'
|
|
120
|
+
const price = parsed.catalog?.product?.price; // 999.99
|
|
121
|
+
const currency = parsed.catalog?.product?.price?.['@currency']; // 'USD'
|
|
122
|
+
const stock = parsed.catalog?.product?.stock; // 25
|
|
123
|
+
const warehouse = parsed.catalog?.product?.stock?.['@warehouse']; // 'W01'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## XML Parser Output Reference
|
|
127
|
+
|
|
128
|
+
### Understanding Parser Output Structure
|
|
129
|
+
|
|
130
|
+
The XML parser transforms XML into JavaScript objects following these rules:
|
|
131
|
+
|
|
132
|
+
**Root Element Becomes Top-Level Key:**
|
|
133
|
+
```xml
|
|
134
|
+
<root>
|
|
135
|
+
<data>value</data>
|
|
136
|
+
</root>
|
|
137
|
+
```
|
|
138
|
+
**Output:**
|
|
139
|
+
```javascript
|
|
140
|
+
{
|
|
141
|
+
root: {
|
|
142
|
+
data: "value"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Attributes Prefixed with `@` (when `includeAttributes: true`):**
|
|
148
|
+
```xml
|
|
149
|
+
<product id="123" category="electronics">
|
|
150
|
+
<name>Laptop</name>
|
|
151
|
+
</product>
|
|
152
|
+
```
|
|
153
|
+
**Output:**
|
|
154
|
+
```javascript
|
|
155
|
+
{
|
|
156
|
+
product: {
|
|
157
|
+
"@id": "123",
|
|
158
|
+
"@category": "electronics",
|
|
159
|
+
name: "Laptop"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Single vs Multiple Elements:**
|
|
165
|
+
```xml
|
|
166
|
+
<!-- Single element = object -->
|
|
167
|
+
<products>
|
|
168
|
+
<product><sku>SKU-001</sku></product>
|
|
169
|
+
</products>
|
|
170
|
+
|
|
171
|
+
<!-- Multiple elements = array -->
|
|
172
|
+
<products>
|
|
173
|
+
<product><sku>SKU-001</sku></product>
|
|
174
|
+
<product><sku>SKU-002</sku></product>
|
|
175
|
+
</products>
|
|
176
|
+
```
|
|
177
|
+
**Output:**
|
|
178
|
+
```javascript
|
|
179
|
+
// Single
|
|
180
|
+
{ products: { product: { sku: "SKU-001" } } }
|
|
181
|
+
|
|
182
|
+
// Multiple
|
|
183
|
+
{ products: { product: [{ sku: "SKU-001" }, { sku: "SKU-002" }] } }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**⚠️ Important:** Always normalize single elements to arrays:
|
|
187
|
+
```typescript
|
|
188
|
+
const products = parsed.products?.product;
|
|
189
|
+
const records = Array.isArray(products) ? products : products ? [products] : [];
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Mixed Content (Attributes + Text):**
|
|
193
|
+
```xml
|
|
194
|
+
<price currency="USD">999.99</price>
|
|
195
|
+
```
|
|
196
|
+
**Output:**
|
|
197
|
+
```javascript
|
|
198
|
+
{
|
|
199
|
+
price: {
|
|
200
|
+
"@currency": "USD",
|
|
201
|
+
"#text": "999.99" // Text content when element has attributes
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Auto-Parsing (Default Behavior):**
|
|
207
|
+
- Numbers: `"29.99"` → `29.99`
|
|
208
|
+
- Booleans: `"true"` → `true`
|
|
209
|
+
- Disable with: `parseNumbers: false`, `parseBooleans: false`
|
|
210
|
+
|
|
211
|
+
## Accessing Parsed XML Data
|
|
212
|
+
|
|
213
|
+
**For simple parsing:** Access the parsed structure directly using standard JavaScript property access.
|
|
214
|
+
|
|
215
|
+
**For complex mapping:** Use `XMLPathResolver` from the mapping services layer (NOT exported from parsers). See `GraphQLMutationMapper` documentation for advanced path resolution with complex queries.
|
|
216
|
+
|
|
217
|
+
### Path Syntax Reference (for reference only - use direct access for simple parsing)
|
|
218
|
+
|
|
219
|
+
| Pattern | Description | XML Example | Path | Result |
|
|
220
|
+
| ---------------------- | ------------------ | ------------------------------ | --------------------- | -------------- |
|
|
221
|
+
| `element` | Element value | `<sku>ABC123</sku>` | `sku` | `'ABC123'` |
|
|
222
|
+
| `element@attr` | Attribute value | `<order id="123">` | `order@id` | `'123'` |
|
|
223
|
+
| `parent.child` | Nested element | `<order><ref>A1</ref></order>` | `order.ref` | `'A1'` |
|
|
224
|
+
| `element[0]` | Array index | `<item>` repeated | `items.item[0]` | First item |
|
|
225
|
+
| `element.*` | All array items | `<item>` repeated | `items.item.*` | Array of all |
|
|
226
|
+
| `element[id=123]@attr` | Filter + attribute | With `id` attribute | `item[id=123]@status` | Filtered value |
|
|
227
|
+
|
|
228
|
+
### Working with Mixed Content
|
|
229
|
+
|
|
230
|
+
When XML elements have both attributes and text content:
|
|
231
|
+
|
|
232
|
+
```xml
|
|
233
|
+
<price currency="USD">999.99</price>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Direct access to parsed structure (recommended for simple parsing)
|
|
238
|
+
const value = parsed.price; // 999.99
|
|
239
|
+
const currency = parsed.price?.['@_currency']; // 'USD'
|
|
240
|
+
|
|
241
|
+
// ℹ️ XMLPathResolver is part of the mapping services layer (not parsers)
|
|
242
|
+
// For advanced path resolution with complex queries, see GraphQLMutationMapper documentation
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Best Practice
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// ✅ For simple parsing: Access parsed structure directly
|
|
249
|
+
const orderDate = parsed.order?.['order-date']; // Simple and direct
|
|
250
|
+
|
|
251
|
+
// ℹ️ For complex mapping with XMLPathResolver:
|
|
252
|
+
// XMLPathResolver is part of the mapping services (NOT exported from parsers)
|
|
253
|
+
// Import: import { GraphQLMutationMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
254
|
+
// See GraphQLMutationMapper documentation for advanced path resolution
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Generating XML from JSON
|
|
258
|
+
|
|
259
|
+
The SDK provides `XMLBuilder` for creating XML from JavaScript objects.
|
|
260
|
+
|
|
261
|
+
### Understanding the `#text` Pattern
|
|
262
|
+
|
|
263
|
+
When generating XML, you use the `XMLBuilder` from `fast-xml-parser` with special keys:
|
|
264
|
+
|
|
265
|
+
| JSON Key | XML Output | Purpose |
|
|
266
|
+
| ----------- | ------------- | -------------------------- |
|
|
267
|
+
| `@prefix` | Attribute | `<Order id="123">` |
|
|
268
|
+
| `#text` | Text content | `<ItemId>SKU001</ItemId>` |
|
|
269
|
+
| `fieldName` | Child element | `<Customer>...</Customer>` |
|
|
270
|
+
|
|
271
|
+
**Why `#text`?** This is the standard convention used by `fast-xml-parser` to represent text content in JSON. When parsing XML, attributes use `@` prefix (e.g., `@id`), and when building XML, you use the same patterns.
|
|
272
|
+
|
|
273
|
+
### Decision Tree - When to use `#text`:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
Does the element have attributes?
|
|
277
|
+
├─ NO → Just use field name: "ItemId": "SKU001"
|
|
278
|
+
│ Result: <ItemId>SKU001</ItemId>
|
|
279
|
+
│
|
|
280
|
+
└─ YES → Does it also have text content?
|
|
281
|
+
├─ NO → Just use @prefix: "@id": "123"
|
|
282
|
+
│ Result: <Order id="123"/>
|
|
283
|
+
│
|
|
284
|
+
└─ YES → Use BOTH @prefix AND #text
|
|
285
|
+
"@id": "9101", "#text": "MULTI-COLOR"
|
|
286
|
+
Result: <Color id="9101">MULTI-COLOR</Color>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Simple XML Generation
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { XMLBuilder } from 'fast-xml-parser';
|
|
293
|
+
|
|
294
|
+
const builder = new XMLBuilder({
|
|
295
|
+
ignoreAttributes: false,
|
|
296
|
+
attributeNamePrefix: '@',
|
|
297
|
+
textNodeName: '#text',
|
|
298
|
+
format: true,
|
|
299
|
+
indentBy: ' ',
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Simple element with text
|
|
303
|
+
const data = {
|
|
304
|
+
Order: {
|
|
305
|
+
ItemId: 'SKU001',
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const xml = builder.build(data);
|
|
310
|
+
// Output:
|
|
311
|
+
// <Order>
|
|
312
|
+
// <ItemId>SKU001</ItemId>
|
|
313
|
+
// </Order>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### XML with Attributes
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// Element with attributes only
|
|
320
|
+
const data = {
|
|
321
|
+
Order: {
|
|
322
|
+
'@id': '12345',
|
|
323
|
+
'@status': 'confirmed',
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const xml = builder.build(data);
|
|
328
|
+
// Output:
|
|
329
|
+
// <Order id="12345" status="confirmed"/>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Mixed Content: Attributes AND Text
|
|
333
|
+
|
|
334
|
+
**This is where `#text` is essential:**
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
// Element with BOTH attribute AND text content
|
|
338
|
+
const data = {
|
|
339
|
+
Color: {
|
|
340
|
+
'@id': '9101',
|
|
341
|
+
'#text': 'MULTI-COLOR',
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const xml = builder.build(data);
|
|
346
|
+
// Output:
|
|
347
|
+
// <Product>
|
|
348
|
+
// <Color id="9101">MULTI-COLOR</Color>
|
|
349
|
+
// </Product>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Complex Example: Order with Multiple Patterns
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
const orderData = {
|
|
356
|
+
Order: {
|
|
357
|
+
// Attributes on Order element
|
|
358
|
+
'@customerOrderId': '12345',
|
|
359
|
+
'@levelOfService': 'REGULAR',
|
|
360
|
+
|
|
361
|
+
// Child elements
|
|
362
|
+
Customer: {
|
|
363
|
+
'@customerId': '232',
|
|
364
|
+
Name: {
|
|
365
|
+
FirstName: 'John',
|
|
366
|
+
LastName: 'Doe',
|
|
367
|
+
},
|
|
368
|
+
EmailAddress: 'john@example.com',
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
// Element with attribute AND text
|
|
372
|
+
OrderSource: {
|
|
373
|
+
'@type': 'source',
|
|
374
|
+
'#text': 'WEBSTORE',
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
// Array of items
|
|
378
|
+
OrderItems: {
|
|
379
|
+
OrderItem: [
|
|
380
|
+
{
|
|
381
|
+
'@id': 'item1',
|
|
382
|
+
'@webLineId': '1',
|
|
383
|
+
ItemId: 'SKU001',
|
|
384
|
+
Quantity: 2,
|
|
385
|
+
Description: {
|
|
386
|
+
Description: 'Wireless Mouse',
|
|
387
|
+
Color: {
|
|
388
|
+
'@id': '9101',
|
|
389
|
+
'#text': 'Black',
|
|
390
|
+
},
|
|
391
|
+
Size: {
|
|
392
|
+
'@id': 'M',
|
|
393
|
+
'#text': 'Medium',
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
],
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const xml = builder.build(orderData, 'OrderDetailResponse');
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Generated XML:**
|
|
406
|
+
|
|
407
|
+
```xml
|
|
408
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
409
|
+
<OrderDetailResponse>
|
|
410
|
+
<Order customerOrderId="12345" levelOfService="REGULAR">
|
|
411
|
+
<Customer customerId="232">
|
|
412
|
+
<Name>
|
|
413
|
+
<FirstName>John</FirstName>
|
|
414
|
+
<LastName>Doe</LastName>
|
|
415
|
+
</Name>
|
|
416
|
+
<EmailAddress>john@example.com</EmailAddress>
|
|
417
|
+
</Customer>
|
|
418
|
+
<OrderSource type="source">WEBSTORE</OrderSource>
|
|
419
|
+
<OrderItems>
|
|
420
|
+
<OrderItem id="item1" webLineId="1">
|
|
421
|
+
<ItemId>SKU001</ItemId>
|
|
422
|
+
<Quantity>2</Quantity>
|
|
423
|
+
<Description>
|
|
424
|
+
<Description>Wireless Mouse</Description>
|
|
425
|
+
<Color id="9101">Black</Color>
|
|
426
|
+
<Size id="M">Medium</Size>
|
|
427
|
+
</Description>
|
|
428
|
+
</OrderItem>
|
|
429
|
+
</OrderItems>
|
|
430
|
+
</Order>
|
|
431
|
+
</OrderDetailResponse>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Common Patterns Reference
|
|
435
|
+
|
|
436
|
+
#### Pattern 1: Simple Text Element
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
"ItemId": "SKU001"
|
|
440
|
+
// → <ItemId>SKU001</ItemId>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
#### Pattern 2: Attribute Only
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
"DestinationTarget": {
|
|
447
|
+
"@ref": "dest-123"
|
|
448
|
+
}
|
|
449
|
+
// → <DestinationTarget ref="dest-123"/>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
#### Pattern 3: Attribute + Text (`#text`)
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
"Size": {
|
|
456
|
+
"@id": "1214",
|
|
457
|
+
"#text": "M 12.0/ W 14.0"
|
|
458
|
+
}
|
|
459
|
+
// → <Size id="1214">M 12.0/ W 14.0</Size>
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### Pattern 4: Nested Children
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
"Customer": {
|
|
466
|
+
"@id": "232",
|
|
467
|
+
"Name": {
|
|
468
|
+
"FirstName": "John",
|
|
469
|
+
"LastName": "Doe"
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// → <Customer id="232">
|
|
473
|
+
// <Name>
|
|
474
|
+
// <FirstName>John</FirstName>
|
|
475
|
+
// <LastName>Doe</LastName>
|
|
476
|
+
// </Name>
|
|
477
|
+
// </Customer>
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### Pattern 5: Arrays (Repeated Elements)
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
"OrderItems": {
|
|
484
|
+
"OrderItem": [
|
|
485
|
+
{ "ItemId": "SKU001" },
|
|
486
|
+
{ "ItemId": "SKU002" }
|
|
487
|
+
]
|
|
488
|
+
}
|
|
489
|
+
// → <OrderItems>
|
|
490
|
+
// <OrderItem><ItemId>SKU001</ItemId></OrderItem>
|
|
491
|
+
// <OrderItem><ItemId>SKU002</ItemId></OrderItem>
|
|
492
|
+
// </OrderItems>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Streaming for Large Files
|
|
496
|
+
|
|
497
|
+
Process large XML files efficiently:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
const largeXMLContent = `
|
|
501
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
502
|
+
<products>
|
|
503
|
+
<product><sku>SKU001</sku><quantity>100</quantity></product>
|
|
504
|
+
<product><sku>SKU002</sku><quantity>200</quantity></product>
|
|
505
|
+
<!-- Thousands more products -->
|
|
506
|
+
</products>
|
|
507
|
+
`;
|
|
508
|
+
|
|
509
|
+
async function processLargeXML() {
|
|
510
|
+
const xmlParser = new XMLParserService();
|
|
511
|
+
|
|
512
|
+
// Stream individual product elements
|
|
513
|
+
for await (const product of xmlParser.parseStreaming(largeXMLContent, {
|
|
514
|
+
itemPath: '//product', // XPath-like selector for repeating elements
|
|
515
|
+
})) {
|
|
516
|
+
console.log('Processing product:', product);
|
|
517
|
+
|
|
518
|
+
// Process each product individually to minimize memory usage
|
|
519
|
+
await processProduct(product);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
async function processProduct(product: Record<string, unknown>) {
|
|
524
|
+
// Transform and send to Fluent Commerce
|
|
525
|
+
console.log(`Processing SKU: ${product.sku}`);
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Configuration Options
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
interface XMLParseOptions {
|
|
533
|
+
// Convert element names to lowercase
|
|
534
|
+
lowercaseKeys?: boolean;
|
|
535
|
+
|
|
536
|
+
// Normalize whitespace in text content
|
|
537
|
+
normalizeWhitespace?: boolean;
|
|
538
|
+
|
|
539
|
+
// Automatically parse numeric values
|
|
540
|
+
parseNumbers?: boolean;
|
|
541
|
+
|
|
542
|
+
// Automatically parse boolean values
|
|
543
|
+
parseBooleans?: boolean;
|
|
544
|
+
|
|
545
|
+
// Automatically parse attribute values (numbers/booleans)
|
|
546
|
+
parseAttributeValues?: boolean;
|
|
547
|
+
|
|
548
|
+
// Root element to start parsing from
|
|
549
|
+
rootElement?: string;
|
|
550
|
+
|
|
551
|
+
// Elements to always treat as arrays
|
|
552
|
+
arrayElements?: string[];
|
|
553
|
+
|
|
554
|
+
// Include XML attributes in output
|
|
555
|
+
includeAttributes?: boolean;
|
|
556
|
+
|
|
557
|
+
// Prefix for attribute keys (default: '@')
|
|
558
|
+
attributePrefix?: string;
|
|
559
|
+
|
|
560
|
+
// Key name for text content (default: '#text')
|
|
561
|
+
textKey?: string;
|
|
562
|
+
|
|
563
|
+
// Maximum parsing depth (default: 100)
|
|
564
|
+
maxDepth?: number;
|
|
565
|
+
|
|
566
|
+
// Whether to remove namespace prefixes
|
|
567
|
+
// Default: false (preserves namespaces like 'ns:element')
|
|
568
|
+
// When true: 'ns:element' becomes 'element'
|
|
569
|
+
removeNamespacePrefix?: boolean;
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### Example with All Options
|
|
574
|
+
|
|
575
|
+
```typescript
|
|
576
|
+
const options: XMLParseOptions = {
|
|
577
|
+
lowercaseKeys: true,
|
|
578
|
+
normalizeWhitespace: true,
|
|
579
|
+
parseNumbers: true,
|
|
580
|
+
parseBooleans: true,
|
|
581
|
+
rootElement: 'catalog',
|
|
582
|
+
arrayElements: ['product', 'category'],
|
|
583
|
+
includeAttributes: true,
|
|
584
|
+
attributePrefix: '_',
|
|
585
|
+
textKey: 'value',
|
|
586
|
+
maxDepth: 50,
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
const parsed = await xmlParser.parse(xmlContent, options);
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Transformation to Fluent Commerce Format
|
|
593
|
+
|
|
594
|
+
### Inventory Update Example
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
import { XMLParserService, UniversalMapper, createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
598
|
+
|
|
599
|
+
const xmlParser = new XMLParserService();
|
|
600
|
+
const client = await createClient({ config });
|
|
601
|
+
|
|
602
|
+
// XML from supplier
|
|
603
|
+
const supplierXML = `
|
|
604
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
605
|
+
<products>
|
|
606
|
+
<product>
|
|
607
|
+
<product_code>SUP-001</product_code>
|
|
608
|
+
<product_name>Wireless Mouse</product_name>
|
|
609
|
+
<stock_level>150</stock_level>
|
|
610
|
+
<warehouse_code>WH01</warehouse_code>
|
|
611
|
+
</product>
|
|
612
|
+
</products>
|
|
613
|
+
`;
|
|
614
|
+
|
|
615
|
+
// Field mapping configuration
|
|
616
|
+
const mappingConfig = {
|
|
617
|
+
fields: {
|
|
618
|
+
ref: {
|
|
619
|
+
source: 'product_code',
|
|
620
|
+
resolver: 'sdk.uppercase',
|
|
621
|
+
required: true,
|
|
622
|
+
},
|
|
623
|
+
name: {
|
|
624
|
+
source: 'product_name',
|
|
625
|
+
},
|
|
626
|
+
qty: {
|
|
627
|
+
source: 'stock_level',
|
|
628
|
+
resolver: 'sdk.parseInt',
|
|
629
|
+
},
|
|
630
|
+
locationRef: {
|
|
631
|
+
source: 'warehouse_code',
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
async function transformAndIngest() {
|
|
637
|
+
// Parse XML
|
|
638
|
+
const parsed = await xmlParser.parse(supplierXML);
|
|
639
|
+
const products = parsed.products?.product;
|
|
640
|
+
|
|
641
|
+
// Transform to Fluent format
|
|
642
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
643
|
+
const result = await mapper.map(products);
|
|
644
|
+
|
|
645
|
+
if (!result.success) {
|
|
646
|
+
console.error('Mapping errors:', result.errors);
|
|
647
|
+
throw new Error('Mapping failed');
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Send to Fluent Commerce (Batch API for INVENTORY only)
|
|
651
|
+
const job = await client.createJob({
|
|
652
|
+
name: 'xml-inventory-update',
|
|
653
|
+
retailerId: process.env.FLUENT_RETAILER_ID!,
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
await client.sendBatch(job.id, {
|
|
657
|
+
entities: result.data,
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### SFCC Order Integration with GraphQLMutationMapper
|
|
663
|
+
|
|
664
|
+
For complex transformations like SFCC orders to Fluent GraphQL mutations:
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
import {
|
|
668
|
+
XMLParserService,
|
|
669
|
+
GraphQLMutationMapper,
|
|
670
|
+
createClient,
|
|
671
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
672
|
+
|
|
673
|
+
// SFCC order XML
|
|
674
|
+
const sfccOrderXML = `<Order>...</Order>`;
|
|
675
|
+
|
|
676
|
+
// XML → GraphQL mutation mapping
|
|
677
|
+
const mappingConfig = {
|
|
678
|
+
mutation: 'createOrder',
|
|
679
|
+
rootPath: 'Order',
|
|
680
|
+
fields: {
|
|
681
|
+
ref: { xmlPath: '@customerOrderId', required: true },
|
|
682
|
+
type: { value: 'HD' },
|
|
683
|
+
retailerId: { value: '1' },
|
|
684
|
+
customer: {
|
|
685
|
+
email: { xmlPath: 'Customer.EmailAddress' },
|
|
686
|
+
firstName: { xmlPath: 'Customer.Name.FirstName' },
|
|
687
|
+
lastName: { xmlPath: 'Customer.Name.LastName' },
|
|
688
|
+
},
|
|
689
|
+
items: {
|
|
690
|
+
arrayPath: 'OrderItems.OrderItem',
|
|
691
|
+
fields: {
|
|
692
|
+
ref: { xmlPath: 'ItemId' },
|
|
693
|
+
quantity: { xmlPath: 'Quantity', resolver: 'sdk.parseInt' },
|
|
694
|
+
price: { xmlPath: 'Price', resolver: 'sdk.parseFloat' },
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
async function processSFCCOrder() {
|
|
701
|
+
// Parse XML
|
|
702
|
+
const xmlParser = new XMLParserService();
|
|
703
|
+
const parsed = await xmlParser.parse(sfccOrderXML);
|
|
704
|
+
|
|
705
|
+
// Transform to GraphQL mutation
|
|
706
|
+
const mapper = new GraphQLMutationMapper(mappingConfig);
|
|
707
|
+
const mutation = await mapper.map(parsed);
|
|
708
|
+
|
|
709
|
+
// Send to Fluent
|
|
710
|
+
const client = await createClient({ config });
|
|
711
|
+
const result = await client.graphql({
|
|
712
|
+
query: mutation.query,
|
|
713
|
+
variables: mutation.variables,
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
console.log('Order created:', result.data);
|
|
717
|
+
}
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
## Error Handling
|
|
721
|
+
|
|
722
|
+
```typescript
|
|
723
|
+
import { FileParsingError } from '@fluentcommerce/fc-connect-sdk';
|
|
724
|
+
|
|
725
|
+
async function robustXMLParsing(xmlContent: string) {
|
|
726
|
+
const xmlParser = new XMLParserService();
|
|
727
|
+
|
|
728
|
+
try {
|
|
729
|
+
// Validate first
|
|
730
|
+
const validation = xmlParser.validate(xmlContent);
|
|
731
|
+
if (!validation.valid) {
|
|
732
|
+
console.error('XML validation failed:', validation.errors);
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Parse with error handling
|
|
737
|
+
const parsed = await xmlParser.parse(xmlContent);
|
|
738
|
+
return parsed;
|
|
739
|
+
} catch (error) {
|
|
740
|
+
if (error instanceof FileParsingError) {
|
|
741
|
+
console.error('Parsing error:', error.message);
|
|
742
|
+
console.error('File:', error.fileName);
|
|
743
|
+
console.error('Context:', error.context);
|
|
744
|
+
|
|
745
|
+
// Handle specific error types
|
|
746
|
+
if (error.message.includes('Maximum depth exceeded')) {
|
|
747
|
+
console.error('XML structure too deep');
|
|
748
|
+
} else if (error.message.includes('Mismatched tags')) {
|
|
749
|
+
console.error('Malformed XML structure');
|
|
750
|
+
}
|
|
751
|
+
} else {
|
|
752
|
+
console.error('Unexpected error:', error);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
## Performance Considerations
|
|
761
|
+
|
|
762
|
+
### Memory Management
|
|
763
|
+
|
|
764
|
+
1. **Use Streaming for Large Files**: Process files over 10MB using streaming
|
|
765
|
+
2. **Batch Processing**: Process items in batches to minimize memory usage
|
|
766
|
+
3. **Selective Parsing**: Use selectors to parse only required elements
|
|
767
|
+
|
|
768
|
+
```typescript
|
|
769
|
+
// Memory-efficient processing
|
|
770
|
+
async function processLargeInventoryFile(xmlContent: string) {
|
|
771
|
+
const xmlParser = new XMLParserService();
|
|
772
|
+
|
|
773
|
+
const batchSize = 100;
|
|
774
|
+
let batch = [];
|
|
775
|
+
|
|
776
|
+
for await (const item of xmlParser.parseStreaming(xmlContent, {
|
|
777
|
+
itemPath: '//product',
|
|
778
|
+
})) {
|
|
779
|
+
batch.push(item);
|
|
780
|
+
|
|
781
|
+
if (batch.length >= batchSize) {
|
|
782
|
+
await processBatch(batch);
|
|
783
|
+
batch = [];
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Process remaining items
|
|
788
|
+
if (batch.length > 0) {
|
|
789
|
+
await processBatch(batch);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Optimization Tips
|
|
795
|
+
|
|
796
|
+
1. **Pre-validate XML**: Validate before parsing to avoid processing invalid data
|
|
797
|
+
2. **Use Specific Selectors**: Target specific elements instead of parsing entire document
|
|
798
|
+
3. **Disable Unused Features**: Turn off attribute parsing if not needed
|
|
799
|
+
4. **Limit Parsing Depth**: Set maxDepth to prevent excessive recursion
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
// Optimized parsing
|
|
803
|
+
const optimizedOptions: XMLParseOptions = {
|
|
804
|
+
includeAttributes: false, // Skip if not needed
|
|
805
|
+
parseNumbers: false, // Skip automatic conversion
|
|
806
|
+
maxDepth: 10, // Limit recursion
|
|
807
|
+
normalizeWhitespace: false, // Skip if preserving formatting
|
|
808
|
+
};
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
## Key Takeaways
|
|
812
|
+
|
|
813
|
+
- 🎯 XML Parser handles hierarchical, tag-based data
|
|
814
|
+
- 🎯 Access parsed structure directly for simple parsing (no special tools needed)
|
|
815
|
+
- 🎯 Use `#text` key for elements with both attributes and text content
|
|
816
|
+
- 🎯 Generate XML with `XMLBuilder` using `@prefix` for attributes
|
|
817
|
+
- 🎯 Stream large files with `parseStreaming()` for memory efficiency
|
|
818
|
+
- 🎯 Combine with `UniversalMapper` for simple transformations
|
|
819
|
+
- 🎯 Use `GraphQLMutationMapper` (with XMLPathResolver) for complex SFCC order transformations
|
|
820
|
+
|
|
821
|
+
## Practice Exercise
|
|
822
|
+
|
|
823
|
+
**Challenge:** Parse this SFCC-style XML and transform it for Fluent:
|
|
824
|
+
|
|
825
|
+
```xml
|
|
826
|
+
<Order customerOrderId="ORD-12345">
|
|
827
|
+
<Customer>
|
|
828
|
+
<EmailAddress>customer@example.com</EmailAddress>
|
|
829
|
+
<Name>
|
|
830
|
+
<FirstName>John</FirstName>
|
|
831
|
+
<LastName>Doe</LastName>
|
|
832
|
+
</Name>
|
|
833
|
+
</Customer>
|
|
834
|
+
<OrderItems>
|
|
835
|
+
<OrderItem webLineId="1">
|
|
836
|
+
<ItemId>SKU001</ItemId>
|
|
837
|
+
<Quantity>2</Quantity>
|
|
838
|
+
</OrderItem>
|
|
839
|
+
</OrderItems>
|
|
840
|
+
</Order>
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
**Requirements:**
|
|
844
|
+
|
|
845
|
+
1. Parse the XML
|
|
846
|
+
2. Extract orderId, customer email/name, items (using direct property access or GraphQLMutationMapper)
|
|
847
|
+
3. Transform to Fluent format
|
|
848
|
+
|
|
849
|
+
**Solution:** See [XML Examples](../examples/xml-parser-examples.ts)
|
|
850
|
+
|
|
851
|
+
## Next Steps
|
|
852
|
+
|
|
853
|
+
Continue to [Module 5: Parquet Parser →](./02-core-guides-parsers-05-parquet-parser.md) to learn columnar data parsing.
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
857
|
+
**Module 4 Complete!** ✅
|