@fluentcommerce/fc-connect-sdk 0.1.53 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -2
- package/README.md +39 -0
- package/dist/cjs/auth/index.d.ts +3 -0
- package/dist/cjs/auth/index.js +13 -0
- package/dist/cjs/auth/profile-loader.d.ts +18 -0
- package/dist/cjs/auth/profile-loader.js +208 -0
- package/dist/cjs/client-factory.d.ts +4 -0
- package/dist/cjs/client-factory.js +10 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/auth/index.d.ts +3 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/profile-loader.d.ts +18 -0
- package/dist/esm/auth/profile-loader.js +169 -0
- package/dist/esm/client-factory.d.ts +4 -0
- package/dist/esm/client-factory.js +9 -0
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/auth/index.d.ts +3 -0
- package/dist/types/auth/profile-loader.d.ts +18 -0
- package/dist/types/client-factory.d.ts +4 -0
- package/dist/types/index.d.ts +3 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -482
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md
CHANGED
|
@@ -1,567 +1,567 @@
|
|
|
1
|
-
# Module 7: Testing & Troubleshooting
|
|
2
|
-
|
|
3
|
-
**Level:** Intermediate
|
|
4
|
-
**Estimated Time:** 20 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
Learn about test coverage for file operations and how to troubleshoot common issues.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Understand test coverage for S3 and SFTP operations
|
|
14
|
-
- ✅ Run and interpret test results
|
|
15
|
-
- ✅ Troubleshoot common file operation errors
|
|
16
|
-
- ✅ Debug connection and permission issues
|
|
17
|
-
|
|
18
|
-
## Test Coverage
|
|
19
|
-
|
|
20
|
-
### S3 Test Coverage
|
|
21
|
-
|
|
22
|
-
**Unit Tests**: `tests/unit/s3-data-source.test.ts`
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
describe('S3DataSource', () => {
|
|
26
|
-
describe('listFiles', () => {
|
|
27
|
-
it('should list all files in bucket', async () => { ... });
|
|
28
|
-
it('should filter by prefix', async () => { ... });
|
|
29
|
-
it('should filter by pattern', async () => { ... });
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('downloadFile', () => {
|
|
33
|
-
it('should download file successfully', async () => { ... });
|
|
34
|
-
it('should handle file not found errors', async () => { ... });
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
describe('uploadFile', () => {
|
|
38
|
-
it('should upload string content', async () => { ... });
|
|
39
|
-
it('should upload buffer content', async () => { ... });
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe('moveFile', () => {
|
|
43
|
-
it('should move file (copy + delete)', async () => { ... });
|
|
44
|
-
it('should handle move errors', async () => { ... });
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('copyFile', () => {
|
|
48
|
-
it('should copy file successfully', async () => { ... });
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('deleteFile', () => {
|
|
52
|
-
it('should delete file successfully', async () => { ... });
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Service Tests**: `tests/unit/services/s3/s3-service.test.ts`
|
|
58
|
-
|
|
59
|
-
### SFTP Test Coverage
|
|
60
|
-
|
|
61
|
-
**Unit Tests**: `tests/unit/data-sources/sftp-data-source.test.ts`
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
describe('SftpDataSource', () => {
|
|
65
|
-
describe('listFiles', () => {
|
|
66
|
-
it('should list files matching pattern', async () => { ... });
|
|
67
|
-
it('should handle empty directory', async () => { ... });
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe('downloadFile', () => {
|
|
71
|
-
it('should download file successfully', async () => { ... });
|
|
72
|
-
it('should handle file not found errors', async () => { ... });
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe('uploadContent', () => {
|
|
76
|
-
it('should upload content successfully', async () => { ... });
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
describe('moveFile', () => {
|
|
80
|
-
it('should move file successfully', async () => { ... });
|
|
81
|
-
it('should create directories if specified', async () => { ... });
|
|
82
|
-
it('should handle move errors', async () => { ... });
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('copyFile', () => {
|
|
86
|
-
it('should copy file successfully', async () => { ... });
|
|
87
|
-
it('should handle copy errors', async () => { ... });
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('deleteFile', () => {
|
|
91
|
-
it('should delete file successfully', async () => { ... });
|
|
92
|
-
it('should handle file not found errors', async () => { ... });
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Integration Tests**: `tests/integration/sftp-data-source.integration.test.ts`
|
|
98
|
-
|
|
99
|
-
### Running Tests
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
cd fc-connect-sdk
|
|
103
|
-
|
|
104
|
-
# Run all tests
|
|
105
|
-
npm test
|
|
106
|
-
|
|
107
|
-
# Run with coverage
|
|
108
|
-
npm run test:coverage
|
|
109
|
-
|
|
110
|
-
# Run S3 tests only
|
|
111
|
-
npm test -- tests/unit/s3-data-source.test.ts
|
|
112
|
-
npm test -- tests/unit/services/s3/
|
|
113
|
-
|
|
114
|
-
# Run SFTP tests only
|
|
115
|
-
npm test -- tests/unit/data-sources/sftp-data-source.test.ts
|
|
116
|
-
|
|
117
|
-
# Run SFTP integration tests (requires .env)
|
|
118
|
-
npm test -- tests/integration/sftp-data-source.integration.test.ts
|
|
119
|
-
|
|
120
|
-
# Run specific test
|
|
121
|
-
npm test -- --testNamePattern="should download file successfully"
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Test Coverage Thresholds
|
|
125
|
-
|
|
126
|
-
```javascript
|
|
127
|
-
// jest.config.js
|
|
128
|
-
coverageThreshold: {
|
|
129
|
-
global: {
|
|
130
|
-
branches: 70,
|
|
131
|
-
functions: 70,
|
|
132
|
-
lines: 70,
|
|
133
|
-
statements: 70
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Common Errors & Solutions
|
|
139
|
-
|
|
140
|
-
### S3 Errors
|
|
141
|
-
|
|
142
|
-
#### NoSuchKey Error
|
|
143
|
-
|
|
144
|
-
**Error:**
|
|
145
|
-
```
|
|
146
|
-
NoSuchKey: The specified key does not exist.
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
**Causes:**
|
|
150
|
-
- File doesn't exist at the specified key
|
|
151
|
-
- Typo in file path
|
|
152
|
-
- File was deleted
|
|
153
|
-
|
|
154
|
-
**Solutions:**
|
|
155
|
-
```typescript
|
|
156
|
-
// Check if file exists before downloading
|
|
157
|
-
if (await s3.fileExists('path/to/file.csv')) {
|
|
158
|
-
const content = await s3.downloadFile('path/to/file.csv');
|
|
159
|
-
} else {
|
|
160
|
-
console.log('File does not exist');
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// List files to verify path
|
|
164
|
-
const files = await s3.listFiles({ prefix: 'path/to/' });
|
|
165
|
-
files.forEach(f => console.log(f.name));
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
#### AccessDenied Error
|
|
169
|
-
|
|
170
|
-
**Error:**
|
|
171
|
-
```
|
|
172
|
-
AccessDenied: Access Denied
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Causes:**
|
|
176
|
-
- IAM policy doesn't allow operation
|
|
177
|
-
- Bucket policy blocks access
|
|
178
|
-
- Wrong AWS credentials
|
|
179
|
-
|
|
180
|
-
**Solutions:**
|
|
181
|
-
```typescript
|
|
182
|
-
// Verify IAM policy has required permissions:
|
|
183
|
-
// - s3:GetObject (download)
|
|
184
|
-
// - s3:PutObject (upload)
|
|
185
|
-
// - s3:DeleteObject (delete/move)
|
|
186
|
-
// - s3:ListBucket (list)
|
|
187
|
-
|
|
188
|
-
// Check credentials
|
|
189
|
-
console.log('Access Key ID:', process.env.AWS_ACCESS_KEY_ID?.substring(0, 8) + '...');
|
|
190
|
-
console.log('Region:', process.env.AWS_REGION);
|
|
191
|
-
console.log('Bucket:', process.env.S3_BUCKET);
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
#### InvalidBucketName Error
|
|
195
|
-
|
|
196
|
-
**Error:**
|
|
197
|
-
```
|
|
198
|
-
InvalidBucketName: The specified bucket is not valid.
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**Causes:**
|
|
202
|
-
- Bucket name contains invalid characters
|
|
203
|
-
- Bucket name doesn't exist
|
|
204
|
-
- Wrong region
|
|
205
|
-
|
|
206
|
-
**Solutions:**
|
|
207
|
-
```typescript
|
|
208
|
-
// Verify bucket name
|
|
209
|
-
const bucketName = process.env.S3_BUCKET;
|
|
210
|
-
console.log('Bucket name:', bucketName);
|
|
211
|
-
|
|
212
|
-
// Check bucket exists in correct region
|
|
213
|
-
const s3 = new S3DataSource({
|
|
214
|
-
s3Config: {
|
|
215
|
-
region: 'us-east-1', // Must match bucket region!
|
|
216
|
-
credentials: {...}
|
|
217
|
-
},
|
|
218
|
-
bucketName
|
|
219
|
-
}, logger);
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### SFTP Errors
|
|
223
|
-
|
|
224
|
-
#### Connection Timeout
|
|
225
|
-
|
|
226
|
-
**Error:**
|
|
227
|
-
```
|
|
228
|
-
Error: Timed out while waiting for handshake
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**Causes:**
|
|
232
|
-
- Wrong host or port
|
|
233
|
-
- Firewall blocking connection
|
|
234
|
-
- SFTP server down
|
|
235
|
-
|
|
236
|
-
**Solutions:**
|
|
237
|
-
```typescript
|
|
238
|
-
// Verify connection details
|
|
239
|
-
console.log('Host:', process.env.SFTP_HOST);
|
|
240
|
-
console.log('Port:', process.env.SFTP_PORT);
|
|
241
|
-
|
|
242
|
-
// Test with increased timeout
|
|
243
|
-
const sftp = new SftpDataSource({
|
|
244
|
-
settings: {
|
|
245
|
-
host: process.env.SFTP_HOST!,
|
|
246
|
-
port: parseInt(process.env.SFTP_PORT || '22'),
|
|
247
|
-
username: process.env.SFTP_USERNAME!,
|
|
248
|
-
password: process.env.SFTP_PASSWORD!,
|
|
249
|
-
connectTimeout: 60000 // 60 seconds
|
|
250
|
-
}
|
|
251
|
-
}, logger);
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
#### Authentication Failed
|
|
255
|
-
|
|
256
|
-
**Error:**
|
|
257
|
-
```
|
|
258
|
-
Error: All configured authentication methods failed
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Causes:**
|
|
262
|
-
- Wrong username or password
|
|
263
|
-
- Key-based auth misconfigured
|
|
264
|
-
- Account locked
|
|
265
|
-
|
|
266
|
-
**Solutions:**
|
|
267
|
-
```typescript
|
|
268
|
-
// Verify credentials
|
|
269
|
-
console.log('Username:', process.env.SFTP_USERNAME);
|
|
270
|
-
console.log('Password length:', process.env.SFTP_PASSWORD?.length);
|
|
271
|
-
|
|
272
|
-
// Try key-based auth
|
|
273
|
-
import * as fs from 'fs';
|
|
274
|
-
const privateKey = fs.readFileSync('/path/to/key.pem', 'utf-8');
|
|
275
|
-
|
|
276
|
-
const sftp = new SftpDataSource({
|
|
277
|
-
settings: {
|
|
278
|
-
host: process.env.SFTP_HOST!,
|
|
279
|
-
username: process.env.SFTP_USERNAME!,
|
|
280
|
-
privateKey: privateKey,
|
|
281
|
-
passphrase: process.env.KEY_PASSPHRASE
|
|
282
|
-
}
|
|
283
|
-
}, logger);
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
#### No Such File
|
|
287
|
-
|
|
288
|
-
**Error:**
|
|
289
|
-
```
|
|
290
|
-
Error: No such file
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**Causes:**
|
|
294
|
-
- File doesn't exist
|
|
295
|
-
- Wrong path (relative vs absolute)
|
|
296
|
-
- Path typo
|
|
297
|
-
|
|
298
|
-
**Solutions:**
|
|
299
|
-
```typescript
|
|
300
|
-
// Use absolute paths with leading slash
|
|
301
|
-
const content = await sftp.downloadFile('/data/file.csv'); // ✅
|
|
302
|
-
// NOT: sftp.downloadFile('data/file.csv'); // ❌
|
|
303
|
-
|
|
304
|
-
// List files to verify path
|
|
305
|
-
const files = await sftp.listFiles();
|
|
306
|
-
files.forEach(f => console.log('Path:', f.path));
|
|
307
|
-
|
|
308
|
-
// Check existence before download
|
|
309
|
-
if (await sftp.fileExists('/data/file.csv')) {
|
|
310
|
-
const content = await sftp.downloadFile('/data/file.csv');
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
#### Permission Denied
|
|
315
|
-
|
|
316
|
-
**Error:**
|
|
317
|
-
```
|
|
318
|
-
Error: Permission denied
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**Causes:**
|
|
322
|
-
- User doesn't have read/write permissions
|
|
323
|
-
- Parent directory not writable
|
|
324
|
-
- File owned by different user
|
|
325
|
-
|
|
326
|
-
**Solutions:**
|
|
327
|
-
```typescript
|
|
328
|
-
// Verify permissions on SFTP server
|
|
329
|
-
// Use createDirs flag when moving to new folders
|
|
330
|
-
await sftp.moveFile(
|
|
331
|
-
'/source/file.csv',
|
|
332
|
-
'/archive/2025/01/file.csv',
|
|
333
|
-
true // Create directories with proper permissions
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
// Check user permissions with SFTP admin
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### General Debugging Tips
|
|
340
|
-
|
|
341
|
-
#### Enable Debug Logging
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
import {
|
|
345
|
-
createConsoleLogger,
|
|
346
|
-
toStructuredLogger
|
|
347
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
348
|
-
|
|
349
|
-
const logger = createConsoleLogger();
|
|
350
|
-
logger.setLevel('debug'); // Show all debug messages
|
|
351
|
-
|
|
352
|
-
const s3 = new S3DataSource(config, logger);
|
|
353
|
-
|
|
354
|
-
// Now all operations will log details
|
|
355
|
-
const files = await s3.listFiles();
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
#### SFTP Connection Pooling
|
|
359
|
-
|
|
360
|
-
The SDK automatically manages SFTP connection pooling for better performance:
|
|
361
|
-
|
|
362
|
-
```typescript
|
|
363
|
-
const sftp = new SftpDataSource({
|
|
364
|
-
type: 'SFTP_CSV',
|
|
365
|
-
connectionId: 'sftp-pooled',
|
|
366
|
-
name: 'SFTP with Connection Pool',
|
|
367
|
-
settings: {
|
|
368
|
-
host: 'sftp.example.com',
|
|
369
|
-
username: 'user',
|
|
370
|
-
password: 'pass',
|
|
371
|
-
maxConnections: 5, // Pool size (default: 5)
|
|
372
|
-
connectionWaitTimeout: 30000 // Wait for available connection (default: 30s)
|
|
373
|
-
}
|
|
374
|
-
}, logger);
|
|
375
|
-
|
|
376
|
-
// Connections are automatically reused from pool
|
|
377
|
-
for (let i = 0; i < 100; i++) {
|
|
378
|
-
await sftp.downloadFile(`/data/file${i}.csv`); // Reuses connections
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// IMPORTANT: Always dispose to close all pooled connections
|
|
382
|
-
await sftp.dispose();
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**Connection Pool Features:**
|
|
386
|
-
- **Automatic Reuse**: Connections are returned to pool after each operation
|
|
387
|
-
- **Health Checks**: Unhealthy connections are removed and replaced
|
|
388
|
-
- **Wait Queue**: Requests wait for available connection when pool is exhausted
|
|
389
|
-
- **Concurrent Operations**: Multiple operations can share pooled connections
|
|
390
|
-
|
|
391
|
-
**Tuning Connection Pool:**
|
|
392
|
-
```typescript
|
|
393
|
-
// High-concurrency workflow (many parallel operations)
|
|
394
|
-
settings: {
|
|
395
|
-
maxConnections: 10, // Increase pool size
|
|
396
|
-
connectionWaitTimeout: 60000 // Longer wait for busy systems
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Low-concurrency workflow (sequential operations)
|
|
400
|
-
settings: {
|
|
401
|
-
maxConnections: 2, // Smaller pool
|
|
402
|
-
connectionWaitTimeout: 15000 // Shorter timeout
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### Connection Leak Detection
|
|
407
|
-
|
|
408
|
-
```typescript
|
|
409
|
-
// ❌ BAD: Connection not disposed
|
|
410
|
-
const sftp = new SftpDataSource(config, logger);
|
|
411
|
-
await sftp.downloadFile('/file.csv');
|
|
412
|
-
// Missing dispose() - ALL pooled connections leak!
|
|
413
|
-
|
|
414
|
-
// ✅ GOOD: Always dispose
|
|
415
|
-
const sftp = new SftpDataSource(config, logger);
|
|
416
|
-
try {
|
|
417
|
-
await sftp.downloadFile('/file.csv');
|
|
418
|
-
} finally {
|
|
419
|
-
await sftp.dispose(); // Closes ALL pooled connections
|
|
420
|
-
}
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
#### Built-in Retry Logic
|
|
424
|
-
|
|
425
|
-
**SFTP** and **S3** both have built-in retry logic with exponential backoff:
|
|
426
|
-
|
|
427
|
-
**SFTP Automatic Retries:**
|
|
428
|
-
```typescript
|
|
429
|
-
const sftp = new SftpDataSource({
|
|
430
|
-
type: 'SFTP_CSV',
|
|
431
|
-
connectionId: 'sftp-retry',
|
|
432
|
-
name: 'SFTP with Retry',
|
|
433
|
-
settings: {
|
|
434
|
-
host: 'sftp.example.com',
|
|
435
|
-
username: 'user',
|
|
436
|
-
password: 'pass',
|
|
437
|
-
retry: {
|
|
438
|
-
maxAttempts: 3, // Number of retry attempts (default: 3)
|
|
439
|
-
baseDelayMs: 1000, // Initial delay (default: 1000ms)
|
|
440
|
-
backoffFactor: 2, // Exponential multiplier (default: 2)
|
|
441
|
-
maxDelayMs: 8000, // Max delay cap (default: 8000ms)
|
|
442
|
-
jitter: 'full', // Adds randomness to prevent thundering herd
|
|
443
|
-
reconnectOnFailure: true // Reconnect on connection errors
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}, logger);
|
|
447
|
-
|
|
448
|
-
// All operations automatically retry on transient errors
|
|
449
|
-
await sftp.downloadFile('/data/file.csv'); // Retries if network fails
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
**How Exponential Backoff Works:**
|
|
453
|
-
- Attempt 1: Immediate (0ms delay)
|
|
454
|
-
- Attempt 2: 1000ms delay (base)
|
|
455
|
-
- Attempt 3: 2000ms delay (base × 2)
|
|
456
|
-
- Attempt 4: 4000ms delay (base × 4)
|
|
457
|
-
- Jitter: Adds random variance (±50%) to prevent multiple clients retrying simultaneously
|
|
458
|
-
|
|
459
|
-
**S3 Automatic Retries:**
|
|
460
|
-
```typescript
|
|
461
|
-
const s3 = new S3DataSource({
|
|
462
|
-
type: 'S3_CSV',
|
|
463
|
-
connectionId: 's3-retry',
|
|
464
|
-
name: 'S3 with Retry',
|
|
465
|
-
s3Config: {
|
|
466
|
-
region: 'us-east-1',
|
|
467
|
-
bucket: 'my-bucket',
|
|
468
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
469
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
470
|
-
maxAttempts: 3 // AWS SDK handles retry logic
|
|
471
|
-
}
|
|
472
|
-
}, logger);
|
|
473
|
-
|
|
474
|
-
// S3 automatically retries on:
|
|
475
|
-
// - 500, 502, 503, 504 HTTP errors
|
|
476
|
-
// - Connection timeouts
|
|
477
|
-
// - Network errors
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
**Retryable vs Non-Retryable Errors:**
|
|
481
|
-
|
|
482
|
-
✅ **Automatically Retried:**
|
|
483
|
-
- Network timeouts
|
|
484
|
-
- Connection refused
|
|
485
|
-
- DNS resolution failures
|
|
486
|
-
- 500 Internal Server Error
|
|
487
|
-
- 502 Bad Gateway
|
|
488
|
-
- 503 Service Unavailable
|
|
489
|
-
- 504 Gateway Timeout
|
|
490
|
-
|
|
491
|
-
❌ **NOT Retried (fail immediately):**
|
|
492
|
-
- File not found (404, NoSuchKey)
|
|
493
|
-
- Permission denied (403, AccessDenied)
|
|
494
|
-
- Invalid credentials (401)
|
|
495
|
-
- File already exists (when overwrite=false)
|
|
496
|
-
- Invalid path/filename
|
|
497
|
-
|
|
498
|
-
#### Network Issues
|
|
499
|
-
|
|
500
|
-
**Built-in retry handles most cases automatically**, but you can add custom logic:
|
|
501
|
-
|
|
502
|
-
```typescript
|
|
503
|
-
// Custom retry logic (only if needed beyond built-in retries)
|
|
504
|
-
async function downloadWithRetry(
|
|
505
|
-
dataSource: S3DataSource | SftpDataSource,
|
|
506
|
-
path: string,
|
|
507
|
-
maxRetries = 3
|
|
508
|
-
): Promise<string> {
|
|
509
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
510
|
-
try {
|
|
511
|
-
return await dataSource.downloadFile(path);
|
|
512
|
-
} catch (error: any) {
|
|
513
|
-
// Don't retry if file doesn't exist
|
|
514
|
-
if (error.name === 'NoSuchKey' || error.message.includes('No such file')) {
|
|
515
|
-
throw error;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
if (attempt === maxRetries) throw error;
|
|
519
|
-
|
|
520
|
-
const delay = Math.pow(2, attempt) * 1000;
|
|
521
|
-
console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
|
|
522
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
throw new Error('Should not reach here');
|
|
526
|
-
}
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
## Troubleshooting Checklist
|
|
530
|
-
|
|
531
|
-
### S3 Issues
|
|
532
|
-
|
|
533
|
-
- [ ] Verify AWS credentials are set
|
|
534
|
-
- [ ] Check bucket name is correct
|
|
535
|
-
- [ ] Verify region matches bucket region
|
|
536
|
-
- [ ] Confirm IAM policy has required permissions
|
|
537
|
-
- [ ] Check file path (no leading slash for S3)
|
|
538
|
-
- [ ] Verify network connectivity to AWS
|
|
539
|
-
|
|
540
|
-
### SFTP Issues
|
|
541
|
-
|
|
542
|
-
- [ ] Verify host and port are correct
|
|
543
|
-
- [ ] Check username and password/key
|
|
544
|
-
- [ ] Confirm firewall allows SFTP traffic
|
|
545
|
-
- [ ] Use absolute paths (with leading slash)
|
|
546
|
-
- [ ] Always call `dispose()` in `finally` block
|
|
547
|
-
- [ ] Check SFTP server is running
|
|
548
|
-
|
|
549
|
-
## Key Takeaways
|
|
550
|
-
|
|
551
|
-
- 🎯 SDK has comprehensive test coverage (≥70%)
|
|
552
|
-
- 🎯 Run `npm test` to verify all operations work
|
|
553
|
-
- 🎯 Use integration tests for SFTP with real credentials
|
|
554
|
-
- 🎯 Enable debug logging to troubleshoot issues
|
|
555
|
-
- 🎯 Always handle NoSuchKey/NoSuchFile errors
|
|
556
|
-
- 🎯 Use retry logic for transient network errors
|
|
557
|
-
- 🎯 Check permissions for AccessDenied errors
|
|
558
|
-
|
|
559
|
-
## Next Steps
|
|
560
|
-
|
|
561
|
-
Continue to [Module 8: API Reference](../../error-handling/modules/error-handling-08-api-reference.md) for complete method signatures.
|
|
562
|
-
|
|
563
|
-
---
|
|
564
|
-
|
|
565
|
-
**Related Resources:**
|
|
566
|
-
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Error handling examples
|
|
567
|
-
- [Test Files](../../../../tests/) - Browse actual test implementations
|
|
1
|
+
# Module 7: Testing & Troubleshooting
|
|
2
|
+
|
|
3
|
+
**Level:** Intermediate
|
|
4
|
+
**Estimated Time:** 20 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Learn about test coverage for file operations and how to troubleshoot common issues.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Understand test coverage for S3 and SFTP operations
|
|
14
|
+
- ✅ Run and interpret test results
|
|
15
|
+
- ✅ Troubleshoot common file operation errors
|
|
16
|
+
- ✅ Debug connection and permission issues
|
|
17
|
+
|
|
18
|
+
## Test Coverage
|
|
19
|
+
|
|
20
|
+
### S3 Test Coverage
|
|
21
|
+
|
|
22
|
+
**Unit Tests**: `tests/unit/s3-data-source.test.ts`
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
describe('S3DataSource', () => {
|
|
26
|
+
describe('listFiles', () => {
|
|
27
|
+
it('should list all files in bucket', async () => { ... });
|
|
28
|
+
it('should filter by prefix', async () => { ... });
|
|
29
|
+
it('should filter by pattern', async () => { ... });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('downloadFile', () => {
|
|
33
|
+
it('should download file successfully', async () => { ... });
|
|
34
|
+
it('should handle file not found errors', async () => { ... });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('uploadFile', () => {
|
|
38
|
+
it('should upload string content', async () => { ... });
|
|
39
|
+
it('should upload buffer content', async () => { ... });
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('moveFile', () => {
|
|
43
|
+
it('should move file (copy + delete)', async () => { ... });
|
|
44
|
+
it('should handle move errors', async () => { ... });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('copyFile', () => {
|
|
48
|
+
it('should copy file successfully', async () => { ... });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('deleteFile', () => {
|
|
52
|
+
it('should delete file successfully', async () => { ... });
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Service Tests**: `tests/unit/services/s3/s3-service.test.ts`
|
|
58
|
+
|
|
59
|
+
### SFTP Test Coverage
|
|
60
|
+
|
|
61
|
+
**Unit Tests**: `tests/unit/data-sources/sftp-data-source.test.ts`
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
describe('SftpDataSource', () => {
|
|
65
|
+
describe('listFiles', () => {
|
|
66
|
+
it('should list files matching pattern', async () => { ... });
|
|
67
|
+
it('should handle empty directory', async () => { ... });
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('downloadFile', () => {
|
|
71
|
+
it('should download file successfully', async () => { ... });
|
|
72
|
+
it('should handle file not found errors', async () => { ... });
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('uploadContent', () => {
|
|
76
|
+
it('should upload content successfully', async () => { ... });
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('moveFile', () => {
|
|
80
|
+
it('should move file successfully', async () => { ... });
|
|
81
|
+
it('should create directories if specified', async () => { ... });
|
|
82
|
+
it('should handle move errors', async () => { ... });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('copyFile', () => {
|
|
86
|
+
it('should copy file successfully', async () => { ... });
|
|
87
|
+
it('should handle copy errors', async () => { ... });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('deleteFile', () => {
|
|
91
|
+
it('should delete file successfully', async () => { ... });
|
|
92
|
+
it('should handle file not found errors', async () => { ... });
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Integration Tests**: `tests/integration/sftp-data-source.integration.test.ts`
|
|
98
|
+
|
|
99
|
+
### Running Tests
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cd fc-connect-sdk
|
|
103
|
+
|
|
104
|
+
# Run all tests
|
|
105
|
+
npm test
|
|
106
|
+
|
|
107
|
+
# Run with coverage
|
|
108
|
+
npm run test:coverage
|
|
109
|
+
|
|
110
|
+
# Run S3 tests only
|
|
111
|
+
npm test -- tests/unit/s3-data-source.test.ts
|
|
112
|
+
npm test -- tests/unit/services/s3/
|
|
113
|
+
|
|
114
|
+
# Run SFTP tests only
|
|
115
|
+
npm test -- tests/unit/data-sources/sftp-data-source.test.ts
|
|
116
|
+
|
|
117
|
+
# Run SFTP integration tests (requires .env)
|
|
118
|
+
npm test -- tests/integration/sftp-data-source.integration.test.ts
|
|
119
|
+
|
|
120
|
+
# Run specific test
|
|
121
|
+
npm test -- --testNamePattern="should download file successfully"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Test Coverage Thresholds
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// jest.config.js
|
|
128
|
+
coverageThreshold: {
|
|
129
|
+
global: {
|
|
130
|
+
branches: 70,
|
|
131
|
+
functions: 70,
|
|
132
|
+
lines: 70,
|
|
133
|
+
statements: 70
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Common Errors & Solutions
|
|
139
|
+
|
|
140
|
+
### S3 Errors
|
|
141
|
+
|
|
142
|
+
#### NoSuchKey Error
|
|
143
|
+
|
|
144
|
+
**Error:**
|
|
145
|
+
```
|
|
146
|
+
NoSuchKey: The specified key does not exist.
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Causes:**
|
|
150
|
+
- File doesn't exist at the specified key
|
|
151
|
+
- Typo in file path
|
|
152
|
+
- File was deleted
|
|
153
|
+
|
|
154
|
+
**Solutions:**
|
|
155
|
+
```typescript
|
|
156
|
+
// Check if file exists before downloading
|
|
157
|
+
if (await s3.fileExists('path/to/file.csv')) {
|
|
158
|
+
const content = await s3.downloadFile('path/to/file.csv');
|
|
159
|
+
} else {
|
|
160
|
+
console.log('File does not exist');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// List files to verify path
|
|
164
|
+
const files = await s3.listFiles({ prefix: 'path/to/' });
|
|
165
|
+
files.forEach(f => console.log(f.name));
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### AccessDenied Error
|
|
169
|
+
|
|
170
|
+
**Error:**
|
|
171
|
+
```
|
|
172
|
+
AccessDenied: Access Denied
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Causes:**
|
|
176
|
+
- IAM policy doesn't allow operation
|
|
177
|
+
- Bucket policy blocks access
|
|
178
|
+
- Wrong AWS credentials
|
|
179
|
+
|
|
180
|
+
**Solutions:**
|
|
181
|
+
```typescript
|
|
182
|
+
// Verify IAM policy has required permissions:
|
|
183
|
+
// - s3:GetObject (download)
|
|
184
|
+
// - s3:PutObject (upload)
|
|
185
|
+
// - s3:DeleteObject (delete/move)
|
|
186
|
+
// - s3:ListBucket (list)
|
|
187
|
+
|
|
188
|
+
// Check credentials
|
|
189
|
+
console.log('Access Key ID:', process.env.AWS_ACCESS_KEY_ID?.substring(0, 8) + '...');
|
|
190
|
+
console.log('Region:', process.env.AWS_REGION);
|
|
191
|
+
console.log('Bucket:', process.env.S3_BUCKET);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
#### InvalidBucketName Error
|
|
195
|
+
|
|
196
|
+
**Error:**
|
|
197
|
+
```
|
|
198
|
+
InvalidBucketName: The specified bucket is not valid.
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Causes:**
|
|
202
|
+
- Bucket name contains invalid characters
|
|
203
|
+
- Bucket name doesn't exist
|
|
204
|
+
- Wrong region
|
|
205
|
+
|
|
206
|
+
**Solutions:**
|
|
207
|
+
```typescript
|
|
208
|
+
// Verify bucket name
|
|
209
|
+
const bucketName = process.env.S3_BUCKET;
|
|
210
|
+
console.log('Bucket name:', bucketName);
|
|
211
|
+
|
|
212
|
+
// Check bucket exists in correct region
|
|
213
|
+
const s3 = new S3DataSource({
|
|
214
|
+
s3Config: {
|
|
215
|
+
region: 'us-east-1', // Must match bucket region!
|
|
216
|
+
credentials: {...}
|
|
217
|
+
},
|
|
218
|
+
bucketName
|
|
219
|
+
}, logger);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### SFTP Errors
|
|
223
|
+
|
|
224
|
+
#### Connection Timeout
|
|
225
|
+
|
|
226
|
+
**Error:**
|
|
227
|
+
```
|
|
228
|
+
Error: Timed out while waiting for handshake
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Causes:**
|
|
232
|
+
- Wrong host or port
|
|
233
|
+
- Firewall blocking connection
|
|
234
|
+
- SFTP server down
|
|
235
|
+
|
|
236
|
+
**Solutions:**
|
|
237
|
+
```typescript
|
|
238
|
+
// Verify connection details
|
|
239
|
+
console.log('Host:', process.env.SFTP_HOST);
|
|
240
|
+
console.log('Port:', process.env.SFTP_PORT);
|
|
241
|
+
|
|
242
|
+
// Test with increased timeout
|
|
243
|
+
const sftp = new SftpDataSource({
|
|
244
|
+
settings: {
|
|
245
|
+
host: process.env.SFTP_HOST!,
|
|
246
|
+
port: parseInt(process.env.SFTP_PORT || '22'),
|
|
247
|
+
username: process.env.SFTP_USERNAME!,
|
|
248
|
+
password: process.env.SFTP_PASSWORD!,
|
|
249
|
+
connectTimeout: 60000 // 60 seconds
|
|
250
|
+
}
|
|
251
|
+
}, logger);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### Authentication Failed
|
|
255
|
+
|
|
256
|
+
**Error:**
|
|
257
|
+
```
|
|
258
|
+
Error: All configured authentication methods failed
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Causes:**
|
|
262
|
+
- Wrong username or password
|
|
263
|
+
- Key-based auth misconfigured
|
|
264
|
+
- Account locked
|
|
265
|
+
|
|
266
|
+
**Solutions:**
|
|
267
|
+
```typescript
|
|
268
|
+
// Verify credentials
|
|
269
|
+
console.log('Username:', process.env.SFTP_USERNAME);
|
|
270
|
+
console.log('Password length:', process.env.SFTP_PASSWORD?.length);
|
|
271
|
+
|
|
272
|
+
// Try key-based auth
|
|
273
|
+
import * as fs from 'fs';
|
|
274
|
+
const privateKey = fs.readFileSync('/path/to/key.pem', 'utf-8');
|
|
275
|
+
|
|
276
|
+
const sftp = new SftpDataSource({
|
|
277
|
+
settings: {
|
|
278
|
+
host: process.env.SFTP_HOST!,
|
|
279
|
+
username: process.env.SFTP_USERNAME!,
|
|
280
|
+
privateKey: privateKey,
|
|
281
|
+
passphrase: process.env.KEY_PASSPHRASE
|
|
282
|
+
}
|
|
283
|
+
}, logger);
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### No Such File
|
|
287
|
+
|
|
288
|
+
**Error:**
|
|
289
|
+
```
|
|
290
|
+
Error: No such file
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Causes:**
|
|
294
|
+
- File doesn't exist
|
|
295
|
+
- Wrong path (relative vs absolute)
|
|
296
|
+
- Path typo
|
|
297
|
+
|
|
298
|
+
**Solutions:**
|
|
299
|
+
```typescript
|
|
300
|
+
// Use absolute paths with leading slash
|
|
301
|
+
const content = await sftp.downloadFile('/data/file.csv'); // ✅
|
|
302
|
+
// NOT: sftp.downloadFile('data/file.csv'); // ❌
|
|
303
|
+
|
|
304
|
+
// List files to verify path
|
|
305
|
+
const files = await sftp.listFiles();
|
|
306
|
+
files.forEach(f => console.log('Path:', f.path));
|
|
307
|
+
|
|
308
|
+
// Check existence before download
|
|
309
|
+
if (await sftp.fileExists('/data/file.csv')) {
|
|
310
|
+
const content = await sftp.downloadFile('/data/file.csv');
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### Permission Denied
|
|
315
|
+
|
|
316
|
+
**Error:**
|
|
317
|
+
```
|
|
318
|
+
Error: Permission denied
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Causes:**
|
|
322
|
+
- User doesn't have read/write permissions
|
|
323
|
+
- Parent directory not writable
|
|
324
|
+
- File owned by different user
|
|
325
|
+
|
|
326
|
+
**Solutions:**
|
|
327
|
+
```typescript
|
|
328
|
+
// Verify permissions on SFTP server
|
|
329
|
+
// Use createDirs flag when moving to new folders
|
|
330
|
+
await sftp.moveFile(
|
|
331
|
+
'/source/file.csv',
|
|
332
|
+
'/archive/2025/01/file.csv',
|
|
333
|
+
true // Create directories with proper permissions
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
// Check user permissions with SFTP admin
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### General Debugging Tips
|
|
340
|
+
|
|
341
|
+
#### Enable Debug Logging
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import {
|
|
345
|
+
createConsoleLogger,
|
|
346
|
+
toStructuredLogger
|
|
347
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
348
|
+
|
|
349
|
+
const logger = createConsoleLogger();
|
|
350
|
+
logger.setLevel('debug'); // Show all debug messages
|
|
351
|
+
|
|
352
|
+
const s3 = new S3DataSource(config, logger);
|
|
353
|
+
|
|
354
|
+
// Now all operations will log details
|
|
355
|
+
const files = await s3.listFiles();
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### SFTP Connection Pooling
|
|
359
|
+
|
|
360
|
+
The SDK automatically manages SFTP connection pooling for better performance:
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
const sftp = new SftpDataSource({
|
|
364
|
+
type: 'SFTP_CSV',
|
|
365
|
+
connectionId: 'sftp-pooled',
|
|
366
|
+
name: 'SFTP with Connection Pool',
|
|
367
|
+
settings: {
|
|
368
|
+
host: 'sftp.example.com',
|
|
369
|
+
username: 'user',
|
|
370
|
+
password: 'pass',
|
|
371
|
+
maxConnections: 5, // Pool size (default: 5)
|
|
372
|
+
connectionWaitTimeout: 30000 // Wait for available connection (default: 30s)
|
|
373
|
+
}
|
|
374
|
+
}, logger);
|
|
375
|
+
|
|
376
|
+
// Connections are automatically reused from pool
|
|
377
|
+
for (let i = 0; i < 100; i++) {
|
|
378
|
+
await sftp.downloadFile(`/data/file${i}.csv`); // Reuses connections
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// IMPORTANT: Always dispose to close all pooled connections
|
|
382
|
+
await sftp.dispose();
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Connection Pool Features:**
|
|
386
|
+
- **Automatic Reuse**: Connections are returned to pool after each operation
|
|
387
|
+
- **Health Checks**: Unhealthy connections are removed and replaced
|
|
388
|
+
- **Wait Queue**: Requests wait for available connection when pool is exhausted
|
|
389
|
+
- **Concurrent Operations**: Multiple operations can share pooled connections
|
|
390
|
+
|
|
391
|
+
**Tuning Connection Pool:**
|
|
392
|
+
```typescript
|
|
393
|
+
// High-concurrency workflow (many parallel operations)
|
|
394
|
+
settings: {
|
|
395
|
+
maxConnections: 10, // Increase pool size
|
|
396
|
+
connectionWaitTimeout: 60000 // Longer wait for busy systems
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Low-concurrency workflow (sequential operations)
|
|
400
|
+
settings: {
|
|
401
|
+
maxConnections: 2, // Smaller pool
|
|
402
|
+
connectionWaitTimeout: 15000 // Shorter timeout
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### Connection Leak Detection
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
// ❌ BAD: Connection not disposed
|
|
410
|
+
const sftp = new SftpDataSource(config, logger);
|
|
411
|
+
await sftp.downloadFile('/file.csv');
|
|
412
|
+
// Missing dispose() - ALL pooled connections leak!
|
|
413
|
+
|
|
414
|
+
// ✅ GOOD: Always dispose
|
|
415
|
+
const sftp = new SftpDataSource(config, logger);
|
|
416
|
+
try {
|
|
417
|
+
await sftp.downloadFile('/file.csv');
|
|
418
|
+
} finally {
|
|
419
|
+
await sftp.dispose(); // Closes ALL pooled connections
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
#### Built-in Retry Logic
|
|
424
|
+
|
|
425
|
+
**SFTP** and **S3** both have built-in retry logic with exponential backoff:
|
|
426
|
+
|
|
427
|
+
**SFTP Automatic Retries:**
|
|
428
|
+
```typescript
|
|
429
|
+
const sftp = new SftpDataSource({
|
|
430
|
+
type: 'SFTP_CSV',
|
|
431
|
+
connectionId: 'sftp-retry',
|
|
432
|
+
name: 'SFTP with Retry',
|
|
433
|
+
settings: {
|
|
434
|
+
host: 'sftp.example.com',
|
|
435
|
+
username: 'user',
|
|
436
|
+
password: 'pass',
|
|
437
|
+
retry: {
|
|
438
|
+
maxAttempts: 3, // Number of retry attempts (default: 3)
|
|
439
|
+
baseDelayMs: 1000, // Initial delay (default: 1000ms)
|
|
440
|
+
backoffFactor: 2, // Exponential multiplier (default: 2)
|
|
441
|
+
maxDelayMs: 8000, // Max delay cap (default: 8000ms)
|
|
442
|
+
jitter: 'full', // Adds randomness to prevent thundering herd
|
|
443
|
+
reconnectOnFailure: true // Reconnect on connection errors
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}, logger);
|
|
447
|
+
|
|
448
|
+
// All operations automatically retry on transient errors
|
|
449
|
+
await sftp.downloadFile('/data/file.csv'); // Retries if network fails
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**How Exponential Backoff Works:**
|
|
453
|
+
- Attempt 1: Immediate (0ms delay)
|
|
454
|
+
- Attempt 2: 1000ms delay (base)
|
|
455
|
+
- Attempt 3: 2000ms delay (base × 2)
|
|
456
|
+
- Attempt 4: 4000ms delay (base × 4)
|
|
457
|
+
- Jitter: Adds random variance (±50%) to prevent multiple clients retrying simultaneously
|
|
458
|
+
|
|
459
|
+
**S3 Automatic Retries:**
|
|
460
|
+
```typescript
|
|
461
|
+
const s3 = new S3DataSource({
|
|
462
|
+
type: 'S3_CSV',
|
|
463
|
+
connectionId: 's3-retry',
|
|
464
|
+
name: 'S3 with Retry',
|
|
465
|
+
s3Config: {
|
|
466
|
+
region: 'us-east-1',
|
|
467
|
+
bucket: 'my-bucket',
|
|
468
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
469
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
470
|
+
maxAttempts: 3 // AWS SDK handles retry logic
|
|
471
|
+
}
|
|
472
|
+
}, logger);
|
|
473
|
+
|
|
474
|
+
// S3 automatically retries on:
|
|
475
|
+
// - 500, 502, 503, 504 HTTP errors
|
|
476
|
+
// - Connection timeouts
|
|
477
|
+
// - Network errors
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**Retryable vs Non-Retryable Errors:**
|
|
481
|
+
|
|
482
|
+
✅ **Automatically Retried:**
|
|
483
|
+
- Network timeouts
|
|
484
|
+
- Connection refused
|
|
485
|
+
- DNS resolution failures
|
|
486
|
+
- 500 Internal Server Error
|
|
487
|
+
- 502 Bad Gateway
|
|
488
|
+
- 503 Service Unavailable
|
|
489
|
+
- 504 Gateway Timeout
|
|
490
|
+
|
|
491
|
+
❌ **NOT Retried (fail immediately):**
|
|
492
|
+
- File not found (404, NoSuchKey)
|
|
493
|
+
- Permission denied (403, AccessDenied)
|
|
494
|
+
- Invalid credentials (401)
|
|
495
|
+
- File already exists (when overwrite=false)
|
|
496
|
+
- Invalid path/filename
|
|
497
|
+
|
|
498
|
+
#### Network Issues
|
|
499
|
+
|
|
500
|
+
**Built-in retry handles most cases automatically**, but you can add custom logic:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
// Custom retry logic (only if needed beyond built-in retries)
|
|
504
|
+
async function downloadWithRetry(
|
|
505
|
+
dataSource: S3DataSource | SftpDataSource,
|
|
506
|
+
path: string,
|
|
507
|
+
maxRetries = 3
|
|
508
|
+
): Promise<string> {
|
|
509
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
510
|
+
try {
|
|
511
|
+
return await dataSource.downloadFile(path);
|
|
512
|
+
} catch (error: any) {
|
|
513
|
+
// Don't retry if file doesn't exist
|
|
514
|
+
if (error.name === 'NoSuchKey' || error.message.includes('No such file')) {
|
|
515
|
+
throw error;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (attempt === maxRetries) throw error;
|
|
519
|
+
|
|
520
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
521
|
+
console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
|
|
522
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
throw new Error('Should not reach here');
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Troubleshooting Checklist
|
|
530
|
+
|
|
531
|
+
### S3 Issues
|
|
532
|
+
|
|
533
|
+
- [ ] Verify AWS credentials are set
|
|
534
|
+
- [ ] Check bucket name is correct
|
|
535
|
+
- [ ] Verify region matches bucket region
|
|
536
|
+
- [ ] Confirm IAM policy has required permissions
|
|
537
|
+
- [ ] Check file path (no leading slash for S3)
|
|
538
|
+
- [ ] Verify network connectivity to AWS
|
|
539
|
+
|
|
540
|
+
### SFTP Issues
|
|
541
|
+
|
|
542
|
+
- [ ] Verify host and port are correct
|
|
543
|
+
- [ ] Check username and password/key
|
|
544
|
+
- [ ] Confirm firewall allows SFTP traffic
|
|
545
|
+
- [ ] Use absolute paths (with leading slash)
|
|
546
|
+
- [ ] Always call `dispose()` in `finally` block
|
|
547
|
+
- [ ] Check SFTP server is running
|
|
548
|
+
|
|
549
|
+
## Key Takeaways
|
|
550
|
+
|
|
551
|
+
- 🎯 SDK has comprehensive test coverage (≥70%)
|
|
552
|
+
- 🎯 Run `npm test` to verify all operations work
|
|
553
|
+
- 🎯 Use integration tests for SFTP with real credentials
|
|
554
|
+
- 🎯 Enable debug logging to troubleshoot issues
|
|
555
|
+
- 🎯 Always handle NoSuchKey/NoSuchFile errors
|
|
556
|
+
- 🎯 Use retry logic for transient network errors
|
|
557
|
+
- 🎯 Check permissions for AccessDenied errors
|
|
558
|
+
|
|
559
|
+
## Next Steps
|
|
560
|
+
|
|
561
|
+
Continue to [Module 8: API Reference](../../error-handling/modules/error-handling-08-api-reference.md) for complete method signatures.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
**Related Resources:**
|
|
566
|
+
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Error handling examples
|
|
567
|
+
- [Test Files](../../../../tests/) - Browse actual test implementations
|