@fluentcommerce/fc-connect-sdk 0.1.54 → 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 +12 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,682 +1,682 @@
|
|
|
1
|
-
# Mapper Comparison Guide: Real-World Scenario
|
|
2
|
-
|
|
3
|
-
> **📚 Quick Decision First?** See [Mapper Quick Decision Guide](../../00-START-HERE/mapper-quick-decision-guide.md) (2-minute read) for a simple decision table.
|
|
4
|
-
|
|
5
|
-
**SCENARIO:** You have 100 locations in a CSV file. You need to create new locations or update existing ones in Fluent Commerce.
|
|
6
|
-
|
|
7
|
-
**CSV Input:**
|
|
8
|
-
```csv
|
|
9
|
-
ref,name,status,type,address1,city,state,country,latitude,longitude
|
|
10
|
-
DC-01,Distribution Center NYC,ACTIVE,DC,123 Main St,New York,NY,US,40.7128,-74.0060
|
|
11
|
-
STORE-001,Manhattan Store,ACTIVE,STORE,456 Broadway,New York,NY,US,40.7580,-73.9855
|
|
12
|
-
STORE-002,Brooklyn Store,ACTIVE,STORE,789 Atlantic Ave,Brooklyn,NY,US,40.6782,-73.9442
|
|
13
|
-
... (97 more rows)
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
**Goal:** Create or update each location using Fluent Commerce API.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Overview: 4 Working Approaches
|
|
21
|
-
|
|
22
|
-
| Approach | Field Mapping | API | GraphQL Query | Use Case |
|
|
23
|
-
|----------|--------------|-----|---------------|----------|
|
|
24
|
-
| **1. GraphQLMutationMapper** | ✅ Auto | GraphQL Mutations | ✅ Auto-generated | Complex XML/JSON, want schema validation |
|
|
25
|
-
| **2. UniversalMapper + Manual GraphQL** | ✅ Auto | GraphQL Mutations | ❌ You write | CSV with transformations, control over queries |
|
|
26
|
-
| **3. UniversalMapper + Event API** | ✅ Auto | Event API | ❌ N/A | Trigger Rubix workflows, bulk operations |
|
|
27
|
-
| **4. Fully Manual** | ❌ Manual | GraphQL Mutations | ❌ You write | Simple operations, maximum control |
|
|
28
|
-
|
|
29
|
-
**Key Insight:** UniversalMapper is NOT just for Batch API - it works with GraphQL mutations AND Event API!
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Approach 1: GraphQLMutationMapper
|
|
34
|
-
|
|
35
|
-
### When to Use
|
|
36
|
-
✅ Complex XML/JSON structures (SFCC orders, EDI)
|
|
37
|
-
✅ Want auto-generated GraphQL mutation queries
|
|
38
|
-
✅ Need schema validation against GraphQL types
|
|
39
|
-
✅ Prefer declarative configuration
|
|
40
|
-
|
|
41
|
-
### Code
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
import {
|
|
45
|
-
GraphQLMutationMapper,
|
|
46
|
-
CSVParserService,
|
|
47
|
-
createClient,
|
|
48
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
49
|
-
|
|
50
|
-
// 1. Parse CSV
|
|
51
|
-
const parser = new CSVParserService();
|
|
52
|
-
const locations = await parser.parse(csvContent, { columns: true });
|
|
53
|
-
|
|
54
|
-
// 2. Configure mapping (CSV columns → GraphQL fields)
|
|
55
|
-
const createConfig = {
|
|
56
|
-
mutation: 'createLocation',
|
|
57
|
-
operationName: 'CreateLocation',
|
|
58
|
-
sourceFormat: 'json' as const,
|
|
59
|
-
arguments: {
|
|
60
|
-
input: {
|
|
61
|
-
_type: 'CreateLocationInput!',
|
|
62
|
-
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
63
|
-
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
64
|
-
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
65
|
-
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
66
|
-
supportPhoneNumber: { value: '+1-800-555-0100' },
|
|
67
|
-
retailer: {
|
|
68
|
-
id: { value: '1', resolver: 'sdk.parseInt' },
|
|
69
|
-
},
|
|
70
|
-
primaryAddress: {
|
|
71
|
-
ref: { source: 'ref' },
|
|
72
|
-
street: { source: 'address1' },
|
|
73
|
-
city: { source: 'city' },
|
|
74
|
-
state: { source: 'state' },
|
|
75
|
-
country: { source: 'country' },
|
|
76
|
-
latitude: { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
77
|
-
longitude: { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
78
|
-
},
|
|
79
|
-
openingSchedule: {
|
|
80
|
-
allHours: { value: true },
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
returnFields: ['id', 'ref', 'type', 'status'],
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// 3. Setup client and mapper
|
|
88
|
-
const client = await createClient({ /* config */ });
|
|
89
|
-
const createMapper = new GraphQLMutationMapper(createConfig, client);
|
|
90
|
-
|
|
91
|
-
// 4. Process each location
|
|
92
|
-
for (const location of locations) {
|
|
93
|
-
// Option A: Use map() - throws on error (use try/catch)
|
|
94
|
-
try {
|
|
95
|
-
const payload = await createMapper.map(location);
|
|
96
|
-
const result = await client.graphql(payload);
|
|
97
|
-
console.log(`✅ Created: ${location.ref}`);
|
|
98
|
-
} catch (error) {
|
|
99
|
-
console.error(`❌ Failed: ${location.ref}`, error);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Option B: Use mapSafe() - returns result object (recommended for production)
|
|
103
|
-
const result = await createMapper.mapSafe(location);
|
|
104
|
-
if (!result.success) {
|
|
105
|
-
console.error(`❌ Failed: ${location.ref}`, result.errors);
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
await client.graphql({ query: result.query, variables: result.variables });
|
|
109
|
-
console.log(`✅ Created: ${location.ref}`);
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### What It Does
|
|
114
|
-
1. **Auto-builds GraphQL mutation query** from mapping config
|
|
115
|
-
2. **Validates** against GraphQL schema (catches type errors before sending)
|
|
116
|
-
3. **Applies** SDK resolvers (`sdk.trim`, `sdk.parseFloat`, etc.)
|
|
117
|
-
4. **Handles** nested structures automatically
|
|
118
|
-
5. **Returns** `{ query, variables }` ready for execution
|
|
119
|
-
|
|
120
|
-
### Pros
|
|
121
|
-
✅ **Auto-generates mutation query** - Don't write GraphQL strings
|
|
122
|
-
✅ **Schema validation** - Catches errors before sending to API
|
|
123
|
-
✅ **Declarative config** - Easy to read and maintain
|
|
124
|
-
✅ **Handles nested structures** - Automatic handling of `primaryAddress`
|
|
125
|
-
✅ **Type safety** - GraphQL types validated
|
|
126
|
-
|
|
127
|
-
### Cons
|
|
128
|
-
❌ **Learning curve** - Need to understand mapping config syntax
|
|
129
|
-
❌ **Verbose config** - More setup for simple mappings
|
|
130
|
-
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
131
|
-
|
|
132
|
-
### Performance
|
|
133
|
-
- **100 locations** = 100 mutations = **100 API calls**
|
|
134
|
-
- **Time**: ~30-60 seconds
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Approach 2: UniversalMapper + Manual GraphQL
|
|
139
|
-
|
|
140
|
-
### When to Use
|
|
141
|
-
✅ Want field mapping/transformation (SDK resolvers)
|
|
142
|
-
✅ Prefer writing your own GraphQL query strings
|
|
143
|
-
✅ Need flexibility in GraphQL query structure
|
|
144
|
-
✅ CSV/JSON with transformations
|
|
145
|
-
|
|
146
|
-
### Code
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
import {
|
|
150
|
-
UniversalMapper,
|
|
151
|
-
CSVParserService,
|
|
152
|
-
createClient,
|
|
153
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
154
|
-
|
|
155
|
-
// 1. Parse CSV
|
|
156
|
-
const parser = new CSVParserService();
|
|
157
|
-
const locations = await parser.parse(csvContent, { columns: true });
|
|
158
|
-
|
|
159
|
-
// 2. Configure field mapping (UniversalMapper)
|
|
160
|
-
const locationMapping = {
|
|
161
|
-
fields: {
|
|
162
|
-
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
163
|
-
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
164
|
-
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
165
|
-
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
166
|
-
supportPhoneNumber: { value: '+1-800-555-0100' },
|
|
167
|
-
|
|
168
|
-
// Nested address fields - UniversalMapper handles this!
|
|
169
|
-
'primaryAddress.ref': { source: 'ref' },
|
|
170
|
-
'primaryAddress.street': { source: 'address1' },
|
|
171
|
-
'primaryAddress.city': { source: 'city' },
|
|
172
|
-
'primaryAddress.state': { source: 'state' },
|
|
173
|
-
'primaryAddress.country': { source: 'country' },
|
|
174
|
-
'primaryAddress.latitude': { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
175
|
-
'primaryAddress.longitude': { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// 3. Map all CSV records
|
|
180
|
-
const mapper = new UniversalMapper(locationMapping);
|
|
181
|
-
const mappedLocations = [];
|
|
182
|
-
|
|
183
|
-
for (const location of locations) {
|
|
184
|
-
const mapped = await mapper.map(location);
|
|
185
|
-
if (mapped.success) {
|
|
186
|
-
mappedLocations.push(mapped.data);
|
|
187
|
-
} else {
|
|
188
|
-
console.error(`Mapping failed: ${mapped.errors?.join(', ')}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// 4. Write GraphQL mutation manually
|
|
193
|
-
const createMutation = `
|
|
194
|
-
mutation CreateLocation($input: CreateLocationInput!) {
|
|
195
|
-
createLocation(input: $input) {
|
|
196
|
-
id
|
|
197
|
-
ref
|
|
198
|
-
name
|
|
199
|
-
type
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
`;
|
|
203
|
-
|
|
204
|
-
// 5. Setup client
|
|
205
|
-
const client = await createClient({ /* config */ });
|
|
206
|
-
|
|
207
|
-
// 6. Execute mutations using mapped data as variables
|
|
208
|
-
for (const location of mappedLocations) {
|
|
209
|
-
// Use mapped plain object as GraphQL variables
|
|
210
|
-
const result = await client.graphql({
|
|
211
|
-
query: createMutation,
|
|
212
|
-
variables: { input: location }, // ✅ Mapped data from UniversalMapper!
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
console.log(`✅ Created: ${location.ref}`);
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### What It Does
|
|
220
|
-
1. **UniversalMapper** handles field mapping and transformations
|
|
221
|
-
2. **Returns plain objects** with nested structures properly formatted
|
|
222
|
-
3. **YOU write** the GraphQL mutation strings
|
|
223
|
-
4. **Use mapped objects** as GraphQL `variables`
|
|
224
|
-
|
|
225
|
-
### Pros
|
|
226
|
-
✅ **Field mapping with SDK resolvers** - Get transformations (`sdk.parseInt`, `sdk.trim`, etc.)
|
|
227
|
-
✅ **Handles nested structures** - `primaryAddress.street` → proper nested object
|
|
228
|
-
✅ **Full control over GraphQL** - Write exact queries you need
|
|
229
|
-
✅ **Easier to debug** - See exactly what's happening
|
|
230
|
-
✅ **Less learning curve** - Just mapping config + standard GraphQL
|
|
231
|
-
|
|
232
|
-
### Cons
|
|
233
|
-
❌ **Manual GraphQL queries** - Must write mutation strings yourself
|
|
234
|
-
❌ **No schema validation** - Errors only at runtime
|
|
235
|
-
❌ **More boilerplate** - Mapping config + GraphQL query strings
|
|
236
|
-
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
237
|
-
|
|
238
|
-
### Performance
|
|
239
|
-
- **Same as GraphQLMutationMapper**: 100 locations = 100 API calls
|
|
240
|
-
- **Time**: ~30-60 seconds
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## Approach 3: UniversalMapper + Event API
|
|
245
|
-
|
|
246
|
-
### When to Use
|
|
247
|
-
✅ Want to trigger Rubix workflows
|
|
248
|
-
✅ Need asynchronous processing
|
|
249
|
-
✅ Bulk operations that trigger business logic
|
|
250
|
-
✅ Products, locations, or any entity with Rubix workflow
|
|
251
|
-
|
|
252
|
-
### Code
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
import {
|
|
256
|
-
UniversalMapper,
|
|
257
|
-
CSVParserService,
|
|
258
|
-
createClient,
|
|
259
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
260
|
-
|
|
261
|
-
// 1. Parse CSV
|
|
262
|
-
const parser = new CSVParserService();
|
|
263
|
-
const locations = await parser.parse(csvContent, { columns: true });
|
|
264
|
-
|
|
265
|
-
// 2. Configure field mapping (same UniversalMapper config)
|
|
266
|
-
const locationMapping = {
|
|
267
|
-
fields: {
|
|
268
|
-
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
269
|
-
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
270
|
-
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
271
|
-
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
272
|
-
|
|
273
|
-
// Nested address fields
|
|
274
|
-
'primaryAddress.ref': { source: 'ref' },
|
|
275
|
-
'primaryAddress.street': { source: 'address1' },
|
|
276
|
-
'primaryAddress.city': { source: 'city' },
|
|
277
|
-
'primaryAddress.state': { source: 'state' },
|
|
278
|
-
'primaryAddress.country': { source: 'country' },
|
|
279
|
-
'primaryAddress.latitude': { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
280
|
-
'primaryAddress.longitude': { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// 3. Map all CSV records
|
|
285
|
-
const mapper = new UniversalMapper(locationMapping);
|
|
286
|
-
const mappedLocations = [];
|
|
287
|
-
|
|
288
|
-
for (const location of locations) {
|
|
289
|
-
const mapped = await mapper.map(location);
|
|
290
|
-
if (mapped.success) {
|
|
291
|
-
mappedLocations.push(mapped.data);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// 4. Setup client
|
|
296
|
-
const client = await createClient({ /* config */ });
|
|
297
|
-
|
|
298
|
-
// 5. Send each record as an event (triggers Rubix workflow)
|
|
299
|
-
const eventName = 'UPSERT_LOCATION';
|
|
300
|
-
const entityRef = 'LOCATION_CATALOGUE:MASTER:1'; // Your catalogue reference
|
|
301
|
-
|
|
302
|
-
for (const location of mappedLocations) {
|
|
303
|
-
await client.sendEvent(
|
|
304
|
-
{
|
|
305
|
-
name: eventName,
|
|
306
|
-
entityRef: entityRef,
|
|
307
|
-
entityType: 'LOCATION_CATALOGUE',
|
|
308
|
-
entitySubtype: 'MASTER',
|
|
309
|
-
rootEntityRef: entityRef,
|
|
310
|
-
rootEntityType: 'LOCATION_CATALOGUE',
|
|
311
|
-
retailerId: '1',
|
|
312
|
-
attributes: location, // ✅ Mapped data from UniversalMapper!
|
|
313
|
-
},
|
|
314
|
-
'async' // or 'sync' for synchronous processing
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
console.log(`✅ Event sent: ${location.ref}`);
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### What It Does
|
|
322
|
-
1. **UniversalMapper** handles field mapping and transformations
|
|
323
|
-
2. **Returns plain objects** ready for Event API
|
|
324
|
-
3. **Send to Event API** which triggers Rubix workflows
|
|
325
|
-
4. **Workflows** handle the actual GraphQL mutations
|
|
326
|
-
|
|
327
|
-
### Pros
|
|
328
|
-
✅ **Field mapping with SDK resolvers** - Same as approach 2
|
|
329
|
-
✅ **Triggers Rubix workflows** - Business logic execution
|
|
330
|
-
✅ **Asynchronous processing** - Don't wait for completion
|
|
331
|
-
✅ **Error recovery** - Workflows can retry
|
|
332
|
-
✅ **Business logic** - Workflows can add custom validation, enrichment
|
|
333
|
-
|
|
334
|
-
### Cons
|
|
335
|
-
❌ **Requires Rubix workflows** - Need workflow setup
|
|
336
|
-
❌ **No immediate feedback** - Async processing
|
|
337
|
-
❌ **More complexity** - Workflow management
|
|
338
|
-
❌ **One-at-a-time** - 100 locations = 100 events
|
|
339
|
-
|
|
340
|
-
### Performance
|
|
341
|
-
- **100 locations** = 100 event API calls
|
|
342
|
-
- **Time**: ~30-60 seconds (event submission), plus async workflow processing
|
|
343
|
-
|
|
344
|
-
---
|
|
345
|
-
|
|
346
|
-
## Approach 4: Fully Manual (No Mapper)
|
|
347
|
-
|
|
348
|
-
### When to Use
|
|
349
|
-
✅ Simple, one-off operations
|
|
350
|
-
✅ Maximum control over everything
|
|
351
|
-
✅ Prototyping/testing
|
|
352
|
-
✅ Don't need field transformations
|
|
353
|
-
|
|
354
|
-
### Code
|
|
355
|
-
|
|
356
|
-
```typescript
|
|
357
|
-
import { CSVParserService, createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
358
|
-
|
|
359
|
-
// 1. Parse CSV manually
|
|
360
|
-
const parser = new CSVParserService();
|
|
361
|
-
const locations = await parser.parse(csvContent, { columns: true });
|
|
362
|
-
|
|
363
|
-
// 2. Write GraphQL mutation manually
|
|
364
|
-
const createMutation = `
|
|
365
|
-
mutation CreateLocation($input: CreateLocationInput!) {
|
|
366
|
-
createLocation(input: $input) {
|
|
367
|
-
id
|
|
368
|
-
ref
|
|
369
|
-
name
|
|
370
|
-
type
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
`;
|
|
374
|
-
|
|
375
|
-
// 3. Setup client
|
|
376
|
-
const client = await createClient({ /* config */ });
|
|
377
|
-
|
|
378
|
-
// 4. Process each location manually (build variables yourself)
|
|
379
|
-
for (const location of locations) {
|
|
380
|
-
// Manually build variables object
|
|
381
|
-
const variables = {
|
|
382
|
-
input: {
|
|
383
|
-
ref: location.ref?.trim(),
|
|
384
|
-
name: location.name?.trim(),
|
|
385
|
-
type: location.type?.toUpperCase(),
|
|
386
|
-
status: location.status || 'ACTIVE',
|
|
387
|
-
supportPhoneNumber: '+1-800-555-0100',
|
|
388
|
-
primaryAddress: {
|
|
389
|
-
ref: location.ref,
|
|
390
|
-
street: location.address1,
|
|
391
|
-
city: location.city,
|
|
392
|
-
state: location.state,
|
|
393
|
-
country: location.country,
|
|
394
|
-
latitude: parseFloat(location.latitude),
|
|
395
|
-
longitude: parseFloat(location.longitude),
|
|
396
|
-
},
|
|
397
|
-
},
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
const result = await client.graphql({ query: createMutation, variables });
|
|
401
|
-
console.log(`✅ Created: ${location.ref}`);
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### What It Does
|
|
406
|
-
1. **You parse** CSV data
|
|
407
|
-
2. **You write** GraphQL mutation strings
|
|
408
|
-
3. **You build** variables object manually
|
|
409
|
-
4. **You handle** transformations (`trim()`, `parseFloat()`, `toUpperCase()`)
|
|
410
|
-
|
|
411
|
-
### Pros
|
|
412
|
-
✅ **Full control** - No abstraction overhead
|
|
413
|
-
✅ **Simple to understand** - No mapper configuration
|
|
414
|
-
✅ **Easy to debug** - See exactly what's happening
|
|
415
|
-
✅ **No learning curve** - Just TypeScript + GraphQL
|
|
416
|
-
|
|
417
|
-
### Cons
|
|
418
|
-
❌ **Boilerplate** - Repetitive code for transformations
|
|
419
|
-
❌ **No validation** - Errors only at runtime
|
|
420
|
-
❌ **Manual transforms** - Write `trim()`, `parseFloat()`, etc. yourself
|
|
421
|
-
❌ **Error handling** - You implement all error logic
|
|
422
|
-
❌ **Maintenance** - Schema changes need code updates
|
|
423
|
-
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
424
|
-
|
|
425
|
-
### Performance
|
|
426
|
-
- **Same as other approaches**: 100 locations = 100 API calls
|
|
427
|
-
- **Time**: ~30-60 seconds
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
## Decision Matrix
|
|
432
|
-
|
|
433
|
-
| Factor | GraphQLMutationMapper | UniversalMapper + GraphQL | UniversalMapper + Event API | Fully Manual |
|
|
434
|
-
|--------|----------------------|--------------------------|----------------------------|--------------|
|
|
435
|
-
| **Field Mapping** | ✅ Built-in | ✅ Built-in | ✅ Built-in | ❌ Manual |
|
|
436
|
-
| **SDK Resolvers** | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
|
|
437
|
-
| **GraphQL Generation** | ✅ Auto | ❌ You write | ❌ N/A | ❌ You write |
|
|
438
|
-
| **Schema Validation** | ✅ Yes | ❌ No | ❌ No | ❌ No |
|
|
439
|
-
| **Nested Structures** | ✅ Auto | ✅ Auto | ✅ Auto | ❌ Manual |
|
|
440
|
-
| **Triggers Workflows** | ❌ No | ❌ No | ✅ Yes | ❌ No |
|
|
441
|
-
| **Immediate Feedback** | ✅ Yes | ✅ Yes | ❌ Async | ✅ Yes |
|
|
442
|
-
| **Learning Curve** | 🟡 Medium | 🟢 Easy | 🟢 Easy | 🟢 Easy |
|
|
443
|
-
| **Best For** | Complex XML/JSON | CSV + control | Workflow triggers | Simple tasks |
|
|
444
|
-
|
|
445
|
-
---
|
|
446
|
-
|
|
447
|
-
## API Comparison: GraphQL Mutations vs Event API vs Batch API
|
|
448
|
-
|
|
449
|
-
### GraphQL Mutations (Approaches 1, 2, 4)
|
|
450
|
-
```typescript
|
|
451
|
-
await client.graphql({
|
|
452
|
-
query: mutation,
|
|
453
|
-
variables: { input: data },
|
|
454
|
-
});
|
|
455
|
-
```
|
|
456
|
-
- **Immediate feedback**: Response includes created/updated entity
|
|
457
|
-
- **All entities**: Locations, products, orders, customers
|
|
458
|
-
- **One-at-a-time**: N records = N API calls
|
|
459
|
-
- **Use when**: Need immediate response, <100 records
|
|
460
|
-
|
|
461
|
-
### Event API (Approach 3)
|
|
462
|
-
```typescript
|
|
463
|
-
await client.sendEvent({
|
|
464
|
-
name: 'UPSERT_LOCATION',
|
|
465
|
-
attributes: data,
|
|
466
|
-
}, 'async');
|
|
467
|
-
```
|
|
468
|
-
- **Triggers workflows**: Rubix workflows process events
|
|
469
|
-
- **Asynchronous**: Don't wait for completion
|
|
470
|
-
- **All entities**: Locations, products, orders (NOT inventory)
|
|
471
|
-
- **One-at-a-time**: N records = N events
|
|
472
|
-
- **Use when**: Need workflow execution, complex business logic
|
|
473
|
-
|
|
474
|
-
### Batch API (Inventory ONLY)
|
|
475
|
-
```typescript
|
|
476
|
-
await client.sendBatch(jobId, {
|
|
477
|
-
entityType: 'INVENTORY',
|
|
478
|
-
action: 'UPSERT',
|
|
479
|
-
entities: data,
|
|
480
|
-
});
|
|
481
|
-
```
|
|
482
|
-
- **Bulk optimized**: 1 API call for thousands of records
|
|
483
|
-
- **Change detection**: BPP filters unchanged records
|
|
484
|
-
- **INVENTORY ONLY**: No other entities supported
|
|
485
|
-
- **Use when**: Bulk inventory updates (>100 records)
|
|
486
|
-
|
|
487
|
-
---
|
|
488
|
-
|
|
489
|
-
## Key Insights
|
|
490
|
-
|
|
491
|
-
### 1. UniversalMapper Works With ALL APIs!
|
|
492
|
-
|
|
493
|
-
**Pattern:**
|
|
494
|
-
```typescript
|
|
495
|
-
// Step 1: Map data using UniversalMapper
|
|
496
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
497
|
-
const mapped = await mapper.map(csvRow);
|
|
498
|
-
|
|
499
|
-
// Step 2: Use mapped data with ANY API
|
|
500
|
-
// Option A: GraphQL Mutations
|
|
501
|
-
await client.graphql({
|
|
502
|
-
query: mutation,
|
|
503
|
-
variables: { input: mapped.data },
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
// Option B: Event API
|
|
507
|
-
await client.sendEvent({
|
|
508
|
-
name: 'UPSERT_ENTITY',
|
|
509
|
-
attributes: mapped.data,
|
|
510
|
-
}, 'async');
|
|
511
|
-
|
|
512
|
-
// Option C: Batch API (inventory only)
|
|
513
|
-
await client.sendBatch(jobId, {
|
|
514
|
-
entityType: 'INVENTORY',
|
|
515
|
-
entities: [mapped.data],
|
|
516
|
-
});
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### 2. Four Approaches Comparison
|
|
520
|
-
|
|
521
|
-
| Approach | Mapping | API | GraphQL Query | Control |
|
|
522
|
-
|----------|---------|-----|---------------|---------|
|
|
523
|
-
| **GraphQLMutationMapper** | Auto | GraphQL | Auto | Low |
|
|
524
|
-
| **UniversalMapper + GraphQL** | Auto | GraphQL | Manual | Medium |
|
|
525
|
-
| **UniversalMapper + Event API** | Auto | Event API | N/A | Medium |
|
|
526
|
-
| **Fully Manual** | Manual | GraphQL | Manual | Maximum |
|
|
527
|
-
|
|
528
|
-
### 3. When to Use Each Approach
|
|
529
|
-
|
|
530
|
-
**GraphQLMutationMapper:**
|
|
531
|
-
- Complex XML/JSON (SFCC orders, EDI)
|
|
532
|
-
- Need schema validation
|
|
533
|
-
- Want auto-generated queries
|
|
534
|
-
|
|
535
|
-
**UniversalMapper + Manual GraphQL:**
|
|
536
|
-
- CSV with transformations
|
|
537
|
-
- Want control over GraphQL queries
|
|
538
|
-
- Comfortable writing queries
|
|
539
|
-
|
|
540
|
-
**UniversalMapper + Event API:**
|
|
541
|
-
- Need to trigger Rubix workflows
|
|
542
|
-
- Complex business logic
|
|
543
|
-
- Asynchronous processing
|
|
544
|
-
|
|
545
|
-
**Fully Manual:**
|
|
546
|
-
- Simple CSV → GraphQL
|
|
547
|
-
- Prototyping
|
|
548
|
-
- Maximum flexibility
|
|
549
|
-
|
|
550
|
-
### 4. Batch API is Special
|
|
551
|
-
|
|
552
|
-
**Batch API ONLY supports inventory:**
|
|
553
|
-
|
|
554
|
-
```typescript
|
|
555
|
-
// ✅ CORRECT - Inventory via Batch API
|
|
556
|
-
await client.sendBatch(jobId, {
|
|
557
|
-
entityType: 'INVENTORY', // Only option!
|
|
558
|
-
action: 'UPSERT',
|
|
559
|
-
entities: inventoryData,
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
// ❌ WRONG - No Batch API for these
|
|
563
|
-
entityType: 'LOCATION' // Use GraphQL or Event API
|
|
564
|
-
entityType: 'PRODUCT' // Use GraphQL or Event API
|
|
565
|
-
entityType: 'ORDER' // Use GraphQL or Event API
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
**For inventory with UniversalMapper:**
|
|
569
|
-
```typescript
|
|
570
|
-
// Map inventory records
|
|
571
|
-
const mapper = new UniversalMapper({
|
|
572
|
-
fields: {
|
|
573
|
-
skuRef: { source: 'sku', required: true },
|
|
574
|
-
locationRef: { source: 'location', required: true },
|
|
575
|
-
qty: { source: 'quantity', resolver: 'sdk.parseInt' },
|
|
576
|
-
},
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
const mapped = await Promise.all(csvRows.map(row => mapper.map(row)));
|
|
580
|
-
|
|
581
|
-
// Send to Batch API (1 API call for thousands of records!)
|
|
582
|
-
const job = await client.createJob({ name: 'inventory', retailerId: '1' });
|
|
583
|
-
await client.sendBatch(job.id, {
|
|
584
|
-
entityType: 'INVENTORY',
|
|
585
|
-
action: 'UPSERT',
|
|
586
|
-
entities: mapped.filter(r => r.success).map(r => r.data),
|
|
587
|
-
});
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
---
|
|
591
|
-
|
|
592
|
-
## Performance Comparison
|
|
593
|
-
|
|
594
|
-
| Scenario | Approach | API Calls | Time | Best For |
|
|
595
|
-
|----------|----------|-----------|------|----------|
|
|
596
|
-
| **100 locations** | GraphQLMutationMapper | 100 | ~30-60 sec | Schema validation |
|
|
597
|
-
| **100 locations** | UniversalMapper + GraphQL | 100 | ~30-60 sec | Query control |
|
|
598
|
-
| **100 locations** | UniversalMapper + Event API | 100 | ~30-60 sec | Workflow triggers |
|
|
599
|
-
| **100 locations** | Fully Manual | 100 | ~30-60 sec | Simplicity |
|
|
600
|
-
| **1,000 inventory** | Any approach + GraphQL | 1,000 | ~5-10 min ❌ | Don't use |
|
|
601
|
-
| **1,000 inventory** | UniversalMapper + Batch API | 2 | ~30 sec ✅ | BEST choice |
|
|
602
|
-
|
|
603
|
-
**Key Takeaway**: All four approaches have same performance for locations (no Batch API). Only inventory benefits from Batch API.
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## Summary
|
|
608
|
-
|
|
609
|
-
**All 4 approaches work for locations:**
|
|
610
|
-
|
|
611
|
-
1. **GraphQLMutationMapper** = Auto mapping + auto GraphQL query
|
|
612
|
-
2. **UniversalMapper + Manual GraphQL** = Auto mapping + manual GraphQL query
|
|
613
|
-
3. **UniversalMapper + Event API** = Auto mapping + workflow triggers
|
|
614
|
-
4. **Fully Manual** = Everything manual
|
|
615
|
-
|
|
616
|
-
**Choose based on:**
|
|
617
|
-
|
|
618
|
-
1. **Need schema validation?** → GraphQLMutationMapper
|
|
619
|
-
2. **Want query control?** → UniversalMapper + Manual GraphQL
|
|
620
|
-
3. **Need workflows?** → UniversalMapper + Event API
|
|
621
|
-
4. **Simple operation?** → Fully Manual
|
|
622
|
-
|
|
623
|
-
**For inventory specifically:**
|
|
624
|
-
- Use UniversalMapper + Batch API (20x faster for bulk!)
|
|
625
|
-
|
|
626
|
-
---
|
|
627
|
-
|
|
628
|
-
---
|
|
629
|
-
|
|
630
|
-
## Testing All Approaches
|
|
631
|
-
|
|
632
|
-
A comprehensive test script is available to validate all 4 approaches with the same input:
|
|
633
|
-
|
|
634
|
-
**Location**: `fc-connect-sdk/tests/manual/mapper-comparison-test.ts`
|
|
635
|
-
|
|
636
|
-
### Run in Dry Run Mode (No API Calls)
|
|
637
|
-
|
|
638
|
-
```bash
|
|
639
|
-
npx tsx tests/manual/mapper-comparison-test.ts
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
This will:
|
|
643
|
-
- Parse the same CSV data in all 4 approaches
|
|
644
|
-
- Show the mapped data structure for each approach
|
|
645
|
-
- Demonstrate that all approaches produce consistent output
|
|
646
|
-
- No actual API calls are made
|
|
647
|
-
|
|
648
|
-
### Run with Live Credentials
|
|
649
|
-
|
|
650
|
-
```bash
|
|
651
|
-
FLUENT_BASE_URL=https://your-instance.api.fluentretail.com/graphql \
|
|
652
|
-
FLUENT_CLIENT_ID=your-client-id \
|
|
653
|
-
FLUENT_CLIENT_SECRET=your-secret \
|
|
654
|
-
FLUENT_USERNAME=your-username \
|
|
655
|
-
FLUENT_PASSWORD=your-password \
|
|
656
|
-
FLUENT_RETAILER_ID=1 \
|
|
657
|
-
npx tsx tests/manual/mapper-comparison-test.ts
|
|
658
|
-
```
|
|
659
|
-
|
|
660
|
-
This will actually execute all 4 approaches against your Fluent Commerce instance.
|
|
661
|
-
|
|
662
|
-
**⚠️ Warning**: This will create 3 locations (DC-01, STORE-001, STORE-002) in your Fluent instance. Use a sandbox/test environment.
|
|
663
|
-
|
|
664
|
-
### Output Example
|
|
665
|
-
|
|
666
|
-
Each approach shows:
|
|
667
|
-
- Parsed CSV data
|
|
668
|
-
- Mapped/transformed data structure
|
|
669
|
-
- GraphQL query (Approach 1 only)
|
|
670
|
-
- Execution result (if using live credentials)
|
|
671
|
-
|
|
672
|
-
---
|
|
673
|
-
|
|
674
|
-
## Related Docs
|
|
675
|
-
|
|
676
|
-
- GraphQLMutationMapper Guide: `docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/`
|
|
677
|
-
- UniversalMapper Guide: `docs/02-CORE-GUIDES/mapping/modules/`
|
|
678
|
-
- Event API Guide: `docs/02-CORE-GUIDES/ingestion/modules/08-event-api.md`
|
|
679
|
-
- Batch API Guide: `docs/02-CORE-GUIDES/ingestion/modules/06-batch-api.md`
|
|
680
|
-
- Real Templates:
|
|
681
|
-
- UniversalMapper + GraphQL: `docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md`
|
|
682
|
-
- UniversalMapper + Event API: `docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md`
|
|
1
|
+
# Mapper Comparison Guide: Real-World Scenario
|
|
2
|
+
|
|
3
|
+
> **📚 Quick Decision First?** See [Mapper Quick Decision Guide](../../00-START-HERE/mapper-quick-decision-guide.md) (2-minute read) for a simple decision table.
|
|
4
|
+
|
|
5
|
+
**SCENARIO:** You have 100 locations in a CSV file. You need to create new locations or update existing ones in Fluent Commerce.
|
|
6
|
+
|
|
7
|
+
**CSV Input:**
|
|
8
|
+
```csv
|
|
9
|
+
ref,name,status,type,address1,city,state,country,latitude,longitude
|
|
10
|
+
DC-01,Distribution Center NYC,ACTIVE,DC,123 Main St,New York,NY,US,40.7128,-74.0060
|
|
11
|
+
STORE-001,Manhattan Store,ACTIVE,STORE,456 Broadway,New York,NY,US,40.7580,-73.9855
|
|
12
|
+
STORE-002,Brooklyn Store,ACTIVE,STORE,789 Atlantic Ave,Brooklyn,NY,US,40.6782,-73.9442
|
|
13
|
+
... (97 more rows)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Goal:** Create or update each location using Fluent Commerce API.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Overview: 4 Working Approaches
|
|
21
|
+
|
|
22
|
+
| Approach | Field Mapping | API | GraphQL Query | Use Case |
|
|
23
|
+
|----------|--------------|-----|---------------|----------|
|
|
24
|
+
| **1. GraphQLMutationMapper** | ✅ Auto | GraphQL Mutations | ✅ Auto-generated | Complex XML/JSON, want schema validation |
|
|
25
|
+
| **2. UniversalMapper + Manual GraphQL** | ✅ Auto | GraphQL Mutations | ❌ You write | CSV with transformations, control over queries |
|
|
26
|
+
| **3. UniversalMapper + Event API** | ✅ Auto | Event API | ❌ N/A | Trigger Rubix workflows, bulk operations |
|
|
27
|
+
| **4. Fully Manual** | ❌ Manual | GraphQL Mutations | ❌ You write | Simple operations, maximum control |
|
|
28
|
+
|
|
29
|
+
**Key Insight:** UniversalMapper is NOT just for Batch API - it works with GraphQL mutations AND Event API!
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Approach 1: GraphQLMutationMapper
|
|
34
|
+
|
|
35
|
+
### When to Use
|
|
36
|
+
✅ Complex XML/JSON structures (SFCC orders, EDI)
|
|
37
|
+
✅ Want auto-generated GraphQL mutation queries
|
|
38
|
+
✅ Need schema validation against GraphQL types
|
|
39
|
+
✅ Prefer declarative configuration
|
|
40
|
+
|
|
41
|
+
### Code
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import {
|
|
45
|
+
GraphQLMutationMapper,
|
|
46
|
+
CSVParserService,
|
|
47
|
+
createClient,
|
|
48
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
49
|
+
|
|
50
|
+
// 1. Parse CSV
|
|
51
|
+
const parser = new CSVParserService();
|
|
52
|
+
const locations = await parser.parse(csvContent, { columns: true });
|
|
53
|
+
|
|
54
|
+
// 2. Configure mapping (CSV columns → GraphQL fields)
|
|
55
|
+
const createConfig = {
|
|
56
|
+
mutation: 'createLocation',
|
|
57
|
+
operationName: 'CreateLocation',
|
|
58
|
+
sourceFormat: 'json' as const,
|
|
59
|
+
arguments: {
|
|
60
|
+
input: {
|
|
61
|
+
_type: 'CreateLocationInput!',
|
|
62
|
+
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
63
|
+
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
64
|
+
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
65
|
+
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
66
|
+
supportPhoneNumber: { value: '+1-800-555-0100' },
|
|
67
|
+
retailer: {
|
|
68
|
+
id: { value: '1', resolver: 'sdk.parseInt' },
|
|
69
|
+
},
|
|
70
|
+
primaryAddress: {
|
|
71
|
+
ref: { source: 'ref' },
|
|
72
|
+
street: { source: 'address1' },
|
|
73
|
+
city: { source: 'city' },
|
|
74
|
+
state: { source: 'state' },
|
|
75
|
+
country: { source: 'country' },
|
|
76
|
+
latitude: { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
77
|
+
longitude: { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
78
|
+
},
|
|
79
|
+
openingSchedule: {
|
|
80
|
+
allHours: { value: true },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
returnFields: ['id', 'ref', 'type', 'status'],
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// 3. Setup client and mapper
|
|
88
|
+
const client = await createClient({ /* config */ });
|
|
89
|
+
const createMapper = new GraphQLMutationMapper(createConfig, client);
|
|
90
|
+
|
|
91
|
+
// 4. Process each location
|
|
92
|
+
for (const location of locations) {
|
|
93
|
+
// Option A: Use map() - throws on error (use try/catch)
|
|
94
|
+
try {
|
|
95
|
+
const payload = await createMapper.map(location);
|
|
96
|
+
const result = await client.graphql(payload);
|
|
97
|
+
console.log(`✅ Created: ${location.ref}`);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error(`❌ Failed: ${location.ref}`, error);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Option B: Use mapSafe() - returns result object (recommended for production)
|
|
103
|
+
const result = await createMapper.mapSafe(location);
|
|
104
|
+
if (!result.success) {
|
|
105
|
+
console.error(`❌ Failed: ${location.ref}`, result.errors);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
await client.graphql({ query: result.query, variables: result.variables });
|
|
109
|
+
console.log(`✅ Created: ${location.ref}`);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### What It Does
|
|
114
|
+
1. **Auto-builds GraphQL mutation query** from mapping config
|
|
115
|
+
2. **Validates** against GraphQL schema (catches type errors before sending)
|
|
116
|
+
3. **Applies** SDK resolvers (`sdk.trim`, `sdk.parseFloat`, etc.)
|
|
117
|
+
4. **Handles** nested structures automatically
|
|
118
|
+
5. **Returns** `{ query, variables }` ready for execution
|
|
119
|
+
|
|
120
|
+
### Pros
|
|
121
|
+
✅ **Auto-generates mutation query** - Don't write GraphQL strings
|
|
122
|
+
✅ **Schema validation** - Catches errors before sending to API
|
|
123
|
+
✅ **Declarative config** - Easy to read and maintain
|
|
124
|
+
✅ **Handles nested structures** - Automatic handling of `primaryAddress`
|
|
125
|
+
✅ **Type safety** - GraphQL types validated
|
|
126
|
+
|
|
127
|
+
### Cons
|
|
128
|
+
❌ **Learning curve** - Need to understand mapping config syntax
|
|
129
|
+
❌ **Verbose config** - More setup for simple mappings
|
|
130
|
+
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
131
|
+
|
|
132
|
+
### Performance
|
|
133
|
+
- **100 locations** = 100 mutations = **100 API calls**
|
|
134
|
+
- **Time**: ~30-60 seconds
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Approach 2: UniversalMapper + Manual GraphQL
|
|
139
|
+
|
|
140
|
+
### When to Use
|
|
141
|
+
✅ Want field mapping/transformation (SDK resolvers)
|
|
142
|
+
✅ Prefer writing your own GraphQL query strings
|
|
143
|
+
✅ Need flexibility in GraphQL query structure
|
|
144
|
+
✅ CSV/JSON with transformations
|
|
145
|
+
|
|
146
|
+
### Code
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import {
|
|
150
|
+
UniversalMapper,
|
|
151
|
+
CSVParserService,
|
|
152
|
+
createClient,
|
|
153
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
154
|
+
|
|
155
|
+
// 1. Parse CSV
|
|
156
|
+
const parser = new CSVParserService();
|
|
157
|
+
const locations = await parser.parse(csvContent, { columns: true });
|
|
158
|
+
|
|
159
|
+
// 2. Configure field mapping (UniversalMapper)
|
|
160
|
+
const locationMapping = {
|
|
161
|
+
fields: {
|
|
162
|
+
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
163
|
+
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
164
|
+
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
165
|
+
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
166
|
+
supportPhoneNumber: { value: '+1-800-555-0100' },
|
|
167
|
+
|
|
168
|
+
// Nested address fields - UniversalMapper handles this!
|
|
169
|
+
'primaryAddress.ref': { source: 'ref' },
|
|
170
|
+
'primaryAddress.street': { source: 'address1' },
|
|
171
|
+
'primaryAddress.city': { source: 'city' },
|
|
172
|
+
'primaryAddress.state': { source: 'state' },
|
|
173
|
+
'primaryAddress.country': { source: 'country' },
|
|
174
|
+
'primaryAddress.latitude': { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
175
|
+
'primaryAddress.longitude': { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 3. Map all CSV records
|
|
180
|
+
const mapper = new UniversalMapper(locationMapping);
|
|
181
|
+
const mappedLocations = [];
|
|
182
|
+
|
|
183
|
+
for (const location of locations) {
|
|
184
|
+
const mapped = await mapper.map(location);
|
|
185
|
+
if (mapped.success) {
|
|
186
|
+
mappedLocations.push(mapped.data);
|
|
187
|
+
} else {
|
|
188
|
+
console.error(`Mapping failed: ${mapped.errors?.join(', ')}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 4. Write GraphQL mutation manually
|
|
193
|
+
const createMutation = `
|
|
194
|
+
mutation CreateLocation($input: CreateLocationInput!) {
|
|
195
|
+
createLocation(input: $input) {
|
|
196
|
+
id
|
|
197
|
+
ref
|
|
198
|
+
name
|
|
199
|
+
type
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
// 5. Setup client
|
|
205
|
+
const client = await createClient({ /* config */ });
|
|
206
|
+
|
|
207
|
+
// 6. Execute mutations using mapped data as variables
|
|
208
|
+
for (const location of mappedLocations) {
|
|
209
|
+
// Use mapped plain object as GraphQL variables
|
|
210
|
+
const result = await client.graphql({
|
|
211
|
+
query: createMutation,
|
|
212
|
+
variables: { input: location }, // ✅ Mapped data from UniversalMapper!
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
console.log(`✅ Created: ${location.ref}`);
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### What It Does
|
|
220
|
+
1. **UniversalMapper** handles field mapping and transformations
|
|
221
|
+
2. **Returns plain objects** with nested structures properly formatted
|
|
222
|
+
3. **YOU write** the GraphQL mutation strings
|
|
223
|
+
4. **Use mapped objects** as GraphQL `variables`
|
|
224
|
+
|
|
225
|
+
### Pros
|
|
226
|
+
✅ **Field mapping with SDK resolvers** - Get transformations (`sdk.parseInt`, `sdk.trim`, etc.)
|
|
227
|
+
✅ **Handles nested structures** - `primaryAddress.street` → proper nested object
|
|
228
|
+
✅ **Full control over GraphQL** - Write exact queries you need
|
|
229
|
+
✅ **Easier to debug** - See exactly what's happening
|
|
230
|
+
✅ **Less learning curve** - Just mapping config + standard GraphQL
|
|
231
|
+
|
|
232
|
+
### Cons
|
|
233
|
+
❌ **Manual GraphQL queries** - Must write mutation strings yourself
|
|
234
|
+
❌ **No schema validation** - Errors only at runtime
|
|
235
|
+
❌ **More boilerplate** - Mapping config + GraphQL query strings
|
|
236
|
+
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
237
|
+
|
|
238
|
+
### Performance
|
|
239
|
+
- **Same as GraphQLMutationMapper**: 100 locations = 100 API calls
|
|
240
|
+
- **Time**: ~30-60 seconds
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Approach 3: UniversalMapper + Event API
|
|
245
|
+
|
|
246
|
+
### When to Use
|
|
247
|
+
✅ Want to trigger Rubix workflows
|
|
248
|
+
✅ Need asynchronous processing
|
|
249
|
+
✅ Bulk operations that trigger business logic
|
|
250
|
+
✅ Products, locations, or any entity with Rubix workflow
|
|
251
|
+
|
|
252
|
+
### Code
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import {
|
|
256
|
+
UniversalMapper,
|
|
257
|
+
CSVParserService,
|
|
258
|
+
createClient,
|
|
259
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
260
|
+
|
|
261
|
+
// 1. Parse CSV
|
|
262
|
+
const parser = new CSVParserService();
|
|
263
|
+
const locations = await parser.parse(csvContent, { columns: true });
|
|
264
|
+
|
|
265
|
+
// 2. Configure field mapping (same UniversalMapper config)
|
|
266
|
+
const locationMapping = {
|
|
267
|
+
fields: {
|
|
268
|
+
ref: { source: 'ref', required: true, resolver: 'sdk.trim' },
|
|
269
|
+
name: { source: 'name', required: true, resolver: 'sdk.trim' },
|
|
270
|
+
type: { source: 'type', required: true, resolver: 'sdk.uppercase' },
|
|
271
|
+
status: { source: 'status', defaultValue: 'ACTIVE' },
|
|
272
|
+
|
|
273
|
+
// Nested address fields
|
|
274
|
+
'primaryAddress.ref': { source: 'ref' },
|
|
275
|
+
'primaryAddress.street': { source: 'address1' },
|
|
276
|
+
'primaryAddress.city': { source: 'city' },
|
|
277
|
+
'primaryAddress.state': { source: 'state' },
|
|
278
|
+
'primaryAddress.country': { source: 'country' },
|
|
279
|
+
'primaryAddress.latitude': { source: 'latitude', resolver: 'sdk.parseFloat' },
|
|
280
|
+
'primaryAddress.longitude': { source: 'longitude', resolver: 'sdk.parseFloat' },
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// 3. Map all CSV records
|
|
285
|
+
const mapper = new UniversalMapper(locationMapping);
|
|
286
|
+
const mappedLocations = [];
|
|
287
|
+
|
|
288
|
+
for (const location of locations) {
|
|
289
|
+
const mapped = await mapper.map(location);
|
|
290
|
+
if (mapped.success) {
|
|
291
|
+
mappedLocations.push(mapped.data);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// 4. Setup client
|
|
296
|
+
const client = await createClient({ /* config */ });
|
|
297
|
+
|
|
298
|
+
// 5. Send each record as an event (triggers Rubix workflow)
|
|
299
|
+
const eventName = 'UPSERT_LOCATION';
|
|
300
|
+
const entityRef = 'LOCATION_CATALOGUE:MASTER:1'; // Your catalogue reference
|
|
301
|
+
|
|
302
|
+
for (const location of mappedLocations) {
|
|
303
|
+
await client.sendEvent(
|
|
304
|
+
{
|
|
305
|
+
name: eventName,
|
|
306
|
+
entityRef: entityRef,
|
|
307
|
+
entityType: 'LOCATION_CATALOGUE',
|
|
308
|
+
entitySubtype: 'MASTER',
|
|
309
|
+
rootEntityRef: entityRef,
|
|
310
|
+
rootEntityType: 'LOCATION_CATALOGUE',
|
|
311
|
+
retailerId: '1',
|
|
312
|
+
attributes: location, // ✅ Mapped data from UniversalMapper!
|
|
313
|
+
},
|
|
314
|
+
'async' // or 'sync' for synchronous processing
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
console.log(`✅ Event sent: ${location.ref}`);
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### What It Does
|
|
322
|
+
1. **UniversalMapper** handles field mapping and transformations
|
|
323
|
+
2. **Returns plain objects** ready for Event API
|
|
324
|
+
3. **Send to Event API** which triggers Rubix workflows
|
|
325
|
+
4. **Workflows** handle the actual GraphQL mutations
|
|
326
|
+
|
|
327
|
+
### Pros
|
|
328
|
+
✅ **Field mapping with SDK resolvers** - Same as approach 2
|
|
329
|
+
✅ **Triggers Rubix workflows** - Business logic execution
|
|
330
|
+
✅ **Asynchronous processing** - Don't wait for completion
|
|
331
|
+
✅ **Error recovery** - Workflows can retry
|
|
332
|
+
✅ **Business logic** - Workflows can add custom validation, enrichment
|
|
333
|
+
|
|
334
|
+
### Cons
|
|
335
|
+
❌ **Requires Rubix workflows** - Need workflow setup
|
|
336
|
+
❌ **No immediate feedback** - Async processing
|
|
337
|
+
❌ **More complexity** - Workflow management
|
|
338
|
+
❌ **One-at-a-time** - 100 locations = 100 events
|
|
339
|
+
|
|
340
|
+
### Performance
|
|
341
|
+
- **100 locations** = 100 event API calls
|
|
342
|
+
- **Time**: ~30-60 seconds (event submission), plus async workflow processing
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Approach 4: Fully Manual (No Mapper)
|
|
347
|
+
|
|
348
|
+
### When to Use
|
|
349
|
+
✅ Simple, one-off operations
|
|
350
|
+
✅ Maximum control over everything
|
|
351
|
+
✅ Prototyping/testing
|
|
352
|
+
✅ Don't need field transformations
|
|
353
|
+
|
|
354
|
+
### Code
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import { CSVParserService, createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
358
|
+
|
|
359
|
+
// 1. Parse CSV manually
|
|
360
|
+
const parser = new CSVParserService();
|
|
361
|
+
const locations = await parser.parse(csvContent, { columns: true });
|
|
362
|
+
|
|
363
|
+
// 2. Write GraphQL mutation manually
|
|
364
|
+
const createMutation = `
|
|
365
|
+
mutation CreateLocation($input: CreateLocationInput!) {
|
|
366
|
+
createLocation(input: $input) {
|
|
367
|
+
id
|
|
368
|
+
ref
|
|
369
|
+
name
|
|
370
|
+
type
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
`;
|
|
374
|
+
|
|
375
|
+
// 3. Setup client
|
|
376
|
+
const client = await createClient({ /* config */ });
|
|
377
|
+
|
|
378
|
+
// 4. Process each location manually (build variables yourself)
|
|
379
|
+
for (const location of locations) {
|
|
380
|
+
// Manually build variables object
|
|
381
|
+
const variables = {
|
|
382
|
+
input: {
|
|
383
|
+
ref: location.ref?.trim(),
|
|
384
|
+
name: location.name?.trim(),
|
|
385
|
+
type: location.type?.toUpperCase(),
|
|
386
|
+
status: location.status || 'ACTIVE',
|
|
387
|
+
supportPhoneNumber: '+1-800-555-0100',
|
|
388
|
+
primaryAddress: {
|
|
389
|
+
ref: location.ref,
|
|
390
|
+
street: location.address1,
|
|
391
|
+
city: location.city,
|
|
392
|
+
state: location.state,
|
|
393
|
+
country: location.country,
|
|
394
|
+
latitude: parseFloat(location.latitude),
|
|
395
|
+
longitude: parseFloat(location.longitude),
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const result = await client.graphql({ query: createMutation, variables });
|
|
401
|
+
console.log(`✅ Created: ${location.ref}`);
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### What It Does
|
|
406
|
+
1. **You parse** CSV data
|
|
407
|
+
2. **You write** GraphQL mutation strings
|
|
408
|
+
3. **You build** variables object manually
|
|
409
|
+
4. **You handle** transformations (`trim()`, `parseFloat()`, `toUpperCase()`)
|
|
410
|
+
|
|
411
|
+
### Pros
|
|
412
|
+
✅ **Full control** - No abstraction overhead
|
|
413
|
+
✅ **Simple to understand** - No mapper configuration
|
|
414
|
+
✅ **Easy to debug** - See exactly what's happening
|
|
415
|
+
✅ **No learning curve** - Just TypeScript + GraphQL
|
|
416
|
+
|
|
417
|
+
### Cons
|
|
418
|
+
❌ **Boilerplate** - Repetitive code for transformations
|
|
419
|
+
❌ **No validation** - Errors only at runtime
|
|
420
|
+
❌ **Manual transforms** - Write `trim()`, `parseFloat()`, etc. yourself
|
|
421
|
+
❌ **Error handling** - You implement all error logic
|
|
422
|
+
❌ **Maintenance** - Schema changes need code updates
|
|
423
|
+
❌ **One-at-a-time** - 100 locations = 100 API calls
|
|
424
|
+
|
|
425
|
+
### Performance
|
|
426
|
+
- **Same as other approaches**: 100 locations = 100 API calls
|
|
427
|
+
- **Time**: ~30-60 seconds
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Decision Matrix
|
|
432
|
+
|
|
433
|
+
| Factor | GraphQLMutationMapper | UniversalMapper + GraphQL | UniversalMapper + Event API | Fully Manual |
|
|
434
|
+
|--------|----------------------|--------------------------|----------------------------|--------------|
|
|
435
|
+
| **Field Mapping** | ✅ Built-in | ✅ Built-in | ✅ Built-in | ❌ Manual |
|
|
436
|
+
| **SDK Resolvers** | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
|
|
437
|
+
| **GraphQL Generation** | ✅ Auto | ❌ You write | ❌ N/A | ❌ You write |
|
|
438
|
+
| **Schema Validation** | ✅ Yes | ❌ No | ❌ No | ❌ No |
|
|
439
|
+
| **Nested Structures** | ✅ Auto | ✅ Auto | ✅ Auto | ❌ Manual |
|
|
440
|
+
| **Triggers Workflows** | ❌ No | ❌ No | ✅ Yes | ❌ No |
|
|
441
|
+
| **Immediate Feedback** | ✅ Yes | ✅ Yes | ❌ Async | ✅ Yes |
|
|
442
|
+
| **Learning Curve** | 🟡 Medium | 🟢 Easy | 🟢 Easy | 🟢 Easy |
|
|
443
|
+
| **Best For** | Complex XML/JSON | CSV + control | Workflow triggers | Simple tasks |
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
## API Comparison: GraphQL Mutations vs Event API vs Batch API
|
|
448
|
+
|
|
449
|
+
### GraphQL Mutations (Approaches 1, 2, 4)
|
|
450
|
+
```typescript
|
|
451
|
+
await client.graphql({
|
|
452
|
+
query: mutation,
|
|
453
|
+
variables: { input: data },
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
- **Immediate feedback**: Response includes created/updated entity
|
|
457
|
+
- **All entities**: Locations, products, orders, customers
|
|
458
|
+
- **One-at-a-time**: N records = N API calls
|
|
459
|
+
- **Use when**: Need immediate response, <100 records
|
|
460
|
+
|
|
461
|
+
### Event API (Approach 3)
|
|
462
|
+
```typescript
|
|
463
|
+
await client.sendEvent({
|
|
464
|
+
name: 'UPSERT_LOCATION',
|
|
465
|
+
attributes: data,
|
|
466
|
+
}, 'async');
|
|
467
|
+
```
|
|
468
|
+
- **Triggers workflows**: Rubix workflows process events
|
|
469
|
+
- **Asynchronous**: Don't wait for completion
|
|
470
|
+
- **All entities**: Locations, products, orders (NOT inventory)
|
|
471
|
+
- **One-at-a-time**: N records = N events
|
|
472
|
+
- **Use when**: Need workflow execution, complex business logic
|
|
473
|
+
|
|
474
|
+
### Batch API (Inventory ONLY)
|
|
475
|
+
```typescript
|
|
476
|
+
await client.sendBatch(jobId, {
|
|
477
|
+
entityType: 'INVENTORY',
|
|
478
|
+
action: 'UPSERT',
|
|
479
|
+
entities: data,
|
|
480
|
+
});
|
|
481
|
+
```
|
|
482
|
+
- **Bulk optimized**: 1 API call for thousands of records
|
|
483
|
+
- **Change detection**: BPP filters unchanged records
|
|
484
|
+
- **INVENTORY ONLY**: No other entities supported
|
|
485
|
+
- **Use when**: Bulk inventory updates (>100 records)
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Key Insights
|
|
490
|
+
|
|
491
|
+
### 1. UniversalMapper Works With ALL APIs!
|
|
492
|
+
|
|
493
|
+
**Pattern:**
|
|
494
|
+
```typescript
|
|
495
|
+
// Step 1: Map data using UniversalMapper
|
|
496
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
497
|
+
const mapped = await mapper.map(csvRow);
|
|
498
|
+
|
|
499
|
+
// Step 2: Use mapped data with ANY API
|
|
500
|
+
// Option A: GraphQL Mutations
|
|
501
|
+
await client.graphql({
|
|
502
|
+
query: mutation,
|
|
503
|
+
variables: { input: mapped.data },
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Option B: Event API
|
|
507
|
+
await client.sendEvent({
|
|
508
|
+
name: 'UPSERT_ENTITY',
|
|
509
|
+
attributes: mapped.data,
|
|
510
|
+
}, 'async');
|
|
511
|
+
|
|
512
|
+
// Option C: Batch API (inventory only)
|
|
513
|
+
await client.sendBatch(jobId, {
|
|
514
|
+
entityType: 'INVENTORY',
|
|
515
|
+
entities: [mapped.data],
|
|
516
|
+
});
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### 2. Four Approaches Comparison
|
|
520
|
+
|
|
521
|
+
| Approach | Mapping | API | GraphQL Query | Control |
|
|
522
|
+
|----------|---------|-----|---------------|---------|
|
|
523
|
+
| **GraphQLMutationMapper** | Auto | GraphQL | Auto | Low |
|
|
524
|
+
| **UniversalMapper + GraphQL** | Auto | GraphQL | Manual | Medium |
|
|
525
|
+
| **UniversalMapper + Event API** | Auto | Event API | N/A | Medium |
|
|
526
|
+
| **Fully Manual** | Manual | GraphQL | Manual | Maximum |
|
|
527
|
+
|
|
528
|
+
### 3. When to Use Each Approach
|
|
529
|
+
|
|
530
|
+
**GraphQLMutationMapper:**
|
|
531
|
+
- Complex XML/JSON (SFCC orders, EDI)
|
|
532
|
+
- Need schema validation
|
|
533
|
+
- Want auto-generated queries
|
|
534
|
+
|
|
535
|
+
**UniversalMapper + Manual GraphQL:**
|
|
536
|
+
- CSV with transformations
|
|
537
|
+
- Want control over GraphQL queries
|
|
538
|
+
- Comfortable writing queries
|
|
539
|
+
|
|
540
|
+
**UniversalMapper + Event API:**
|
|
541
|
+
- Need to trigger Rubix workflows
|
|
542
|
+
- Complex business logic
|
|
543
|
+
- Asynchronous processing
|
|
544
|
+
|
|
545
|
+
**Fully Manual:**
|
|
546
|
+
- Simple CSV → GraphQL
|
|
547
|
+
- Prototyping
|
|
548
|
+
- Maximum flexibility
|
|
549
|
+
|
|
550
|
+
### 4. Batch API is Special
|
|
551
|
+
|
|
552
|
+
**Batch API ONLY supports inventory:**
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
// ✅ CORRECT - Inventory via Batch API
|
|
556
|
+
await client.sendBatch(jobId, {
|
|
557
|
+
entityType: 'INVENTORY', // Only option!
|
|
558
|
+
action: 'UPSERT',
|
|
559
|
+
entities: inventoryData,
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
// ❌ WRONG - No Batch API for these
|
|
563
|
+
entityType: 'LOCATION' // Use GraphQL or Event API
|
|
564
|
+
entityType: 'PRODUCT' // Use GraphQL or Event API
|
|
565
|
+
entityType: 'ORDER' // Use GraphQL or Event API
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**For inventory with UniversalMapper:**
|
|
569
|
+
```typescript
|
|
570
|
+
// Map inventory records
|
|
571
|
+
const mapper = new UniversalMapper({
|
|
572
|
+
fields: {
|
|
573
|
+
skuRef: { source: 'sku', required: true },
|
|
574
|
+
locationRef: { source: 'location', required: true },
|
|
575
|
+
qty: { source: 'quantity', resolver: 'sdk.parseInt' },
|
|
576
|
+
},
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const mapped = await Promise.all(csvRows.map(row => mapper.map(row)));
|
|
580
|
+
|
|
581
|
+
// Send to Batch API (1 API call for thousands of records!)
|
|
582
|
+
const job = await client.createJob({ name: 'inventory', retailerId: '1' });
|
|
583
|
+
await client.sendBatch(job.id, {
|
|
584
|
+
entityType: 'INVENTORY',
|
|
585
|
+
action: 'UPSERT',
|
|
586
|
+
entities: mapped.filter(r => r.success).map(r => r.data),
|
|
587
|
+
});
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
## Performance Comparison
|
|
593
|
+
|
|
594
|
+
| Scenario | Approach | API Calls | Time | Best For |
|
|
595
|
+
|----------|----------|-----------|------|----------|
|
|
596
|
+
| **100 locations** | GraphQLMutationMapper | 100 | ~30-60 sec | Schema validation |
|
|
597
|
+
| **100 locations** | UniversalMapper + GraphQL | 100 | ~30-60 sec | Query control |
|
|
598
|
+
| **100 locations** | UniversalMapper + Event API | 100 | ~30-60 sec | Workflow triggers |
|
|
599
|
+
| **100 locations** | Fully Manual | 100 | ~30-60 sec | Simplicity |
|
|
600
|
+
| **1,000 inventory** | Any approach + GraphQL | 1,000 | ~5-10 min ❌ | Don't use |
|
|
601
|
+
| **1,000 inventory** | UniversalMapper + Batch API | 2 | ~30 sec ✅ | BEST choice |
|
|
602
|
+
|
|
603
|
+
**Key Takeaway**: All four approaches have same performance for locations (no Batch API). Only inventory benefits from Batch API.
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## Summary
|
|
608
|
+
|
|
609
|
+
**All 4 approaches work for locations:**
|
|
610
|
+
|
|
611
|
+
1. **GraphQLMutationMapper** = Auto mapping + auto GraphQL query
|
|
612
|
+
2. **UniversalMapper + Manual GraphQL** = Auto mapping + manual GraphQL query
|
|
613
|
+
3. **UniversalMapper + Event API** = Auto mapping + workflow triggers
|
|
614
|
+
4. **Fully Manual** = Everything manual
|
|
615
|
+
|
|
616
|
+
**Choose based on:**
|
|
617
|
+
|
|
618
|
+
1. **Need schema validation?** → GraphQLMutationMapper
|
|
619
|
+
2. **Want query control?** → UniversalMapper + Manual GraphQL
|
|
620
|
+
3. **Need workflows?** → UniversalMapper + Event API
|
|
621
|
+
4. **Simple operation?** → Fully Manual
|
|
622
|
+
|
|
623
|
+
**For inventory specifically:**
|
|
624
|
+
- Use UniversalMapper + Batch API (20x faster for bulk!)
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
## Testing All Approaches
|
|
631
|
+
|
|
632
|
+
A comprehensive test script is available to validate all 4 approaches with the same input:
|
|
633
|
+
|
|
634
|
+
**Location**: `fc-connect-sdk/tests/manual/mapper-comparison-test.ts`
|
|
635
|
+
|
|
636
|
+
### Run in Dry Run Mode (No API Calls)
|
|
637
|
+
|
|
638
|
+
```bash
|
|
639
|
+
npx tsx tests/manual/mapper-comparison-test.ts
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
This will:
|
|
643
|
+
- Parse the same CSV data in all 4 approaches
|
|
644
|
+
- Show the mapped data structure for each approach
|
|
645
|
+
- Demonstrate that all approaches produce consistent output
|
|
646
|
+
- No actual API calls are made
|
|
647
|
+
|
|
648
|
+
### Run with Live Credentials
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
FLUENT_BASE_URL=https://your-instance.api.fluentretail.com/graphql \
|
|
652
|
+
FLUENT_CLIENT_ID=your-client-id \
|
|
653
|
+
FLUENT_CLIENT_SECRET=your-secret \
|
|
654
|
+
FLUENT_USERNAME=your-username \
|
|
655
|
+
FLUENT_PASSWORD=your-password \
|
|
656
|
+
FLUENT_RETAILER_ID=1 \
|
|
657
|
+
npx tsx tests/manual/mapper-comparison-test.ts
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
This will actually execute all 4 approaches against your Fluent Commerce instance.
|
|
661
|
+
|
|
662
|
+
**⚠️ Warning**: This will create 3 locations (DC-01, STORE-001, STORE-002) in your Fluent instance. Use a sandbox/test environment.
|
|
663
|
+
|
|
664
|
+
### Output Example
|
|
665
|
+
|
|
666
|
+
Each approach shows:
|
|
667
|
+
- Parsed CSV data
|
|
668
|
+
- Mapped/transformed data structure
|
|
669
|
+
- GraphQL query (Approach 1 only)
|
|
670
|
+
- Execution result (if using live credentials)
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## Related Docs
|
|
675
|
+
|
|
676
|
+
- GraphQLMutationMapper Guide: `docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/`
|
|
677
|
+
- UniversalMapper Guide: `docs/02-CORE-GUIDES/mapping/modules/`
|
|
678
|
+
- Event API Guide: `docs/02-CORE-GUIDES/ingestion/modules/08-event-api.md`
|
|
679
|
+
- Batch API Guide: `docs/02-CORE-GUIDES/ingestion/modules/06-batch-api.md`
|
|
680
|
+
- Real Templates:
|
|
681
|
+
- UniversalMapper + GraphQL: `docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md`
|
|
682
|
+
- UniversalMapper + Event API: `docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md`
|