@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,624 +1,624 @@
|
|
|
1
|
-
# Module 5: Best Practices
|
|
2
|
-
|
|
3
|
-
**Level:** Advanced
|
|
4
|
-
**Estimated Time:** 25 minutes
|
|
5
|
-
|
|
6
|
-
**SDK Version:** Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
This module consolidates production-ready patterns, performance optimizations, and troubleshooting techniques for multi-connection scenarios.
|
|
11
|
-
|
|
12
|
-
## Learning Objectives
|
|
13
|
-
|
|
14
|
-
By the end of this module, you will:
|
|
15
|
-
- ✅ Know when to use each multi-connection pattern
|
|
16
|
-
- ✅ Implement production-ready error handling
|
|
17
|
-
- ✅ Optimize performance for large-scale exports
|
|
18
|
-
- ✅ Debug common issues effectively
|
|
19
|
-
- ✅ Apply security and reliability best practices
|
|
20
|
-
|
|
21
|
-
## Decision Matrix: Which Pattern to Use?
|
|
22
|
-
|
|
23
|
-
### Quick Decision Tree
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
Do you need ALL connections fully paginated?
|
|
27
|
-
├─ YES → Use parallel queries (Promise.all)
|
|
28
|
-
│
|
|
29
|
-
└─ NO → Do you need MORE THAN ONE connection paginated?
|
|
30
|
-
├─ YES → Use parallel queries (Promise.all)
|
|
31
|
-
│
|
|
32
|
-
└─ NO → Use single query with connectionPath
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Detailed Comparison
|
|
36
|
-
|
|
37
|
-
| Scenario | Pattern | Why |
|
|
38
|
-
|----------|---------|-----|
|
|
39
|
-
| Export all products + all locations | Parallel | Both need full pagination |
|
|
40
|
-
| Export all products + first page locations | Single + connectionPath | Only products need pagination |
|
|
41
|
-
| Export 3+ different entities | Parallel | Multiple connections need pagination |
|
|
42
|
-
| Get order with all items | Single + connectionPath | Nested connection |
|
|
43
|
-
| Export with different limits per entity | Parallel | Independent limit control |
|
|
44
|
-
|
|
45
|
-
## Best Practice 1: Always Use connectionPath
|
|
46
|
-
|
|
47
|
-
### ✅ DO: Be Explicit
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
// ✅ Good - explicit and predictable
|
|
51
|
-
const result = await client.graphql({
|
|
52
|
-
query: multiConnectionQuery,
|
|
53
|
-
pagination: {
|
|
54
|
-
connectionPath: 'products',
|
|
55
|
-
maxPages: 10
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### ❌ DON'T: Rely on Auto-Detection
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
// ❌ Risky - which connection gets paginated?
|
|
64
|
-
const result = await client.graphql({
|
|
65
|
-
query: multiConnectionQuery,
|
|
66
|
-
pagination: { maxPages: 10 } // Auto-detection is unpredictable
|
|
67
|
-
});
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Exception:** Only one connection exists and path is obvious.
|
|
71
|
-
|
|
72
|
-
## Best Practice 2: Use Parallel Queries for Multiple Full Pagination
|
|
73
|
-
|
|
74
|
-
### ✅ DO: Separate Queries
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
// ✅ Good - parallel queries with independent configs
|
|
78
|
-
const [products, locations] = await Promise.all([
|
|
79
|
-
client.graphql({
|
|
80
|
-
query: productsQuery,
|
|
81
|
-
variables: { first: 100 },
|
|
82
|
-
pagination: { maxPages: 10, maxRecords: 1000 }
|
|
83
|
-
}),
|
|
84
|
-
client.graphql({
|
|
85
|
-
query: locationsQuery,
|
|
86
|
-
variables: { first: 50 },
|
|
87
|
-
pagination: { maxPages: 5, maxRecords: 250 }
|
|
88
|
-
})
|
|
89
|
-
]);
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### ❌ DON'T: Single Query Expecting Multiple Pagination
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
// ❌ Bad - only one connection will be paginated
|
|
96
|
-
const result = await client.graphql({
|
|
97
|
-
query: multiConnectionQuery,
|
|
98
|
-
pagination: {
|
|
99
|
-
connectionPath: 'products', // locations won't be paginated
|
|
100
|
-
maxPages: 10
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Best Practice 3: Monitor Progress Per Connection
|
|
106
|
-
|
|
107
|
-
### ✅ DO: Separate Progress Tracking
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
const [products, locations] = await Promise.all([
|
|
111
|
-
client.graphql({
|
|
112
|
-
query: productsQuery,
|
|
113
|
-
pagination: {
|
|
114
|
-
maxPages: 10,
|
|
115
|
-
onProgress: (page, records) => {
|
|
116
|
-
console.log(`[Products] Page ${page}: ${records} records`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}),
|
|
120
|
-
client.graphql({
|
|
121
|
-
query: locationsQuery,
|
|
122
|
-
pagination: {
|
|
123
|
-
maxPages: 5,
|
|
124
|
-
onProgress: (page, records) => {
|
|
125
|
-
console.log(`[Locations] Page ${page}: ${records} records`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
]);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### ❌ DON'T: Generic Logging
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
// ❌ Bad - can't tell which connection
|
|
136
|
-
const result = await client.graphql({
|
|
137
|
-
query: multiConnectionQuery,
|
|
138
|
-
pagination: {
|
|
139
|
-
connectionPath: 'products',
|
|
140
|
-
onProgress: (page, records) => {
|
|
141
|
-
console.log(`Page ${page}: ${records}`); // Which connection?
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Best Practice 4: Use Promise.allSettled for Resilience
|
|
148
|
-
|
|
149
|
-
### ✅ DO: Handle Partial Failures
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
const results = await Promise.allSettled([
|
|
153
|
-
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
154
|
-
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } }),
|
|
155
|
-
client.graphql({ query: virtualPositionsQuery, pagination: { maxPages: 20 } })
|
|
156
|
-
]);
|
|
157
|
-
|
|
158
|
-
const successful = results.filter(r => r.status === 'fulfilled');
|
|
159
|
-
const failed = results.filter(r => r.status === 'rejected');
|
|
160
|
-
|
|
161
|
-
console.log(`✅ Successful: ${successful.length}`);
|
|
162
|
-
console.log(`❌ Failed: ${failed.length}`);
|
|
163
|
-
|
|
164
|
-
// Process successful results
|
|
165
|
-
successful.forEach((result, index) => {
|
|
166
|
-
if (result.status === 'fulfilled') {
|
|
167
|
-
const data = result.value;
|
|
168
|
-
// Process data
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Log failures
|
|
173
|
-
failed.forEach((result, index) => {
|
|
174
|
-
if (result.status === 'rejected') {
|
|
175
|
-
console.error(`Failed query ${index}:`, result.reason);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### ❌ DON'T: Use Promise.all Without Error Handling
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
// ❌ Bad - one failure loses all results
|
|
184
|
-
try {
|
|
185
|
-
const [products, locations] = await Promise.all([
|
|
186
|
-
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
187
|
-
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
188
|
-
]);
|
|
189
|
-
} catch (error) {
|
|
190
|
-
// Both results lost if one fails
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## Best Practice 5: Set Appropriate Safety Limits
|
|
195
|
-
|
|
196
|
-
### ✅ DO: Use OR-Logic Limits
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
const result = await client.graphql({
|
|
200
|
-
query: productsQuery,
|
|
201
|
-
pagination: {
|
|
202
|
-
maxPages: 100, // OR
|
|
203
|
-
maxRecords: 10000, // OR
|
|
204
|
-
timeoutMs: 60000 // OR (60 seconds)
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
**Whichever limit is hit first stops pagination.**
|
|
210
|
-
|
|
211
|
-
### ✅ DO: Match Limits to Entity Complexity
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
// Simple entities - higher limits
|
|
215
|
-
const virtualPositions = await client.graphql({
|
|
216
|
-
query: virtualPositionsQuery,
|
|
217
|
-
pagination: {
|
|
218
|
-
maxPages: 200,
|
|
219
|
-
maxRecords: 20000
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// Complex entities - lower limits
|
|
224
|
-
const orders = await client.graphql({
|
|
225
|
-
query: ordersWithItemsQuery,
|
|
226
|
-
pagination: {
|
|
227
|
-
maxPages: 50,
|
|
228
|
-
maxRecords: 2000
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Best Practice 6: Optimize Page Sizes
|
|
234
|
-
|
|
235
|
-
### ✅ DO: Match Page Size to Entity
|
|
236
|
-
|
|
237
|
-
| Entity Type | Recommended Page Size | Reasoning |
|
|
238
|
-
|-------------|----------------------|-----------|
|
|
239
|
-
| VirtualPositions | 200-500 | Very simple fields |
|
|
240
|
-
| Locations | 100-200 | Simple fields |
|
|
241
|
-
| Products | 50-100 | Medium complexity |
|
|
242
|
-
| Orders (no items) | 50-100 | Medium complexity |
|
|
243
|
-
| Orders (with items) | 20-50 | High complexity, nested |
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
const [virtualPositions, products, orders] = await Promise.all([
|
|
247
|
-
client.graphql({
|
|
248
|
-
query: virtualPositionsQuery,
|
|
249
|
-
variables: { first: 200 }, // ← Large page size
|
|
250
|
-
pagination: { maxRecords: 10000 }
|
|
251
|
-
}),
|
|
252
|
-
client.graphql({
|
|
253
|
-
query: productsQuery,
|
|
254
|
-
variables: { first: 75 }, // ← Medium page size
|
|
255
|
-
pagination: { maxRecords: 5000 }
|
|
256
|
-
}),
|
|
257
|
-
client.graphql({
|
|
258
|
-
query: ordersQuery,
|
|
259
|
-
variables: { first: 30 }, // ← Small page size
|
|
260
|
-
pagination: { maxRecords: 1000 }
|
|
261
|
-
})
|
|
262
|
-
]);
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## Best Practice 7: Reuse Client Instances
|
|
266
|
-
|
|
267
|
-
### ✅ DO: Share Client
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
// ✅ Good - create once, reuse
|
|
271
|
-
const client = await createClient({
|
|
272
|
-
config: {
|
|
273
|
-
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
274
|
-
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
275
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
276
|
-
username: process.env.FLUENT_USERNAME!,
|
|
277
|
-
password: process.env.FLUENT_PASSWORD!,
|
|
278
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
const [products, locations, virtualPositions] = await Promise.all([
|
|
283
|
-
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
284
|
-
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } }),
|
|
285
|
-
client.graphql({ query: virtualPositionsQuery, pagination: { maxPages: 20 } })
|
|
286
|
-
]);
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### ❌ DON'T: Create Multiple Clients
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
// ❌ Bad - creates new auth token for each query
|
|
293
|
-
const results = await Promise.all([
|
|
294
|
-
createClient({ config: {...} }).then(c => c.graphql({ ... })),
|
|
295
|
-
createClient({ config: {...} }).then(c => c.graphql({ ... })),
|
|
296
|
-
createClient({ config: {...} }).then(c => c.graphql({ ... }))
|
|
297
|
-
]);
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
## Best Practice 8: Use Appropriate Logging
|
|
301
|
-
|
|
302
|
-
### ✅ DO: Use Native Log in Versori
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
// ✅ Versori Platform - use native log
|
|
306
|
-
import { schedule, http } from '@versori/run';
|
|
307
|
-
import { createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
308
|
-
|
|
309
|
-
export const workflow = schedule('multi-export', '0 * * * *').then(
|
|
310
|
-
http('process', { connection: 'fluent' }, async (ctx) => {
|
|
311
|
-
const { log } = ctx;
|
|
312
|
-
|
|
313
|
-
// Pass native log to SDK
|
|
314
|
-
const client = await createClient(ctx); // Auto-detects Versori context
|
|
315
|
-
|
|
316
|
-
log.info('Starting parallel export');
|
|
317
|
-
const [products, locations] = await Promise.all([
|
|
318
|
-
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
319
|
-
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
320
|
-
]);
|
|
321
|
-
|
|
322
|
-
log.info('Export complete', {
|
|
323
|
-
products: products.extensions.autoPagination.totalRecords,
|
|
324
|
-
locations: locations.extensions.autoPagination.totalRecords
|
|
325
|
-
});
|
|
326
|
-
})
|
|
327
|
-
);
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### ✅ DO: Use Minimal Logging in Standalone
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
// ✅ Standalone Node.js/Deno - use minimal logging utilities
|
|
334
|
-
import {
|
|
335
|
-
createClient,
|
|
336
|
-
createConsoleLogger,
|
|
337
|
-
toStructuredLogger
|
|
338
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
339
|
-
|
|
340
|
-
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
341
|
-
service: 'MultiConnectionExport',
|
|
342
|
-
correlationId: 'export-123'
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
const client = await createClient({
|
|
346
|
-
config: { /* ... */ }
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
logger.info('Starting parallel export');
|
|
350
|
-
const [products, locations] = await Promise.all([
|
|
351
|
-
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
352
|
-
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
353
|
-
]);
|
|
354
|
-
|
|
355
|
-
logger.info('Export complete', {
|
|
356
|
-
products: products.extensions.autoPagination.totalRecords,
|
|
357
|
-
locations: locations.extensions.autoPagination.totalRecords
|
|
358
|
-
});
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## Best Practice 9: Batch Parallel Queries
|
|
362
|
-
|
|
363
|
-
### ✅ DO: Limit Concurrent Queries
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
async function batchedParallelQueries(queries: any[], batchSize = 3) {
|
|
367
|
-
const results = [];
|
|
368
|
-
|
|
369
|
-
for (let i = 0; i < queries.length; i += batchSize) {
|
|
370
|
-
const batch = queries.slice(i, i + batchSize);
|
|
371
|
-
console.log(`Processing batch ${i / batchSize + 1}...`);
|
|
372
|
-
|
|
373
|
-
const batchResults = await Promise.all(
|
|
374
|
-
batch.map(q => client.graphql(q))
|
|
375
|
-
);
|
|
376
|
-
|
|
377
|
-
results.push(...batchResults);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
return results;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Use it
|
|
384
|
-
const queries = [
|
|
385
|
-
{ query: productsQuery, pagination: { maxPages: 10 } },
|
|
386
|
-
{ query: locationsQuery, pagination: { maxPages: 5 } },
|
|
387
|
-
{ query: virtualPositionsQuery, pagination: { maxPages: 20 } },
|
|
388
|
-
{ query: ordersQuery, pagination: { maxPages: 15 } },
|
|
389
|
-
{ query: fulfilmentsQuery, pagination: { maxPages: 8 } }
|
|
390
|
-
];
|
|
391
|
-
|
|
392
|
-
const results = await batchedParallelQueries(queries, 3);
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### ❌ DON'T: Too Many Concurrent Queries
|
|
396
|
-
|
|
397
|
-
```typescript
|
|
398
|
-
// ❌ Bad - 10+ parallel queries may overwhelm API/network
|
|
399
|
-
const results = await Promise.all([...Array(10)].map(/* query */));
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
## Troubleshooting
|
|
403
|
-
|
|
404
|
-
### Issue 1: Only First Page Returned
|
|
405
|
-
|
|
406
|
-
**Symptoms:**
|
|
407
|
-
- `maxPages: 10` set, but only first page returned
|
|
408
|
-
- `totalPages: 1` in metadata
|
|
409
|
-
|
|
410
|
-
**Causes & Fixes:**
|
|
411
|
-
|
|
412
|
-
```typescript
|
|
413
|
-
// Cause 1: No $after variable in query
|
|
414
|
-
// ❌ Wrong
|
|
415
|
-
query GetProducts($first: Int!) {
|
|
416
|
-
products(first: $first) { ... } // Missing $after
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// ✅ Fix
|
|
420
|
-
query GetProducts($first: Int!, $after: String) {
|
|
421
|
-
products(first: $first, after: $after) { ... }
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Cause 2: connectionPath pointing to wrong field
|
|
425
|
-
// ❌ Wrong
|
|
426
|
-
pagination: { connectionPath: 'product' } // Typo
|
|
427
|
-
|
|
428
|
-
// ✅ Fix
|
|
429
|
-
pagination: { connectionPath: 'products' } // Correct field name
|
|
430
|
-
|
|
431
|
-
// Cause 3: No more pages available
|
|
432
|
-
// ✅ Check hasNextPage in first response
|
|
433
|
-
const firstPage = await client.graphql({
|
|
434
|
-
query,
|
|
435
|
-
variables: { first: 100 }
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
console.log(firstPage.data.products.pageInfo.hasNextPage);
|
|
439
|
-
// If false, only one page exists
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
### Issue 2: "Connection not found at path"
|
|
443
|
-
|
|
444
|
-
**Symptoms:**
|
|
445
|
-
- Error: "No connection found at path 'products'"
|
|
446
|
-
|
|
447
|
-
**Causes & Fixes:**
|
|
448
|
-
|
|
449
|
-
```typescript
|
|
450
|
-
// Cause 1: Typo in connectionPath
|
|
451
|
-
// ❌ Wrong
|
|
452
|
-
pagination: { connectionPath: 'product' }
|
|
453
|
-
|
|
454
|
-
// ✅ Fix
|
|
455
|
-
pagination: { connectionPath: 'products' }
|
|
456
|
-
|
|
457
|
-
// Cause 2: Path doesn't match query structure
|
|
458
|
-
// ❌ Wrong
|
|
459
|
-
query { order { items { ... } } }
|
|
460
|
-
pagination: { connectionPath: 'items' }
|
|
461
|
-
|
|
462
|
-
// ✅ Fix
|
|
463
|
-
pagination: { connectionPath: 'order.items' }
|
|
464
|
-
|
|
465
|
-
// Cause 3: Using alias but targeting original name
|
|
466
|
-
// ❌ Wrong
|
|
467
|
-
query { myProducts: products { ... } }
|
|
468
|
-
pagination: { connectionPath: 'products' }
|
|
469
|
-
|
|
470
|
-
// ✅ Fix
|
|
471
|
-
pagination: { connectionPath: 'myProducts' }
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### Issue 3: Slow Performance
|
|
475
|
-
|
|
476
|
-
**Symptoms:**
|
|
477
|
-
- Queries taking very long
|
|
478
|
-
- High memory usage
|
|
479
|
-
|
|
480
|
-
**Optimizations:**
|
|
481
|
-
|
|
482
|
-
```typescript
|
|
483
|
-
// Optimization 1: Reduce page size for complex queries
|
|
484
|
-
// ❌ Slow
|
|
485
|
-
variables: { first: 200 } // Too large for orders with items
|
|
486
|
-
|
|
487
|
-
// ✅ Fast
|
|
488
|
-
variables: { first: 30 } // Appropriate for complex entities
|
|
489
|
-
|
|
490
|
-
// Optimization 2: Add timeoutMs limit
|
|
491
|
-
pagination: {
|
|
492
|
-
maxPages: 100,
|
|
493
|
-
timeoutMs: 60000 // ← Stop after 60 seconds
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// Optimization 3: Reduce maxRecords
|
|
497
|
-
pagination: {
|
|
498
|
-
maxRecords: 5000 // ← Prevent excessive fetching
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// Optimization 4: Use batching for many queries
|
|
502
|
-
await batchedParallelQueries(queries, 3); // 3 at a time
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
### Issue 4: Unexpected Record Counts
|
|
506
|
-
|
|
507
|
-
**Symptoms:**
|
|
508
|
-
- Getting more/fewer records than expected
|
|
509
|
-
|
|
510
|
-
**Diagnostic Steps:**
|
|
511
|
-
|
|
512
|
-
```typescript
|
|
513
|
-
// Step 1: Check metadata
|
|
514
|
-
console.log(result.extensions.autoPagination);
|
|
515
|
-
// {
|
|
516
|
-
// totalPages: 8,
|
|
517
|
-
// totalRecords: 743,
|
|
518
|
-
// truncated: true // ← Hit a limit
|
|
519
|
-
// }
|
|
520
|
-
|
|
521
|
-
// Step 2: Check which limit was hit
|
|
522
|
-
if (result.extensions.autoPagination.truncated) {
|
|
523
|
-
// Check configured limits
|
|
524
|
-
console.log('Configured limits:', {
|
|
525
|
-
maxPages: 10,
|
|
526
|
-
maxRecords: 1000,
|
|
527
|
-
timeoutMs: 30000
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
// If totalPages < maxPages, likely hit maxRecords or timeoutMs
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// Step 3: Verify page size
|
|
534
|
-
const { totalRecords, totalPages } = result.extensions.autoPagination;
|
|
535
|
-
const avgPageSize = totalRecords / totalPages;
|
|
536
|
-
console.log(`Average page size: ${avgPageSize}`);
|
|
537
|
-
// Should match variables.first (approximately)
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### Issue 5: Deduplication Issues
|
|
541
|
-
|
|
542
|
-
**Symptoms:**
|
|
543
|
-
- Seeing duplicate records
|
|
544
|
-
- Record count higher than expected
|
|
545
|
-
|
|
546
|
-
**Causes & Fixes:**
|
|
547
|
-
|
|
548
|
-
```typescript
|
|
549
|
-
// Cause: Entities don't have 'id' field
|
|
550
|
-
// ❌ Missing id
|
|
551
|
-
query GetProducts($first: Int!, $after: String) {
|
|
552
|
-
products(first: $first, after: $after) {
|
|
553
|
-
edges {
|
|
554
|
-
node { ref type } // ← No 'id' field
|
|
555
|
-
cursor
|
|
556
|
-
}
|
|
557
|
-
pageInfo { hasNextPage }
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// ✅ Include id for deduplication
|
|
562
|
-
query GetProducts($first: Int!, $after: String) {
|
|
563
|
-
products(first: $first, after: $after) {
|
|
564
|
-
edges {
|
|
565
|
-
node { id ref type } // ← Include 'id'
|
|
566
|
-
cursor
|
|
567
|
-
}
|
|
568
|
-
pageInfo { hasNextPage }
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
**Note:** SDK deduplicates by `id` field automatically. Always include `id` in your queries.
|
|
574
|
-
|
|
575
|
-
## Production Checklist
|
|
576
|
-
|
|
577
|
-
Before deploying multi-connection pagination:
|
|
578
|
-
|
|
579
|
-
- [ ] ✅ **Best Practice 1**: Used `connectionPath` for all multi-connection queries
|
|
580
|
-
- [ ] ✅ **Best Practice 2**: Used parallel queries (`Promise.all`) for multiple full pagination
|
|
581
|
-
- [ ] ✅ **Best Practice 3**: Added separate progress monitoring with `onProgress` callbacks per connection
|
|
582
|
-
- [ ] ✅ **Best Practice 4**: Implemented error handling with `Promise.allSettled` for resilience
|
|
583
|
-
- [ ] ✅ **Best Practice 5**: Set appropriate safety limits (`maxPages`, `maxRecords`, `timeoutMs`)
|
|
584
|
-
- [ ] ✅ **Best Practice 6**: Optimized page sizes for entity complexity
|
|
585
|
-
- [ ] ✅ **Best Practice 7**: Reused client instances (not creating new clients per query)
|
|
586
|
-
- [ ] ✅ **Best Practice 8**: Used appropriate logging (native log for Versori, minimal utilities for standalone)
|
|
587
|
-
- [ ] ✅ **Best Practice 9**: Batched parallel queries (limit concurrent queries to 3-5)
|
|
588
|
-
- [ ] ✅ Included `id` field in all queries for deduplication
|
|
589
|
-
- [ ] ✅ Tested with small limits first (`maxPages: 2`)
|
|
590
|
-
- [ ] ✅ Tested edge cases (empty results, single page, errors)
|
|
591
|
-
|
|
592
|
-
## Performance Benchmarks
|
|
593
|
-
|
|
594
|
-
Based on real Fluent Commerce API testing:
|
|
595
|
-
|
|
596
|
-
| Scenario | Page Size | Pages | Records | Time | Notes |
|
|
597
|
-
|----------|-----------|-------|---------|------|-------|
|
|
598
|
-
| Virtual Positions | 200 | 50 | 10,000 | ~45s | Simple fields |
|
|
599
|
-
| Products | 100 | 50 | 5,000 | ~60s | Medium complexity |
|
|
600
|
-
| Orders (no items) | 75 | 20 | 1,500 | ~35s | Medium complexity |
|
|
601
|
-
| Orders (with items) | 30 | 20 | 600 | ~50s | High complexity |
|
|
602
|
-
|
|
603
|
-
**Parallel vs Sequential:**
|
|
604
|
-
- **Parallel** (3 queries): ~60-70s total (overlapping execution)
|
|
605
|
-
- **Sequential** (3 queries): ~140-150s total (sum of individual times)
|
|
606
|
-
|
|
607
|
-
**Speedup:** ~2-2.5x faster with parallel execution
|
|
608
|
-
|
|
609
|
-
## Key Takeaways
|
|
610
|
-
|
|
611
|
-
- 🎯 **Always use `connectionPath`** - Explicit is better than implicit (Best Practice 1)
|
|
612
|
-
- 🎯 **Parallel for multiple** - Use `Promise.all()` when all need pagination (Best Practice 2)
|
|
613
|
-
- 🎯 **Monitor progress** - Separate `onProgress` callbacks per connection (Best Practice 3)
|
|
614
|
-
- 🎯 **Handle errors gracefully** - Use `Promise.allSettled()` (Best Practice 4)
|
|
615
|
-
- 🎯 **Set safety limits** - Use OR-logic: maxPages, maxRecords, timeoutMs (Best Practice 5)
|
|
616
|
-
- 🎯 **Optimize page sizes** - Match entity complexity (Best Practice 6)
|
|
617
|
-
- 🎯 **Reuse clients** - Don't create multiple instances (Best Practice 7)
|
|
618
|
-
- 🎯 **Use appropriate logging** - Native log for Versori, minimal utilities for standalone (Best Practice 8)
|
|
619
|
-
- 🎯 **Batch parallel queries** - Limit concurrent queries to 3-5 (Best Practice 9)
|
|
620
|
-
- 🎯 **Test small first** - Verify with `maxPages: 2` before production
|
|
621
|
-
|
|
622
|
-
## Next Steps
|
|
623
|
-
|
|
624
|
-
Continue to [Module 6: API Reference](./multiple-connections-06-api-reference.md) for complete interface documentation and reference material.
|
|
1
|
+
# Module 5: Best Practices
|
|
2
|
+
|
|
3
|
+
**Level:** Advanced
|
|
4
|
+
**Estimated Time:** 25 minutes
|
|
5
|
+
|
|
6
|
+
**SDK Version:** Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This module consolidates production-ready patterns, performance optimizations, and troubleshooting techniques for multi-connection scenarios.
|
|
11
|
+
|
|
12
|
+
## Learning Objectives
|
|
13
|
+
|
|
14
|
+
By the end of this module, you will:
|
|
15
|
+
- ✅ Know when to use each multi-connection pattern
|
|
16
|
+
- ✅ Implement production-ready error handling
|
|
17
|
+
- ✅ Optimize performance for large-scale exports
|
|
18
|
+
- ✅ Debug common issues effectively
|
|
19
|
+
- ✅ Apply security and reliability best practices
|
|
20
|
+
|
|
21
|
+
## Decision Matrix: Which Pattern to Use?
|
|
22
|
+
|
|
23
|
+
### Quick Decision Tree
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Do you need ALL connections fully paginated?
|
|
27
|
+
├─ YES → Use parallel queries (Promise.all)
|
|
28
|
+
│
|
|
29
|
+
└─ NO → Do you need MORE THAN ONE connection paginated?
|
|
30
|
+
├─ YES → Use parallel queries (Promise.all)
|
|
31
|
+
│
|
|
32
|
+
└─ NO → Use single query with connectionPath
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Detailed Comparison
|
|
36
|
+
|
|
37
|
+
| Scenario | Pattern | Why |
|
|
38
|
+
|----------|---------|-----|
|
|
39
|
+
| Export all products + all locations | Parallel | Both need full pagination |
|
|
40
|
+
| Export all products + first page locations | Single + connectionPath | Only products need pagination |
|
|
41
|
+
| Export 3+ different entities | Parallel | Multiple connections need pagination |
|
|
42
|
+
| Get order with all items | Single + connectionPath | Nested connection |
|
|
43
|
+
| Export with different limits per entity | Parallel | Independent limit control |
|
|
44
|
+
|
|
45
|
+
## Best Practice 1: Always Use connectionPath
|
|
46
|
+
|
|
47
|
+
### ✅ DO: Be Explicit
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// ✅ Good - explicit and predictable
|
|
51
|
+
const result = await client.graphql({
|
|
52
|
+
query: multiConnectionQuery,
|
|
53
|
+
pagination: {
|
|
54
|
+
connectionPath: 'products',
|
|
55
|
+
maxPages: 10
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### ❌ DON'T: Rely on Auto-Detection
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// ❌ Risky - which connection gets paginated?
|
|
64
|
+
const result = await client.graphql({
|
|
65
|
+
query: multiConnectionQuery,
|
|
66
|
+
pagination: { maxPages: 10 } // Auto-detection is unpredictable
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Exception:** Only one connection exists and path is obvious.
|
|
71
|
+
|
|
72
|
+
## Best Practice 2: Use Parallel Queries for Multiple Full Pagination
|
|
73
|
+
|
|
74
|
+
### ✅ DO: Separate Queries
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// ✅ Good - parallel queries with independent configs
|
|
78
|
+
const [products, locations] = await Promise.all([
|
|
79
|
+
client.graphql({
|
|
80
|
+
query: productsQuery,
|
|
81
|
+
variables: { first: 100 },
|
|
82
|
+
pagination: { maxPages: 10, maxRecords: 1000 }
|
|
83
|
+
}),
|
|
84
|
+
client.graphql({
|
|
85
|
+
query: locationsQuery,
|
|
86
|
+
variables: { first: 50 },
|
|
87
|
+
pagination: { maxPages: 5, maxRecords: 250 }
|
|
88
|
+
})
|
|
89
|
+
]);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### ❌ DON'T: Single Query Expecting Multiple Pagination
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// ❌ Bad - only one connection will be paginated
|
|
96
|
+
const result = await client.graphql({
|
|
97
|
+
query: multiConnectionQuery,
|
|
98
|
+
pagination: {
|
|
99
|
+
connectionPath: 'products', // locations won't be paginated
|
|
100
|
+
maxPages: 10
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Best Practice 3: Monitor Progress Per Connection
|
|
106
|
+
|
|
107
|
+
### ✅ DO: Separate Progress Tracking
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
const [products, locations] = await Promise.all([
|
|
111
|
+
client.graphql({
|
|
112
|
+
query: productsQuery,
|
|
113
|
+
pagination: {
|
|
114
|
+
maxPages: 10,
|
|
115
|
+
onProgress: (page, records) => {
|
|
116
|
+
console.log(`[Products] Page ${page}: ${records} records`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
client.graphql({
|
|
121
|
+
query: locationsQuery,
|
|
122
|
+
pagination: {
|
|
123
|
+
maxPages: 5,
|
|
124
|
+
onProgress: (page, records) => {
|
|
125
|
+
console.log(`[Locations] Page ${page}: ${records} records`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
]);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### ❌ DON'T: Generic Logging
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// ❌ Bad - can't tell which connection
|
|
136
|
+
const result = await client.graphql({
|
|
137
|
+
query: multiConnectionQuery,
|
|
138
|
+
pagination: {
|
|
139
|
+
connectionPath: 'products',
|
|
140
|
+
onProgress: (page, records) => {
|
|
141
|
+
console.log(`Page ${page}: ${records}`); // Which connection?
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Best Practice 4: Use Promise.allSettled for Resilience
|
|
148
|
+
|
|
149
|
+
### ✅ DO: Handle Partial Failures
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
const results = await Promise.allSettled([
|
|
153
|
+
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
154
|
+
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } }),
|
|
155
|
+
client.graphql({ query: virtualPositionsQuery, pagination: { maxPages: 20 } })
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
const successful = results.filter(r => r.status === 'fulfilled');
|
|
159
|
+
const failed = results.filter(r => r.status === 'rejected');
|
|
160
|
+
|
|
161
|
+
console.log(`✅ Successful: ${successful.length}`);
|
|
162
|
+
console.log(`❌ Failed: ${failed.length}`);
|
|
163
|
+
|
|
164
|
+
// Process successful results
|
|
165
|
+
successful.forEach((result, index) => {
|
|
166
|
+
if (result.status === 'fulfilled') {
|
|
167
|
+
const data = result.value;
|
|
168
|
+
// Process data
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Log failures
|
|
173
|
+
failed.forEach((result, index) => {
|
|
174
|
+
if (result.status === 'rejected') {
|
|
175
|
+
console.error(`Failed query ${index}:`, result.reason);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### ❌ DON'T: Use Promise.all Without Error Handling
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// ❌ Bad - one failure loses all results
|
|
184
|
+
try {
|
|
185
|
+
const [products, locations] = await Promise.all([
|
|
186
|
+
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
187
|
+
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
188
|
+
]);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
// Both results lost if one fails
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Best Practice 5: Set Appropriate Safety Limits
|
|
195
|
+
|
|
196
|
+
### ✅ DO: Use OR-Logic Limits
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const result = await client.graphql({
|
|
200
|
+
query: productsQuery,
|
|
201
|
+
pagination: {
|
|
202
|
+
maxPages: 100, // OR
|
|
203
|
+
maxRecords: 10000, // OR
|
|
204
|
+
timeoutMs: 60000 // OR (60 seconds)
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Whichever limit is hit first stops pagination.**
|
|
210
|
+
|
|
211
|
+
### ✅ DO: Match Limits to Entity Complexity
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Simple entities - higher limits
|
|
215
|
+
const virtualPositions = await client.graphql({
|
|
216
|
+
query: virtualPositionsQuery,
|
|
217
|
+
pagination: {
|
|
218
|
+
maxPages: 200,
|
|
219
|
+
maxRecords: 20000
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Complex entities - lower limits
|
|
224
|
+
const orders = await client.graphql({
|
|
225
|
+
query: ordersWithItemsQuery,
|
|
226
|
+
pagination: {
|
|
227
|
+
maxPages: 50,
|
|
228
|
+
maxRecords: 2000
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Best Practice 6: Optimize Page Sizes
|
|
234
|
+
|
|
235
|
+
### ✅ DO: Match Page Size to Entity
|
|
236
|
+
|
|
237
|
+
| Entity Type | Recommended Page Size | Reasoning |
|
|
238
|
+
|-------------|----------------------|-----------|
|
|
239
|
+
| VirtualPositions | 200-500 | Very simple fields |
|
|
240
|
+
| Locations | 100-200 | Simple fields |
|
|
241
|
+
| Products | 50-100 | Medium complexity |
|
|
242
|
+
| Orders (no items) | 50-100 | Medium complexity |
|
|
243
|
+
| Orders (with items) | 20-50 | High complexity, nested |
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const [virtualPositions, products, orders] = await Promise.all([
|
|
247
|
+
client.graphql({
|
|
248
|
+
query: virtualPositionsQuery,
|
|
249
|
+
variables: { first: 200 }, // ← Large page size
|
|
250
|
+
pagination: { maxRecords: 10000 }
|
|
251
|
+
}),
|
|
252
|
+
client.graphql({
|
|
253
|
+
query: productsQuery,
|
|
254
|
+
variables: { first: 75 }, // ← Medium page size
|
|
255
|
+
pagination: { maxRecords: 5000 }
|
|
256
|
+
}),
|
|
257
|
+
client.graphql({
|
|
258
|
+
query: ordersQuery,
|
|
259
|
+
variables: { first: 30 }, // ← Small page size
|
|
260
|
+
pagination: { maxRecords: 1000 }
|
|
261
|
+
})
|
|
262
|
+
]);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Best Practice 7: Reuse Client Instances
|
|
266
|
+
|
|
267
|
+
### ✅ DO: Share Client
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// ✅ Good - create once, reuse
|
|
271
|
+
const client = await createClient({
|
|
272
|
+
config: {
|
|
273
|
+
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
274
|
+
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
275
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
276
|
+
username: process.env.FLUENT_USERNAME!,
|
|
277
|
+
password: process.env.FLUENT_PASSWORD!,
|
|
278
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const [products, locations, virtualPositions] = await Promise.all([
|
|
283
|
+
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
284
|
+
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } }),
|
|
285
|
+
client.graphql({ query: virtualPositionsQuery, pagination: { maxPages: 20 } })
|
|
286
|
+
]);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### ❌ DON'T: Create Multiple Clients
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// ❌ Bad - creates new auth token for each query
|
|
293
|
+
const results = await Promise.all([
|
|
294
|
+
createClient({ config: {...} }).then(c => c.graphql({ ... })),
|
|
295
|
+
createClient({ config: {...} }).then(c => c.graphql({ ... })),
|
|
296
|
+
createClient({ config: {...} }).then(c => c.graphql({ ... }))
|
|
297
|
+
]);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Best Practice 8: Use Appropriate Logging
|
|
301
|
+
|
|
302
|
+
### ✅ DO: Use Native Log in Versori
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// ✅ Versori Platform - use native log
|
|
306
|
+
import { schedule, http } from '@versori/run';
|
|
307
|
+
import { createClient } from '@fluentcommerce/fc-connect-sdk';
|
|
308
|
+
|
|
309
|
+
export const workflow = schedule('multi-export', '0 * * * *').then(
|
|
310
|
+
http('process', { connection: 'fluent' }, async (ctx) => {
|
|
311
|
+
const { log } = ctx;
|
|
312
|
+
|
|
313
|
+
// Pass native log to SDK
|
|
314
|
+
const client = await createClient(ctx); // Auto-detects Versori context
|
|
315
|
+
|
|
316
|
+
log.info('Starting parallel export');
|
|
317
|
+
const [products, locations] = await Promise.all([
|
|
318
|
+
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
319
|
+
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
log.info('Export complete', {
|
|
323
|
+
products: products.extensions.autoPagination.totalRecords,
|
|
324
|
+
locations: locations.extensions.autoPagination.totalRecords
|
|
325
|
+
});
|
|
326
|
+
})
|
|
327
|
+
);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### ✅ DO: Use Minimal Logging in Standalone
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
// ✅ Standalone Node.js/Deno - use minimal logging utilities
|
|
334
|
+
import {
|
|
335
|
+
createClient,
|
|
336
|
+
createConsoleLogger,
|
|
337
|
+
toStructuredLogger
|
|
338
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
339
|
+
|
|
340
|
+
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
341
|
+
service: 'MultiConnectionExport',
|
|
342
|
+
correlationId: 'export-123'
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
const client = await createClient({
|
|
346
|
+
config: { /* ... */ }
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
logger.info('Starting parallel export');
|
|
350
|
+
const [products, locations] = await Promise.all([
|
|
351
|
+
client.graphql({ query: productsQuery, pagination: { maxPages: 10 } }),
|
|
352
|
+
client.graphql({ query: locationsQuery, pagination: { maxPages: 5 } })
|
|
353
|
+
]);
|
|
354
|
+
|
|
355
|
+
logger.info('Export complete', {
|
|
356
|
+
products: products.extensions.autoPagination.totalRecords,
|
|
357
|
+
locations: locations.extensions.autoPagination.totalRecords
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Best Practice 9: Batch Parallel Queries
|
|
362
|
+
|
|
363
|
+
### ✅ DO: Limit Concurrent Queries
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
async function batchedParallelQueries(queries: any[], batchSize = 3) {
|
|
367
|
+
const results = [];
|
|
368
|
+
|
|
369
|
+
for (let i = 0; i < queries.length; i += batchSize) {
|
|
370
|
+
const batch = queries.slice(i, i + batchSize);
|
|
371
|
+
console.log(`Processing batch ${i / batchSize + 1}...`);
|
|
372
|
+
|
|
373
|
+
const batchResults = await Promise.all(
|
|
374
|
+
batch.map(q => client.graphql(q))
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
results.push(...batchResults);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return results;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Use it
|
|
384
|
+
const queries = [
|
|
385
|
+
{ query: productsQuery, pagination: { maxPages: 10 } },
|
|
386
|
+
{ query: locationsQuery, pagination: { maxPages: 5 } },
|
|
387
|
+
{ query: virtualPositionsQuery, pagination: { maxPages: 20 } },
|
|
388
|
+
{ query: ordersQuery, pagination: { maxPages: 15 } },
|
|
389
|
+
{ query: fulfilmentsQuery, pagination: { maxPages: 8 } }
|
|
390
|
+
];
|
|
391
|
+
|
|
392
|
+
const results = await batchedParallelQueries(queries, 3);
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### ❌ DON'T: Too Many Concurrent Queries
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// ❌ Bad - 10+ parallel queries may overwhelm API/network
|
|
399
|
+
const results = await Promise.all([...Array(10)].map(/* query */));
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Troubleshooting
|
|
403
|
+
|
|
404
|
+
### Issue 1: Only First Page Returned
|
|
405
|
+
|
|
406
|
+
**Symptoms:**
|
|
407
|
+
- `maxPages: 10` set, but only first page returned
|
|
408
|
+
- `totalPages: 1` in metadata
|
|
409
|
+
|
|
410
|
+
**Causes & Fixes:**
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// Cause 1: No $after variable in query
|
|
414
|
+
// ❌ Wrong
|
|
415
|
+
query GetProducts($first: Int!) {
|
|
416
|
+
products(first: $first) { ... } // Missing $after
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// ✅ Fix
|
|
420
|
+
query GetProducts($first: Int!, $after: String) {
|
|
421
|
+
products(first: $first, after: $after) { ... }
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Cause 2: connectionPath pointing to wrong field
|
|
425
|
+
// ❌ Wrong
|
|
426
|
+
pagination: { connectionPath: 'product' } // Typo
|
|
427
|
+
|
|
428
|
+
// ✅ Fix
|
|
429
|
+
pagination: { connectionPath: 'products' } // Correct field name
|
|
430
|
+
|
|
431
|
+
// Cause 3: No more pages available
|
|
432
|
+
// ✅ Check hasNextPage in first response
|
|
433
|
+
const firstPage = await client.graphql({
|
|
434
|
+
query,
|
|
435
|
+
variables: { first: 100 }
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
console.log(firstPage.data.products.pageInfo.hasNextPage);
|
|
439
|
+
// If false, only one page exists
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Issue 2: "Connection not found at path"
|
|
443
|
+
|
|
444
|
+
**Symptoms:**
|
|
445
|
+
- Error: "No connection found at path 'products'"
|
|
446
|
+
|
|
447
|
+
**Causes & Fixes:**
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
// Cause 1: Typo in connectionPath
|
|
451
|
+
// ❌ Wrong
|
|
452
|
+
pagination: { connectionPath: 'product' }
|
|
453
|
+
|
|
454
|
+
// ✅ Fix
|
|
455
|
+
pagination: { connectionPath: 'products' }
|
|
456
|
+
|
|
457
|
+
// Cause 2: Path doesn't match query structure
|
|
458
|
+
// ❌ Wrong
|
|
459
|
+
query { order { items { ... } } }
|
|
460
|
+
pagination: { connectionPath: 'items' }
|
|
461
|
+
|
|
462
|
+
// ✅ Fix
|
|
463
|
+
pagination: { connectionPath: 'order.items' }
|
|
464
|
+
|
|
465
|
+
// Cause 3: Using alias but targeting original name
|
|
466
|
+
// ❌ Wrong
|
|
467
|
+
query { myProducts: products { ... } }
|
|
468
|
+
pagination: { connectionPath: 'products' }
|
|
469
|
+
|
|
470
|
+
// ✅ Fix
|
|
471
|
+
pagination: { connectionPath: 'myProducts' }
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Issue 3: Slow Performance
|
|
475
|
+
|
|
476
|
+
**Symptoms:**
|
|
477
|
+
- Queries taking very long
|
|
478
|
+
- High memory usage
|
|
479
|
+
|
|
480
|
+
**Optimizations:**
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
// Optimization 1: Reduce page size for complex queries
|
|
484
|
+
// ❌ Slow
|
|
485
|
+
variables: { first: 200 } // Too large for orders with items
|
|
486
|
+
|
|
487
|
+
// ✅ Fast
|
|
488
|
+
variables: { first: 30 } // Appropriate for complex entities
|
|
489
|
+
|
|
490
|
+
// Optimization 2: Add timeoutMs limit
|
|
491
|
+
pagination: {
|
|
492
|
+
maxPages: 100,
|
|
493
|
+
timeoutMs: 60000 // ← Stop after 60 seconds
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Optimization 3: Reduce maxRecords
|
|
497
|
+
pagination: {
|
|
498
|
+
maxRecords: 5000 // ← Prevent excessive fetching
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Optimization 4: Use batching for many queries
|
|
502
|
+
await batchedParallelQueries(queries, 3); // 3 at a time
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Issue 4: Unexpected Record Counts
|
|
506
|
+
|
|
507
|
+
**Symptoms:**
|
|
508
|
+
- Getting more/fewer records than expected
|
|
509
|
+
|
|
510
|
+
**Diagnostic Steps:**
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
// Step 1: Check metadata
|
|
514
|
+
console.log(result.extensions.autoPagination);
|
|
515
|
+
// {
|
|
516
|
+
// totalPages: 8,
|
|
517
|
+
// totalRecords: 743,
|
|
518
|
+
// truncated: true // ← Hit a limit
|
|
519
|
+
// }
|
|
520
|
+
|
|
521
|
+
// Step 2: Check which limit was hit
|
|
522
|
+
if (result.extensions.autoPagination.truncated) {
|
|
523
|
+
// Check configured limits
|
|
524
|
+
console.log('Configured limits:', {
|
|
525
|
+
maxPages: 10,
|
|
526
|
+
maxRecords: 1000,
|
|
527
|
+
timeoutMs: 30000
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// If totalPages < maxPages, likely hit maxRecords or timeoutMs
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Step 3: Verify page size
|
|
534
|
+
const { totalRecords, totalPages } = result.extensions.autoPagination;
|
|
535
|
+
const avgPageSize = totalRecords / totalPages;
|
|
536
|
+
console.log(`Average page size: ${avgPageSize}`);
|
|
537
|
+
// Should match variables.first (approximately)
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Issue 5: Deduplication Issues
|
|
541
|
+
|
|
542
|
+
**Symptoms:**
|
|
543
|
+
- Seeing duplicate records
|
|
544
|
+
- Record count higher than expected
|
|
545
|
+
|
|
546
|
+
**Causes & Fixes:**
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
// Cause: Entities don't have 'id' field
|
|
550
|
+
// ❌ Missing id
|
|
551
|
+
query GetProducts($first: Int!, $after: String) {
|
|
552
|
+
products(first: $first, after: $after) {
|
|
553
|
+
edges {
|
|
554
|
+
node { ref type } // ← No 'id' field
|
|
555
|
+
cursor
|
|
556
|
+
}
|
|
557
|
+
pageInfo { hasNextPage }
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// ✅ Include id for deduplication
|
|
562
|
+
query GetProducts($first: Int!, $after: String) {
|
|
563
|
+
products(first: $first, after: $after) {
|
|
564
|
+
edges {
|
|
565
|
+
node { id ref type } // ← Include 'id'
|
|
566
|
+
cursor
|
|
567
|
+
}
|
|
568
|
+
pageInfo { hasNextPage }
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
**Note:** SDK deduplicates by `id` field automatically. Always include `id` in your queries.
|
|
574
|
+
|
|
575
|
+
## Production Checklist
|
|
576
|
+
|
|
577
|
+
Before deploying multi-connection pagination:
|
|
578
|
+
|
|
579
|
+
- [ ] ✅ **Best Practice 1**: Used `connectionPath` for all multi-connection queries
|
|
580
|
+
- [ ] ✅ **Best Practice 2**: Used parallel queries (`Promise.all`) for multiple full pagination
|
|
581
|
+
- [ ] ✅ **Best Practice 3**: Added separate progress monitoring with `onProgress` callbacks per connection
|
|
582
|
+
- [ ] ✅ **Best Practice 4**: Implemented error handling with `Promise.allSettled` for resilience
|
|
583
|
+
- [ ] ✅ **Best Practice 5**: Set appropriate safety limits (`maxPages`, `maxRecords`, `timeoutMs`)
|
|
584
|
+
- [ ] ✅ **Best Practice 6**: Optimized page sizes for entity complexity
|
|
585
|
+
- [ ] ✅ **Best Practice 7**: Reused client instances (not creating new clients per query)
|
|
586
|
+
- [ ] ✅ **Best Practice 8**: Used appropriate logging (native log for Versori, minimal utilities for standalone)
|
|
587
|
+
- [ ] ✅ **Best Practice 9**: Batched parallel queries (limit concurrent queries to 3-5)
|
|
588
|
+
- [ ] ✅ Included `id` field in all queries for deduplication
|
|
589
|
+
- [ ] ✅ Tested with small limits first (`maxPages: 2`)
|
|
590
|
+
- [ ] ✅ Tested edge cases (empty results, single page, errors)
|
|
591
|
+
|
|
592
|
+
## Performance Benchmarks
|
|
593
|
+
|
|
594
|
+
Based on real Fluent Commerce API testing:
|
|
595
|
+
|
|
596
|
+
| Scenario | Page Size | Pages | Records | Time | Notes |
|
|
597
|
+
|----------|-----------|-------|---------|------|-------|
|
|
598
|
+
| Virtual Positions | 200 | 50 | 10,000 | ~45s | Simple fields |
|
|
599
|
+
| Products | 100 | 50 | 5,000 | ~60s | Medium complexity |
|
|
600
|
+
| Orders (no items) | 75 | 20 | 1,500 | ~35s | Medium complexity |
|
|
601
|
+
| Orders (with items) | 30 | 20 | 600 | ~50s | High complexity |
|
|
602
|
+
|
|
603
|
+
**Parallel vs Sequential:**
|
|
604
|
+
- **Parallel** (3 queries): ~60-70s total (overlapping execution)
|
|
605
|
+
- **Sequential** (3 queries): ~140-150s total (sum of individual times)
|
|
606
|
+
|
|
607
|
+
**Speedup:** ~2-2.5x faster with parallel execution
|
|
608
|
+
|
|
609
|
+
## Key Takeaways
|
|
610
|
+
|
|
611
|
+
- 🎯 **Always use `connectionPath`** - Explicit is better than implicit (Best Practice 1)
|
|
612
|
+
- 🎯 **Parallel for multiple** - Use `Promise.all()` when all need pagination (Best Practice 2)
|
|
613
|
+
- 🎯 **Monitor progress** - Separate `onProgress` callbacks per connection (Best Practice 3)
|
|
614
|
+
- 🎯 **Handle errors gracefully** - Use `Promise.allSettled()` (Best Practice 4)
|
|
615
|
+
- 🎯 **Set safety limits** - Use OR-logic: maxPages, maxRecords, timeoutMs (Best Practice 5)
|
|
616
|
+
- 🎯 **Optimize page sizes** - Match entity complexity (Best Practice 6)
|
|
617
|
+
- 🎯 **Reuse clients** - Don't create multiple instances (Best Practice 7)
|
|
618
|
+
- 🎯 **Use appropriate logging** - Native log for Versori, minimal utilities for standalone (Best Practice 8)
|
|
619
|
+
- 🎯 **Batch parallel queries** - Limit concurrent queries to 3-5 (Best Practice 9)
|
|
620
|
+
- 🎯 **Test small first** - Verify with `maxPages: 2` before production
|
|
621
|
+
|
|
622
|
+
## Next Steps
|
|
623
|
+
|
|
624
|
+
Continue to [Module 6: API Reference](./multiple-connections-06-api-reference.md) for complete interface documentation and reference material.
|