@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,553 +1,553 @@
|
|
|
1
|
-
# SFTP Credential Access & Security Best Practices
|
|
2
|
-
|
|
3
|
-
**For Versori Platform Integration**
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 🎯 Overview
|
|
8
|
-
|
|
9
|
-
This guide covers the **secure retrieval of SFTP credentials** in Versori platform connectors. We'll show **two approaches** - one using `credentials()` API and one using `activation.connections` (recommended).
|
|
10
|
-
|
|
11
|
-
**Key Principle:** Never hardcode credentials in code - always use Versori connection configuration.
|
|
12
|
-
|
|
13
|
-
> **Note:** This guide consolidates the canonical pattern documentation. For production-ready patterns with comprehensive error handling, see the Method 1 section below.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 📋 The Two Approaches
|
|
18
|
-
|
|
19
|
-
| Approach | Method | Decoding | Complexity | Recommended |
|
|
20
|
-
|----------|--------|----------|------------|-------------|
|
|
21
|
-
| **Method 1** | `credentials().getAccessToken()` | ⚠️ Base64 | Medium | ❌ More work |
|
|
22
|
-
| **Method 2** | `activation.connections` | ✅ None | Low | ✅ **BEST** |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## ✅ Correct Method: credentials().getAccessToken()
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
// ✅ CORRECT - Use .getAccessToken()
|
|
30
|
-
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Method 1: credentials() API (Your Corrected Code)
|
|
36
|
-
|
|
37
|
-
**Use when:** Working in `fn()` tasks where `connectionVariables` not available
|
|
38
|
-
|
|
39
|
-
### ✅ Corrected Implementation
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
import { schedule, fn } from '@versori/run';
|
|
43
|
-
import { Buffer } from 'node:buffer'; // ⭐ Required for Deno runtime!
|
|
44
|
-
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
45
|
-
|
|
46
|
-
export const sftpWorkflow = schedule("sftp-sync", "0 * * * *")
|
|
47
|
-
.then(fn("get-files", async (ctx) => {
|
|
48
|
-
const { log } = ctx;
|
|
49
|
-
|
|
50
|
-
// ========================================
|
|
51
|
-
// SFTP CREDENTIAL RETRIEVAL
|
|
52
|
-
// ========================================
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Retrieve SFTP credentials from connection configuration
|
|
56
|
-
*
|
|
57
|
-
* This approach retrieves credentials stored in the Versori connection settings.
|
|
58
|
-
* The connection must be configured in the UI with Basic Authentication.
|
|
59
|
-
*
|
|
60
|
-
* Steps:
|
|
61
|
-
* 1. Call ctx.credentials().getAccessToken('SFTP') to get base64-encoded credentials
|
|
62
|
-
* 2. Decode the accessToken from base64 to get "username:password" string
|
|
63
|
-
* 3. Split on ':' to extract username and password
|
|
64
|
-
*
|
|
65
|
-
* Connection Name: 'SFTP' (must match the connection name in Versori UI)
|
|
66
|
-
* Auth Type: Basic Authentication (username + password)
|
|
67
|
-
*
|
|
68
|
-
* This method provides:
|
|
69
|
-
* - Centralized credential management through Versori UI
|
|
70
|
-
* - Better security (credentials not stored in integration variables)
|
|
71
|
-
* - Easier credential rotation and updates
|
|
72
|
-
*/
|
|
73
|
-
log.info('Retrieving SFTP credentials from connection configuration');
|
|
74
|
-
|
|
75
|
-
let sftpUsername: string;
|
|
76
|
-
let sftpPassword: string;
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
// Retrieve credentials from the 'SFTP' connection
|
|
80
|
-
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
81
|
-
|
|
82
|
-
if (!sftpCred?.accessToken) {
|
|
83
|
-
throw new Error('No SFTP credentials found in connection configuration');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Decode base64 accessToken to get "username:password"
|
|
87
|
-
const rawBasicAuth = Buffer.from(sftpCred.accessToken, 'base64').toString('utf-8');
|
|
88
|
-
|
|
89
|
-
// Split on ':' to extract username and password
|
|
90
|
-
const parts = rawBasicAuth.split(':');
|
|
91
|
-
|
|
92
|
-
if (parts.length !== 2) {
|
|
93
|
-
throw new Error('Invalid SFTP credential format - expected username:password');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
sftpUsername = parts[0];
|
|
97
|
-
sftpPassword = parts[1];
|
|
98
|
-
|
|
99
|
-
log.info('SFTP credentials retrieved successfully', {
|
|
100
|
-
hasUsername: !!sftpUsername,
|
|
101
|
-
hasPassword: !!sftpPassword,
|
|
102
|
-
usernameLength: sftpUsername.length,
|
|
103
|
-
passwordLength: sftpPassword.length,
|
|
104
|
-
});
|
|
105
|
-
} catch (error: any) {
|
|
106
|
-
log.error('Failed to retrieve SFTP credentials', {
|
|
107
|
-
error: error?.message,
|
|
108
|
-
stack: error?.stack,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
success: false,
|
|
113
|
-
error: 'Failed to retrieve SFTP credentials from connection configuration',
|
|
114
|
-
details: error?.message,
|
|
115
|
-
recommendation: 'Please ensure the SFTP connection is configured in the Connections section with Basic Authentication (username and password)',
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ========================================
|
|
120
|
-
// USE CREDENTIALS WITH SFTP
|
|
121
|
-
// ========================================
|
|
122
|
-
|
|
123
|
-
const sftp = new SftpDataSource({
|
|
124
|
-
host: 'sftp.example.com',
|
|
125
|
-
port: 22,
|
|
126
|
-
username: sftpUsername,
|
|
127
|
-
password: sftpPassword
|
|
128
|
-
}, log);
|
|
129
|
-
|
|
130
|
-
const files = await sftp.listFiles('/inbound');
|
|
131
|
-
log.info('Files retrieved', { count: files.length });
|
|
132
|
-
|
|
133
|
-
return { success: true, fileCount: files.length };
|
|
134
|
-
}));
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### ⚠️ Limitations of Method 1
|
|
138
|
-
|
|
139
|
-
**Why this is NOT the best approach:**
|
|
140
|
-
|
|
141
|
-
1. ❌ **Requires base64 decoding** - Extra complexity
|
|
142
|
-
2. ❌ **Only works in `fn()` tasks** - Not in `http()` tasks with `connectionVariables`
|
|
143
|
-
3. ❌ **More error-prone** - Manual string splitting
|
|
144
|
-
4. ❌ **Depends on connection structure** - Assumes `accessToken` field exists
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## ✅ Method 2: activation.connections (RECOMMENDED!)
|
|
149
|
-
|
|
150
|
-
**Use when:** Any task type - **PREFERRED for all cases**
|
|
151
|
-
|
|
152
|
-
### Why This Is Better
|
|
153
|
-
|
|
154
|
-
✅ **Already Decoded** - No Buffer.from() needed!
|
|
155
|
-
✅ **Works Everywhere** - fn(), http(), webhook() tasks
|
|
156
|
-
✅ **Type-Safe** - Direct access to credential structure
|
|
157
|
-
✅ **Cleaner Code** - Fewer steps, less error handling
|
|
158
|
-
|
|
159
|
-
### Complete Implementation
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import { schedule, http } from '@versori/run';
|
|
163
|
-
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
164
|
-
|
|
165
|
-
export const sftpWorkflowRecommended = schedule("sftp-sync-best", "0 * * * *")
|
|
166
|
-
.then(http("process", { connection: "fluent_commerce" }, async (ctx) => {
|
|
167
|
-
const { activation, log } = ctx;
|
|
168
|
-
|
|
169
|
-
// ========================================
|
|
170
|
-
// SFTP CREDENTIAL RETRIEVAL (RECOMMENDED APPROACH)
|
|
171
|
-
// ========================================
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Retrieve SFTP credentials using activation.connections
|
|
175
|
-
*
|
|
176
|
-
* This is the RECOMMENDED approach because:
|
|
177
|
-
* 1. Credentials are ALREADY DECODED (no Buffer.from needed!)
|
|
178
|
-
* 2. Works in any task type (fn, http, webhook)
|
|
179
|
-
* 3. Type-safe access to credential structure
|
|
180
|
-
* 4. Cleaner, more maintainable code
|
|
181
|
-
*
|
|
182
|
-
* Connection Name: 'versori_ftp_server' (must match Versori UI)
|
|
183
|
-
* Auth Type: Basic Authentication (username + password)
|
|
184
|
-
*
|
|
185
|
-
* Benefits:
|
|
186
|
-
* - ✅ No base64 decoding required
|
|
187
|
-
* - ✅ Direct access to username and password
|
|
188
|
-
* - ✅ Better error messages
|
|
189
|
-
* - ✅ Works with multiple connections
|
|
190
|
-
*/
|
|
191
|
-
log.info('Retrieving SFTP credentials from activation.connections');
|
|
192
|
-
|
|
193
|
-
let sftpUsername: string;
|
|
194
|
-
let sftpPassword: string;
|
|
195
|
-
let sftpHost: string;
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
// Get ALL connections from activation
|
|
199
|
-
const allConnections = activation.connections || [];
|
|
200
|
-
|
|
201
|
-
log.debug('Available connections', {
|
|
202
|
-
names: allConnections.map(c => c.name)
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
// Find the SFTP connection by name
|
|
206
|
-
const sftpConnection = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
207
|
-
|
|
208
|
-
if (!sftpConnection) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
`SFTP connection 'versori_ftp_server' not found. ` +
|
|
211
|
-
`Available connections: ${allConnections.map(c => c.name).join(', ')}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Extract credential data
|
|
216
|
-
const sftpCred = sftpConnection.credentials[0]?.credential;
|
|
217
|
-
|
|
218
|
-
if (!sftpCred?.data?.basicAuth) {
|
|
219
|
-
throw new Error(
|
|
220
|
-
'SFTP connection is not configured with Basic Authentication. ' +
|
|
221
|
-
'Please configure username and password in the Versori connection settings.'
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ⭐ ALREADY DECODED - No Buffer.from needed!
|
|
226
|
-
sftpUsername = sftpCred.data.basicAuth.username;
|
|
227
|
-
sftpPassword = sftpCred.data.basicAuth.password;
|
|
228
|
-
sftpHost = sftpConnection.baseUrl || 'sftp.example.com';
|
|
229
|
-
|
|
230
|
-
log.info('SFTP credentials retrieved successfully', {
|
|
231
|
-
username: sftpUsername,
|
|
232
|
-
host: sftpHost,
|
|
233
|
-
hasPassword: !!sftpPassword,
|
|
234
|
-
passwordLength: sftpPassword.length
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
} catch (error: any) {
|
|
238
|
-
log.error('Failed to retrieve SFTP credentials', {
|
|
239
|
-
error: error?.message,
|
|
240
|
-
stack: error?.stack
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
success: false,
|
|
245
|
-
error: 'Failed to retrieve SFTP credentials',
|
|
246
|
-
details: error?.message,
|
|
247
|
-
recommendation: [
|
|
248
|
-
'Ensure the SFTP connection is configured in Versori:',
|
|
249
|
-
'1. Connection name: "versori_ftp_server"',
|
|
250
|
-
'2. Auth type: Basic Authentication',
|
|
251
|
-
'3. Username and password configured',
|
|
252
|
-
'4. BaseUrl set (optional, for host)'
|
|
253
|
-
].join('\n')
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// ========================================
|
|
258
|
-
// USE CREDENTIALS WITH SFTP
|
|
259
|
-
// ========================================
|
|
260
|
-
|
|
261
|
-
const sftp = new SftpDataSource({
|
|
262
|
-
host: sftpHost,
|
|
263
|
-
port: 22,
|
|
264
|
-
username: sftpUsername,
|
|
265
|
-
password: sftpPassword
|
|
266
|
-
}, log);
|
|
267
|
-
|
|
268
|
-
log.info('Connecting to SFTP server', { host: sftpHost });
|
|
269
|
-
|
|
270
|
-
try {
|
|
271
|
-
const files = await sftp.listFiles('/inbound');
|
|
272
|
-
log.info('Files retrieved from SFTP', { count: files.length });
|
|
273
|
-
|
|
274
|
-
return {
|
|
275
|
-
success: true,
|
|
276
|
-
fileCount: files.length,
|
|
277
|
-
host: sftpHost,
|
|
278
|
-
method: 'activation.connections (recommended)'
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
} catch (error: any) {
|
|
282
|
-
log.error('SFTP operation failed', {
|
|
283
|
-
error: error?.message,
|
|
284
|
-
host: sftpHost
|
|
285
|
-
});
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
288
|
-
}));
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## 🔐 Versori Connection Setup
|
|
294
|
-
|
|
295
|
-
### Step 1: Create Connection in Versori UI
|
|
296
|
-
|
|
297
|
-
1. Go to **Connections** section in Versori
|
|
298
|
-
2. Click **"Add Connection"**
|
|
299
|
-
3. Choose **Basic Authentication** type
|
|
300
|
-
4. Configure:
|
|
301
|
-
- **Name:** `versori_ftp_server` (must match code)
|
|
302
|
-
- **Username:** Your SFTP username
|
|
303
|
-
- **Password:** Your SFTP password
|
|
304
|
-
- **BaseUrl:** `sftp.example.com` (optional - for host)
|
|
305
|
-
|
|
306
|
-
### Step 2: Verify Connection Structure
|
|
307
|
-
|
|
308
|
-
Use this debug connector to inspect your connection:
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
311
|
-
import { webhook, fn } from '@versori/run';
|
|
312
|
-
|
|
313
|
-
export const debugConnection = webhook("debug-sftp-connection")
|
|
314
|
-
.then(fn("inspect", async (ctx) => {
|
|
315
|
-
const { activation } = ctx;
|
|
316
|
-
|
|
317
|
-
const allConnections = activation.connections || [];
|
|
318
|
-
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
319
|
-
|
|
320
|
-
if (!sftpConn) {
|
|
321
|
-
return {
|
|
322
|
-
error: "Connection 'versori_ftp_server' not found",
|
|
323
|
-
available: allConnections.map(c => c.name)
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const cred = sftpConn.credentials[0]?.credential;
|
|
328
|
-
|
|
329
|
-
return {
|
|
330
|
-
connectionName: sftpConn.name,
|
|
331
|
-
hasBasicAuth: !!cred?.data?.basicAuth,
|
|
332
|
-
hasUsername: !!cred?.data?.basicAuth?.username,
|
|
333
|
-
hasPassword: !!cred?.data?.basicAuth?.password,
|
|
334
|
-
username: cred?.data?.basicAuth?.username,
|
|
335
|
-
baseUrl: sftpConn.baseUrl,
|
|
336
|
-
// Don't log the actual password!
|
|
337
|
-
passwordLength: cred?.data?.basicAuth?.password?.length
|
|
338
|
-
};
|
|
339
|
-
}));
|
|
340
|
-
|
|
341
|
-
// Call: GET https://your-versori-url/debug-sftp-connection
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
---
|
|
345
|
-
|
|
346
|
-
## 🎯 Decision Guide
|
|
347
|
-
|
|
348
|
-
```
|
|
349
|
-
Need SFTP credentials?
|
|
350
|
-
├─ In http() task?
|
|
351
|
-
│ └─ Can use connectionVariables? (single connection in http() parameter)
|
|
352
|
-
│ ├─ YES → Use connectionVariables.username/password (SIMPLEST!)
|
|
353
|
-
│ └─ NO → Use activation.connections ✅
|
|
354
|
-
│
|
|
355
|
-
└─ In fn() task?
|
|
356
|
-
├─ Only one connection needed?
|
|
357
|
-
│ ├─ Use activation.connections ✅ (RECOMMENDED)
|
|
358
|
-
│ └─ Or credentials().getAccessToken() (if you must)
|
|
359
|
-
│
|
|
360
|
-
└─ Multiple connections?
|
|
361
|
-
└─ Use activation.connections ✅ (REQUIRED)
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## 🔒 Security Best Practices
|
|
367
|
-
|
|
368
|
-
### 1. Never Log Credentials
|
|
369
|
-
|
|
370
|
-
```typescript
|
|
371
|
-
// ❌ BAD - Logs password
|
|
372
|
-
log.info('SFTP config', { username, password });
|
|
373
|
-
|
|
374
|
-
// ✅ GOOD - Logs without password
|
|
375
|
-
log.info('SFTP config', {
|
|
376
|
-
username,
|
|
377
|
-
hasPassword: !!password,
|
|
378
|
-
passwordLength: password.length,
|
|
379
|
-
host
|
|
380
|
-
});
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### 2. Validate Credentials
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
// ✅ Check before using
|
|
387
|
-
if (!sftpUsername || !sftpPassword) {
|
|
388
|
-
throw new Error('Missing SFTP credentials');
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (sftpPassword.length < 8) {
|
|
392
|
-
log.warn('SFTP password seems short', { length: sftpPassword.length });
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### 3. Handle Missing Connections
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
// ✅ Provide helpful error messages
|
|
400
|
-
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
401
|
-
|
|
402
|
-
if (!sftpConn) {
|
|
403
|
-
throw new Error(
|
|
404
|
-
`SFTP connection not found. Available: ${allConnections.map(c => c.name).join(', ')}`
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### 4. Use Connection Configuration (Not Integration Variables)
|
|
410
|
-
|
|
411
|
-
```typescript
|
|
412
|
-
// ❌ BAD - Credentials in code or integration variables
|
|
413
|
-
const username = 'hardcoded-user';
|
|
414
|
-
const password = process.env.SFTP_PASSWORD;
|
|
415
|
-
|
|
416
|
-
// ✅ GOOD - From connection configuration
|
|
417
|
-
const { username, password } = sftpCred.data.basicAuth;
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
---
|
|
421
|
-
|
|
422
|
-
## 📊 Comparison Summary
|
|
423
|
-
|
|
424
|
-
| Feature | credentials().getAccessToken() | activation.connections |
|
|
425
|
-
|---------|-------------------|----------------------|
|
|
426
|
-
| **Decoding** | ⚠️ Manual base64 | ✅ Already decoded |
|
|
427
|
-
| **Complexity** | Medium (3-4 steps) | Low (2 steps) |
|
|
428
|
-
| **Error Handling** | Custom string parsing | Type-safe access |
|
|
429
|
-
| **Task Type** | fn() only | Any (fn, http, webhook) |
|
|
430
|
-
| **Multiple Connections** | One at a time | All at once |
|
|
431
|
-
| **Recommended** | ❌ No | ✅ **YES** |
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## ✅ Recommendations
|
|
436
|
-
|
|
437
|
-
### For New Code
|
|
438
|
-
|
|
439
|
-
**Use `activation.connections` (Method 2):**
|
|
440
|
-
|
|
441
|
-
```typescript
|
|
442
|
-
const allConns = ctx.activation.connections || [];
|
|
443
|
-
const sftpConn = allConns.find(c => c.name === 'versori_ftp_server');
|
|
444
|
-
const { username, password } = sftpConn.credentials[0].credential.data.basicAuth;
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
**Why:**
|
|
448
|
-
- ✅ No decoding needed
|
|
449
|
-
- ✅ Cleaner code
|
|
450
|
-
- ✅ Better error messages
|
|
451
|
-
- ✅ Works everywhere
|
|
452
|
-
|
|
453
|
-
### For Existing Code
|
|
454
|
-
|
|
455
|
-
**If using `credentials().getAccessToken()`:**
|
|
456
|
-
|
|
457
|
-
1. ✅ **Use correct method:** `.getAccessToken()` (not `.get()`)
|
|
458
|
-
2. ✅ **Add Buffer import:** `import { Buffer } from 'node:buffer';`
|
|
459
|
-
3. ✅ **Add error handling** for missing credentials
|
|
460
|
-
4. ⚠️ **Consider migrating** to `activation.connections` for cleaner code
|
|
461
|
-
|
|
462
|
-
---
|
|
463
|
-
|
|
464
|
-
## 🔍 Troubleshooting
|
|
465
|
-
|
|
466
|
-
### Error: "credentials is not a function"
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
// ❌ Missing ctx
|
|
470
|
-
const creds = credentials().getAccessToken('SFTP');
|
|
471
|
-
|
|
472
|
-
// ✅ Call from ctx
|
|
473
|
-
const creds = await ctx.credentials().getAccessToken('SFTP');
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
### Error: "getAccessToken is not a function"
|
|
477
|
-
|
|
478
|
-
```typescript
|
|
479
|
-
// ✅ Correct method
|
|
480
|
-
const cred = await ctx.credentials().getAccessToken('SFTP');
|
|
481
|
-
|
|
482
|
-
// Make sure you're calling from ctx:
|
|
483
|
-
const { credentials } = ctx;
|
|
484
|
-
const cred = await credentials().getAccessToken('SFTP');
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
### Error: "Buffer is not defined"
|
|
488
|
-
|
|
489
|
-
```typescript
|
|
490
|
-
// ❌ Missing import
|
|
491
|
-
const decoded = Buffer.from(base64, 'base64').toString('utf-8');
|
|
492
|
-
|
|
493
|
-
// ✅ Add import
|
|
494
|
-
import { Buffer } from 'node:buffer';
|
|
495
|
-
const decoded = Buffer.from(base64, 'base64').toString('utf-8');
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
### Credentials are undefined
|
|
499
|
-
|
|
500
|
-
```typescript
|
|
501
|
-
// ✅ Check connection exists
|
|
502
|
-
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
503
|
-
if (!sftpConn) {
|
|
504
|
-
ctx.log.error('Connection not found', {
|
|
505
|
-
requested: 'versori_ftp_server',
|
|
506
|
-
available: allConnections.map(c => c.name)
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
---
|
|
512
|
-
|
|
513
|
-
## 📚 Related Documentation
|
|
514
|
-
|
|
515
|
-
- **Versori Expert Skill:** Complete credential access patterns for all connection types
|
|
516
|
-
- **SFTP Complete Guide:** Full SFTP usage documentation
|
|
517
|
-
- **Connection Handling:** Multi-connection workflows
|
|
518
|
-
- **[SFTP Operations Guide](./modules/data-sources-03-sftp-operations.md)** - Complete SFTP integration patterns
|
|
519
|
-
|
|
520
|
-
---
|
|
521
|
-
|
|
522
|
-
## Migration Checklist
|
|
523
|
-
|
|
524
|
-
If you have workflows using the old pattern, follow these steps:
|
|
525
|
-
|
|
526
|
-
### 1. Update Code
|
|
527
|
-
- [ ] Replace old pattern with recommended pattern (activation.connections)
|
|
528
|
-
- [ ] Add comprehensive error handling
|
|
529
|
-
- [ ] Update variable names (`sftpUsername`, `sftpPassword`)
|
|
530
|
-
- [ ] Add detailed logging
|
|
531
|
-
- [ ] Add user-friendly error handling
|
|
532
|
-
|
|
533
|
-
### 2. Configure Connection
|
|
534
|
-
- [ ] Create SFTP connection in Versori UI
|
|
535
|
-
- [ ] Set authentication type to Basic Auth
|
|
536
|
-
- [ ] Enter username and password
|
|
537
|
-
- [ ] Test connection
|
|
538
|
-
|
|
539
|
-
### 3. Update Activation Variables
|
|
540
|
-
- [ ] Remove `sftpUsername` from activation variables (if stored there)
|
|
541
|
-
- [ ] Remove `sftpPassword` from activation variables (if stored there)
|
|
542
|
-
- [ ] Keep `sftpHost`, `sftpPort`, paths in activation variables
|
|
543
|
-
|
|
544
|
-
### 4. Test
|
|
545
|
-
- [ ] Test credential retrieval with valid connection
|
|
546
|
-
- [ ] Test error handling with missing connection
|
|
547
|
-
- [ ] Test error handling with malformed credentials
|
|
548
|
-
- [ ] Verify logging output
|
|
549
|
-
|
|
550
|
-
---
|
|
551
|
-
|
|
552
|
-
**Generated:** 2025-10-29
|
|
553
|
-
**Platform:** Versori
|
|
1
|
+
# SFTP Credential Access & Security Best Practices
|
|
2
|
+
|
|
3
|
+
**For Versori Platform Integration**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎯 Overview
|
|
8
|
+
|
|
9
|
+
This guide covers the **secure retrieval of SFTP credentials** in Versori platform connectors. We'll show **two approaches** - one using `credentials()` API and one using `activation.connections` (recommended).
|
|
10
|
+
|
|
11
|
+
**Key Principle:** Never hardcode credentials in code - always use Versori connection configuration.
|
|
12
|
+
|
|
13
|
+
> **Note:** This guide consolidates the canonical pattern documentation. For production-ready patterns with comprehensive error handling, see the Method 1 section below.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 📋 The Two Approaches
|
|
18
|
+
|
|
19
|
+
| Approach | Method | Decoding | Complexity | Recommended |
|
|
20
|
+
|----------|--------|----------|------------|-------------|
|
|
21
|
+
| **Method 1** | `credentials().getAccessToken()` | ⚠️ Base64 | Medium | ❌ More work |
|
|
22
|
+
| **Method 2** | `activation.connections` | ✅ None | Low | ✅ **BEST** |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ✅ Correct Method: credentials().getAccessToken()
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// ✅ CORRECT - Use .getAccessToken()
|
|
30
|
+
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Method 1: credentials() API (Your Corrected Code)
|
|
36
|
+
|
|
37
|
+
**Use when:** Working in `fn()` tasks where `connectionVariables` not available
|
|
38
|
+
|
|
39
|
+
### ✅ Corrected Implementation
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { schedule, fn } from '@versori/run';
|
|
43
|
+
import { Buffer } from 'node:buffer'; // ⭐ Required for Deno runtime!
|
|
44
|
+
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
45
|
+
|
|
46
|
+
export const sftpWorkflow = schedule("sftp-sync", "0 * * * *")
|
|
47
|
+
.then(fn("get-files", async (ctx) => {
|
|
48
|
+
const { log } = ctx;
|
|
49
|
+
|
|
50
|
+
// ========================================
|
|
51
|
+
// SFTP CREDENTIAL RETRIEVAL
|
|
52
|
+
// ========================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retrieve SFTP credentials from connection configuration
|
|
56
|
+
*
|
|
57
|
+
* This approach retrieves credentials stored in the Versori connection settings.
|
|
58
|
+
* The connection must be configured in the UI with Basic Authentication.
|
|
59
|
+
*
|
|
60
|
+
* Steps:
|
|
61
|
+
* 1. Call ctx.credentials().getAccessToken('SFTP') to get base64-encoded credentials
|
|
62
|
+
* 2. Decode the accessToken from base64 to get "username:password" string
|
|
63
|
+
* 3. Split on ':' to extract username and password
|
|
64
|
+
*
|
|
65
|
+
* Connection Name: 'SFTP' (must match the connection name in Versori UI)
|
|
66
|
+
* Auth Type: Basic Authentication (username + password)
|
|
67
|
+
*
|
|
68
|
+
* This method provides:
|
|
69
|
+
* - Centralized credential management through Versori UI
|
|
70
|
+
* - Better security (credentials not stored in integration variables)
|
|
71
|
+
* - Easier credential rotation and updates
|
|
72
|
+
*/
|
|
73
|
+
log.info('Retrieving SFTP credentials from connection configuration');
|
|
74
|
+
|
|
75
|
+
let sftpUsername: string;
|
|
76
|
+
let sftpPassword: string;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
// Retrieve credentials from the 'SFTP' connection
|
|
80
|
+
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
81
|
+
|
|
82
|
+
if (!sftpCred?.accessToken) {
|
|
83
|
+
throw new Error('No SFTP credentials found in connection configuration');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Decode base64 accessToken to get "username:password"
|
|
87
|
+
const rawBasicAuth = Buffer.from(sftpCred.accessToken, 'base64').toString('utf-8');
|
|
88
|
+
|
|
89
|
+
// Split on ':' to extract username and password
|
|
90
|
+
const parts = rawBasicAuth.split(':');
|
|
91
|
+
|
|
92
|
+
if (parts.length !== 2) {
|
|
93
|
+
throw new Error('Invalid SFTP credential format - expected username:password');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
sftpUsername = parts[0];
|
|
97
|
+
sftpPassword = parts[1];
|
|
98
|
+
|
|
99
|
+
log.info('SFTP credentials retrieved successfully', {
|
|
100
|
+
hasUsername: !!sftpUsername,
|
|
101
|
+
hasPassword: !!sftpPassword,
|
|
102
|
+
usernameLength: sftpUsername.length,
|
|
103
|
+
passwordLength: sftpPassword.length,
|
|
104
|
+
});
|
|
105
|
+
} catch (error: any) {
|
|
106
|
+
log.error('Failed to retrieve SFTP credentials', {
|
|
107
|
+
error: error?.message,
|
|
108
|
+
stack: error?.stack,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
error: 'Failed to retrieve SFTP credentials from connection configuration',
|
|
114
|
+
details: error?.message,
|
|
115
|
+
recommendation: 'Please ensure the SFTP connection is configured in the Connections section with Basic Authentication (username and password)',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ========================================
|
|
120
|
+
// USE CREDENTIALS WITH SFTP
|
|
121
|
+
// ========================================
|
|
122
|
+
|
|
123
|
+
const sftp = new SftpDataSource({
|
|
124
|
+
host: 'sftp.example.com',
|
|
125
|
+
port: 22,
|
|
126
|
+
username: sftpUsername,
|
|
127
|
+
password: sftpPassword
|
|
128
|
+
}, log);
|
|
129
|
+
|
|
130
|
+
const files = await sftp.listFiles('/inbound');
|
|
131
|
+
log.info('Files retrieved', { count: files.length });
|
|
132
|
+
|
|
133
|
+
return { success: true, fileCount: files.length };
|
|
134
|
+
}));
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### ⚠️ Limitations of Method 1
|
|
138
|
+
|
|
139
|
+
**Why this is NOT the best approach:**
|
|
140
|
+
|
|
141
|
+
1. ❌ **Requires base64 decoding** - Extra complexity
|
|
142
|
+
2. ❌ **Only works in `fn()` tasks** - Not in `http()` tasks with `connectionVariables`
|
|
143
|
+
3. ❌ **More error-prone** - Manual string splitting
|
|
144
|
+
4. ❌ **Depends on connection structure** - Assumes `accessToken` field exists
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## ✅ Method 2: activation.connections (RECOMMENDED!)
|
|
149
|
+
|
|
150
|
+
**Use when:** Any task type - **PREFERRED for all cases**
|
|
151
|
+
|
|
152
|
+
### Why This Is Better
|
|
153
|
+
|
|
154
|
+
✅ **Already Decoded** - No Buffer.from() needed!
|
|
155
|
+
✅ **Works Everywhere** - fn(), http(), webhook() tasks
|
|
156
|
+
✅ **Type-Safe** - Direct access to credential structure
|
|
157
|
+
✅ **Cleaner Code** - Fewer steps, less error handling
|
|
158
|
+
|
|
159
|
+
### Complete Implementation
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { schedule, http } from '@versori/run';
|
|
163
|
+
import { SftpDataSource } from '@fluentcommerce/fc-connect-sdk';
|
|
164
|
+
|
|
165
|
+
export const sftpWorkflowRecommended = schedule("sftp-sync-best", "0 * * * *")
|
|
166
|
+
.then(http("process", { connection: "fluent_commerce" }, async (ctx) => {
|
|
167
|
+
const { activation, log } = ctx;
|
|
168
|
+
|
|
169
|
+
// ========================================
|
|
170
|
+
// SFTP CREDENTIAL RETRIEVAL (RECOMMENDED APPROACH)
|
|
171
|
+
// ========================================
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Retrieve SFTP credentials using activation.connections
|
|
175
|
+
*
|
|
176
|
+
* This is the RECOMMENDED approach because:
|
|
177
|
+
* 1. Credentials are ALREADY DECODED (no Buffer.from needed!)
|
|
178
|
+
* 2. Works in any task type (fn, http, webhook)
|
|
179
|
+
* 3. Type-safe access to credential structure
|
|
180
|
+
* 4. Cleaner, more maintainable code
|
|
181
|
+
*
|
|
182
|
+
* Connection Name: 'versori_ftp_server' (must match Versori UI)
|
|
183
|
+
* Auth Type: Basic Authentication (username + password)
|
|
184
|
+
*
|
|
185
|
+
* Benefits:
|
|
186
|
+
* - ✅ No base64 decoding required
|
|
187
|
+
* - ✅ Direct access to username and password
|
|
188
|
+
* - ✅ Better error messages
|
|
189
|
+
* - ✅ Works with multiple connections
|
|
190
|
+
*/
|
|
191
|
+
log.info('Retrieving SFTP credentials from activation.connections');
|
|
192
|
+
|
|
193
|
+
let sftpUsername: string;
|
|
194
|
+
let sftpPassword: string;
|
|
195
|
+
let sftpHost: string;
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
// Get ALL connections from activation
|
|
199
|
+
const allConnections = activation.connections || [];
|
|
200
|
+
|
|
201
|
+
log.debug('Available connections', {
|
|
202
|
+
names: allConnections.map(c => c.name)
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Find the SFTP connection by name
|
|
206
|
+
const sftpConnection = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
207
|
+
|
|
208
|
+
if (!sftpConnection) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
`SFTP connection 'versori_ftp_server' not found. ` +
|
|
211
|
+
`Available connections: ${allConnections.map(c => c.name).join(', ')}`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Extract credential data
|
|
216
|
+
const sftpCred = sftpConnection.credentials[0]?.credential;
|
|
217
|
+
|
|
218
|
+
if (!sftpCred?.data?.basicAuth) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
'SFTP connection is not configured with Basic Authentication. ' +
|
|
221
|
+
'Please configure username and password in the Versori connection settings.'
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ⭐ ALREADY DECODED - No Buffer.from needed!
|
|
226
|
+
sftpUsername = sftpCred.data.basicAuth.username;
|
|
227
|
+
sftpPassword = sftpCred.data.basicAuth.password;
|
|
228
|
+
sftpHost = sftpConnection.baseUrl || 'sftp.example.com';
|
|
229
|
+
|
|
230
|
+
log.info('SFTP credentials retrieved successfully', {
|
|
231
|
+
username: sftpUsername,
|
|
232
|
+
host: sftpHost,
|
|
233
|
+
hasPassword: !!sftpPassword,
|
|
234
|
+
passwordLength: sftpPassword.length
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
} catch (error: any) {
|
|
238
|
+
log.error('Failed to retrieve SFTP credentials', {
|
|
239
|
+
error: error?.message,
|
|
240
|
+
stack: error?.stack
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
success: false,
|
|
245
|
+
error: 'Failed to retrieve SFTP credentials',
|
|
246
|
+
details: error?.message,
|
|
247
|
+
recommendation: [
|
|
248
|
+
'Ensure the SFTP connection is configured in Versori:',
|
|
249
|
+
'1. Connection name: "versori_ftp_server"',
|
|
250
|
+
'2. Auth type: Basic Authentication',
|
|
251
|
+
'3. Username and password configured',
|
|
252
|
+
'4. BaseUrl set (optional, for host)'
|
|
253
|
+
].join('\n')
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ========================================
|
|
258
|
+
// USE CREDENTIALS WITH SFTP
|
|
259
|
+
// ========================================
|
|
260
|
+
|
|
261
|
+
const sftp = new SftpDataSource({
|
|
262
|
+
host: sftpHost,
|
|
263
|
+
port: 22,
|
|
264
|
+
username: sftpUsername,
|
|
265
|
+
password: sftpPassword
|
|
266
|
+
}, log);
|
|
267
|
+
|
|
268
|
+
log.info('Connecting to SFTP server', { host: sftpHost });
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
const files = await sftp.listFiles('/inbound');
|
|
272
|
+
log.info('Files retrieved from SFTP', { count: files.length });
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
success: true,
|
|
276
|
+
fileCount: files.length,
|
|
277
|
+
host: sftpHost,
|
|
278
|
+
method: 'activation.connections (recommended)'
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
} catch (error: any) {
|
|
282
|
+
log.error('SFTP operation failed', {
|
|
283
|
+
error: error?.message,
|
|
284
|
+
host: sftpHost
|
|
285
|
+
});
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}));
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 🔐 Versori Connection Setup
|
|
294
|
+
|
|
295
|
+
### Step 1: Create Connection in Versori UI
|
|
296
|
+
|
|
297
|
+
1. Go to **Connections** section in Versori
|
|
298
|
+
2. Click **"Add Connection"**
|
|
299
|
+
3. Choose **Basic Authentication** type
|
|
300
|
+
4. Configure:
|
|
301
|
+
- **Name:** `versori_ftp_server` (must match code)
|
|
302
|
+
- **Username:** Your SFTP username
|
|
303
|
+
- **Password:** Your SFTP password
|
|
304
|
+
- **BaseUrl:** `sftp.example.com` (optional - for host)
|
|
305
|
+
|
|
306
|
+
### Step 2: Verify Connection Structure
|
|
307
|
+
|
|
308
|
+
Use this debug connector to inspect your connection:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import { webhook, fn } from '@versori/run';
|
|
312
|
+
|
|
313
|
+
export const debugConnection = webhook("debug-sftp-connection")
|
|
314
|
+
.then(fn("inspect", async (ctx) => {
|
|
315
|
+
const { activation } = ctx;
|
|
316
|
+
|
|
317
|
+
const allConnections = activation.connections || [];
|
|
318
|
+
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
319
|
+
|
|
320
|
+
if (!sftpConn) {
|
|
321
|
+
return {
|
|
322
|
+
error: "Connection 'versori_ftp_server' not found",
|
|
323
|
+
available: allConnections.map(c => c.name)
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const cred = sftpConn.credentials[0]?.credential;
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
connectionName: sftpConn.name,
|
|
331
|
+
hasBasicAuth: !!cred?.data?.basicAuth,
|
|
332
|
+
hasUsername: !!cred?.data?.basicAuth?.username,
|
|
333
|
+
hasPassword: !!cred?.data?.basicAuth?.password,
|
|
334
|
+
username: cred?.data?.basicAuth?.username,
|
|
335
|
+
baseUrl: sftpConn.baseUrl,
|
|
336
|
+
// Don't log the actual password!
|
|
337
|
+
passwordLength: cred?.data?.basicAuth?.password?.length
|
|
338
|
+
};
|
|
339
|
+
}));
|
|
340
|
+
|
|
341
|
+
// Call: GET https://your-versori-url/debug-sftp-connection
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## 🎯 Decision Guide
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
Need SFTP credentials?
|
|
350
|
+
├─ In http() task?
|
|
351
|
+
│ └─ Can use connectionVariables? (single connection in http() parameter)
|
|
352
|
+
│ ├─ YES → Use connectionVariables.username/password (SIMPLEST!)
|
|
353
|
+
│ └─ NO → Use activation.connections ✅
|
|
354
|
+
│
|
|
355
|
+
└─ In fn() task?
|
|
356
|
+
├─ Only one connection needed?
|
|
357
|
+
│ ├─ Use activation.connections ✅ (RECOMMENDED)
|
|
358
|
+
│ └─ Or credentials().getAccessToken() (if you must)
|
|
359
|
+
│
|
|
360
|
+
└─ Multiple connections?
|
|
361
|
+
└─ Use activation.connections ✅ (REQUIRED)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## 🔒 Security Best Practices
|
|
367
|
+
|
|
368
|
+
### 1. Never Log Credentials
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// ❌ BAD - Logs password
|
|
372
|
+
log.info('SFTP config', { username, password });
|
|
373
|
+
|
|
374
|
+
// ✅ GOOD - Logs without password
|
|
375
|
+
log.info('SFTP config', {
|
|
376
|
+
username,
|
|
377
|
+
hasPassword: !!password,
|
|
378
|
+
passwordLength: password.length,
|
|
379
|
+
host
|
|
380
|
+
});
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### 2. Validate Credentials
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
// ✅ Check before using
|
|
387
|
+
if (!sftpUsername || !sftpPassword) {
|
|
388
|
+
throw new Error('Missing SFTP credentials');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (sftpPassword.length < 8) {
|
|
392
|
+
log.warn('SFTP password seems short', { length: sftpPassword.length });
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### 3. Handle Missing Connections
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// ✅ Provide helpful error messages
|
|
400
|
+
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
401
|
+
|
|
402
|
+
if (!sftpConn) {
|
|
403
|
+
throw new Error(
|
|
404
|
+
`SFTP connection not found. Available: ${allConnections.map(c => c.name).join(', ')}`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 4. Use Connection Configuration (Not Integration Variables)
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// ❌ BAD - Credentials in code or integration variables
|
|
413
|
+
const username = 'hardcoded-user';
|
|
414
|
+
const password = process.env.SFTP_PASSWORD;
|
|
415
|
+
|
|
416
|
+
// ✅ GOOD - From connection configuration
|
|
417
|
+
const { username, password } = sftpCred.data.basicAuth;
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## 📊 Comparison Summary
|
|
423
|
+
|
|
424
|
+
| Feature | credentials().getAccessToken() | activation.connections |
|
|
425
|
+
|---------|-------------------|----------------------|
|
|
426
|
+
| **Decoding** | ⚠️ Manual base64 | ✅ Already decoded |
|
|
427
|
+
| **Complexity** | Medium (3-4 steps) | Low (2 steps) |
|
|
428
|
+
| **Error Handling** | Custom string parsing | Type-safe access |
|
|
429
|
+
| **Task Type** | fn() only | Any (fn, http, webhook) |
|
|
430
|
+
| **Multiple Connections** | One at a time | All at once |
|
|
431
|
+
| **Recommended** | ❌ No | ✅ **YES** |
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## ✅ Recommendations
|
|
436
|
+
|
|
437
|
+
### For New Code
|
|
438
|
+
|
|
439
|
+
**Use `activation.connections` (Method 2):**
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
const allConns = ctx.activation.connections || [];
|
|
443
|
+
const sftpConn = allConns.find(c => c.name === 'versori_ftp_server');
|
|
444
|
+
const { username, password } = sftpConn.credentials[0].credential.data.basicAuth;
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Why:**
|
|
448
|
+
- ✅ No decoding needed
|
|
449
|
+
- ✅ Cleaner code
|
|
450
|
+
- ✅ Better error messages
|
|
451
|
+
- ✅ Works everywhere
|
|
452
|
+
|
|
453
|
+
### For Existing Code
|
|
454
|
+
|
|
455
|
+
**If using `credentials().getAccessToken()`:**
|
|
456
|
+
|
|
457
|
+
1. ✅ **Use correct method:** `.getAccessToken()` (not `.get()`)
|
|
458
|
+
2. ✅ **Add Buffer import:** `import { Buffer } from 'node:buffer';`
|
|
459
|
+
3. ✅ **Add error handling** for missing credentials
|
|
460
|
+
4. ⚠️ **Consider migrating** to `activation.connections` for cleaner code
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## 🔍 Troubleshooting
|
|
465
|
+
|
|
466
|
+
### Error: "credentials is not a function"
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// ❌ Missing ctx
|
|
470
|
+
const creds = credentials().getAccessToken('SFTP');
|
|
471
|
+
|
|
472
|
+
// ✅ Call from ctx
|
|
473
|
+
const creds = await ctx.credentials().getAccessToken('SFTP');
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Error: "getAccessToken is not a function"
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
// ✅ Correct method
|
|
480
|
+
const cred = await ctx.credentials().getAccessToken('SFTP');
|
|
481
|
+
|
|
482
|
+
// Make sure you're calling from ctx:
|
|
483
|
+
const { credentials } = ctx;
|
|
484
|
+
const cred = await credentials().getAccessToken('SFTP');
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Error: "Buffer is not defined"
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
// ❌ Missing import
|
|
491
|
+
const decoded = Buffer.from(base64, 'base64').toString('utf-8');
|
|
492
|
+
|
|
493
|
+
// ✅ Add import
|
|
494
|
+
import { Buffer } from 'node:buffer';
|
|
495
|
+
const decoded = Buffer.from(base64, 'base64').toString('utf-8');
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Credentials are undefined
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// ✅ Check connection exists
|
|
502
|
+
const sftpConn = allConnections.find(c => c.name === 'versori_ftp_server');
|
|
503
|
+
if (!sftpConn) {
|
|
504
|
+
ctx.log.error('Connection not found', {
|
|
505
|
+
requested: 'versori_ftp_server',
|
|
506
|
+
available: allConnections.map(c => c.name)
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## 📚 Related Documentation
|
|
514
|
+
|
|
515
|
+
- **Versori Expert Skill:** Complete credential access patterns for all connection types
|
|
516
|
+
- **SFTP Complete Guide:** Full SFTP usage documentation
|
|
517
|
+
- **Connection Handling:** Multi-connection workflows
|
|
518
|
+
- **[SFTP Operations Guide](./modules/data-sources-03-sftp-operations.md)** - Complete SFTP integration patterns
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Migration Checklist
|
|
523
|
+
|
|
524
|
+
If you have workflows using the old pattern, follow these steps:
|
|
525
|
+
|
|
526
|
+
### 1. Update Code
|
|
527
|
+
- [ ] Replace old pattern with recommended pattern (activation.connections)
|
|
528
|
+
- [ ] Add comprehensive error handling
|
|
529
|
+
- [ ] Update variable names (`sftpUsername`, `sftpPassword`)
|
|
530
|
+
- [ ] Add detailed logging
|
|
531
|
+
- [ ] Add user-friendly error handling
|
|
532
|
+
|
|
533
|
+
### 2. Configure Connection
|
|
534
|
+
- [ ] Create SFTP connection in Versori UI
|
|
535
|
+
- [ ] Set authentication type to Basic Auth
|
|
536
|
+
- [ ] Enter username and password
|
|
537
|
+
- [ ] Test connection
|
|
538
|
+
|
|
539
|
+
### 3. Update Activation Variables
|
|
540
|
+
- [ ] Remove `sftpUsername` from activation variables (if stored there)
|
|
541
|
+
- [ ] Remove `sftpPassword` from activation variables (if stored there)
|
|
542
|
+
- [ ] Keep `sftpHost`, `sftpPort`, paths in activation variables
|
|
543
|
+
|
|
544
|
+
### 4. Test
|
|
545
|
+
- [ ] Test credential retrieval with valid connection
|
|
546
|
+
- [ ] Test error handling with missing connection
|
|
547
|
+
- [ ] Test error handling with malformed credentials
|
|
548
|
+
- [ ] Verify logging output
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
**Generated:** 2025-10-29
|
|
553
|
+
**Platform:** Versori
|