@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
package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md
CHANGED
|
@@ -1,656 +1,656 @@
|
|
|
1
|
-
# Connection Validation Pattern
|
|
2
|
-
|
|
3
|
-
**Pattern**: Optional connection validation for `createClient()` with fail-fast authentication checking
|
|
4
|
-
|
|
5
|
-
**Version**: SDK ^0.1.34+
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
The `createClient()` function supports optional connection validation via the `validateConnection` option. When enabled, it executes a minimal GraphQL query (`query { me { ref } }`) to verify authentication immediately, providing fail-fast error detection.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Pattern: Make It Configurable
|
|
16
|
-
|
|
17
|
-
**Recommended Approach**: Use activation variable to enable/disable validation
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
// ✅ OPTIONAL: Validate connection immediately (fail-fast mode)
|
|
21
|
-
// Set activation variable 'validateConnectionOnStart' = 'true' to enable
|
|
22
|
-
// When enabled: Executes query { me { ref } } to verify authentication
|
|
23
|
-
// When disabled: Fast creation, validation happens on first API call (default)
|
|
24
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
25
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
26
|
-
|
|
27
|
-
if (validateConnection) {
|
|
28
|
-
log.info('✅ Connection validated successfully - authentication confirmed', { jobId });
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## When to Use
|
|
35
|
-
|
|
36
|
-
### ✅ **Enable Validation** (`validateConnection: true`)
|
|
37
|
-
|
|
38
|
-
- **Webhook workflows** - Quick error responses to callers
|
|
39
|
-
- **Critical production workflows** - Fail-fast on auth errors
|
|
40
|
-
- **Long-running workflows** - Catch auth issues before processing
|
|
41
|
-
- **Debugging scenarios** - Verify credentials immediately
|
|
42
|
-
|
|
43
|
-
### ❌ **Disable Validation** (default)
|
|
44
|
-
|
|
45
|
-
- **High-frequency scheduled workflows** - Avoid extra API call overhead
|
|
46
|
-
- **Development/testing** - Speed matters more than early validation
|
|
47
|
-
- **Workflows that handle errors gracefully** - Errors surface on first API call anyway
|
|
48
|
-
- **Batch processing** - Multiple client creations per workflow
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Complete Examples
|
|
53
|
-
|
|
54
|
-
### Example 1: Webhook Workflow (Fail-Fast Recommended)
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
export const orderIngestion = webhook('order-ingestion')
|
|
58
|
-
.then(
|
|
59
|
-
http('process-order', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
60
|
-
const { log, activation } = ctx;
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
// ✅ Fail-fast: Validate connection immediately for webhooks
|
|
64
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
65
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
66
|
-
|
|
67
|
-
if (validateConnection) {
|
|
68
|
-
log.info('✅ Connection validated successfully - authentication confirmed');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Process order...
|
|
72
|
-
return { success: true };
|
|
73
|
-
|
|
74
|
-
} catch (error: any) {
|
|
75
|
-
// 🔍 Enhanced: Error logging with recommendations
|
|
76
|
-
log.error('[ConnectionValidation] Authentication failed', {
|
|
77
|
-
error: error instanceof Error ? error.message : String(error),
|
|
78
|
-
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
79
|
-
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
80
|
-
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
81
|
-
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
82
|
-
? 'Check network connectivity and Fluent Commerce API availability'
|
|
83
|
-
: 'Review error details and verify connection configuration'
|
|
84
|
-
});
|
|
85
|
-
throw error;
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
)
|
|
89
|
-
.catch((ctx: Context<any>) => {
|
|
90
|
-
const error = ctx.data instanceof Error ? ctx.data : new Error(String(ctx.data));
|
|
91
|
-
const errorDetails = {
|
|
92
|
-
message: error instanceof Error ? error.message : String(error),
|
|
93
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
94
|
-
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
95
|
-
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
96
|
-
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
97
|
-
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
98
|
-
? 'Check network connectivity and Fluent Commerce API availability'
|
|
99
|
-
: 'Review error details and verify workflow configuration'
|
|
100
|
-
};
|
|
101
|
-
ctx.log.error('[ConnectionValidation] Workflow failed', errorDetails);
|
|
102
|
-
return { success: false, error: error.message, recommendation: errorDetails.recommendation };
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Example 2: Scheduled Workflow (Optional)
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
export const scheduledProductIngestion = schedule('product-ingestion', '0 * * * *')
|
|
110
|
-
.then(
|
|
111
|
-
http('execute-ingestion', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
112
|
-
const { log, activation } = ctx;
|
|
113
|
-
|
|
114
|
-
// ✅ Optional: Validate connection (configurable via activation variable)
|
|
115
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
116
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
117
|
-
|
|
118
|
-
if (validateConnection) {
|
|
119
|
-
log.info('✅ Connection validated successfully');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Process files...
|
|
123
|
-
return result;
|
|
124
|
-
})
|
|
125
|
-
);
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Example 3: Extraction Workflow
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
export async function executeInventoryPositionExtraction(
|
|
132
|
-
ctx: VersoriContext,
|
|
133
|
-
params: ExtractionParams
|
|
134
|
-
): Promise<ExtractionResult> {
|
|
135
|
-
const { log, openKv, activation } = ctx;
|
|
136
|
-
|
|
137
|
-
// ✅ Optional: Validate connection immediately (fail-fast mode)
|
|
138
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
139
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
140
|
-
|
|
141
|
-
if (validateConnection) {
|
|
142
|
-
log.info('✅ Connection validated successfully - authentication confirmed', { jobId });
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Continue with extraction...
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Activation Variable Configuration
|
|
152
|
-
|
|
153
|
-
**Variable Name**: `validateConnectionOnStart`
|
|
154
|
-
|
|
155
|
-
**Values**:
|
|
156
|
-
- `'true'` - Enable validation (fail-fast mode)
|
|
157
|
-
- `'false'` or unset - Disable validation (fast creation, default)
|
|
158
|
-
|
|
159
|
-
**How to Set**:
|
|
160
|
-
1. Go to Versori Activation Variables
|
|
161
|
-
2. Add variable: `validateConnectionOnStart` = `true`
|
|
162
|
-
3. Save activation
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## Benefits
|
|
167
|
-
|
|
168
|
-
✅ **Fail-Fast**: Catch auth errors immediately, not on first API call
|
|
169
|
-
✅ **Better Logging**: "authenticated" vs "instance created"
|
|
170
|
-
✅ **Configurable**: Enable only when needed
|
|
171
|
-
✅ **Performance**: No overhead when disabled (default)
|
|
172
|
-
✅ **Backward Compatible**: Existing templates work unchanged
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Default Behavior
|
|
177
|
-
|
|
178
|
-
**Without `validateConnection` option** (default):
|
|
179
|
-
- Fast client creation
|
|
180
|
-
- No API call during creation
|
|
181
|
-
- Validation happens on first API call
|
|
182
|
-
- Errors surface when you try to use the client
|
|
183
|
-
|
|
184
|
-
**With `validateConnection: true`**:
|
|
185
|
-
- Executes `query { me { ref } }` immediately
|
|
186
|
-
- Fails fast if authentication is invalid
|
|
187
|
-
- Logs "created and authenticated" on success
|
|
188
|
-
- Logs "Connection validation failed" on error
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Automatic Connection Validation (v0.1.40+)
|
|
193
|
-
|
|
194
|
-
**SDK Automatic Checks:**
|
|
195
|
-
|
|
196
|
-
When you call `createClient(ctx)`, the SDK automatically validates:
|
|
197
|
-
|
|
198
|
-
### 1. ctx.fetch Presence (CRITICAL)
|
|
199
|
-
|
|
200
|
-
**Validates:** `ctx.fetch` exists
|
|
201
|
-
**Throws:** `"Invalid Versori context: ctx.fetch is required. Ensure you are running in Versori platform and using createClient(ctx)."`
|
|
202
|
-
**Purpose:** Ensures running in Versori runtime environment
|
|
203
|
-
|
|
204
|
-
**Example:**
|
|
205
|
-
```typescript
|
|
206
|
-
// ❌ Wrong context - will throw
|
|
207
|
-
const invalidCtx = { log: console };
|
|
208
|
-
const client = await createClient(invalidCtx);
|
|
209
|
-
// Error: Invalid Versori context: ctx.fetch is required...
|
|
210
|
-
|
|
211
|
-
// ✅ Correct Versori context
|
|
212
|
-
const client = await createClient(ctx); // ctx from Versori workflow
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### 2. retailerId Detection (WARNING)
|
|
216
|
-
|
|
217
|
-
**Attempts extraction from:**
|
|
218
|
-
1. `ctx.connectionVariables.retailerId` (priority 1)
|
|
219
|
-
2. `baseUrl` path regex `/\/retailer\/([^/]+)\/?$/` (priority 2)
|
|
220
|
-
|
|
221
|
-
**Logs WARNING if not found:**
|
|
222
|
-
- Message: `"[fc-connect-sdk:client] No retailerId found in connection config or baseUrl"`
|
|
223
|
-
- Hint: `"Set connection.retailerId or use client.setRetailerId() for Event/Job/Batch APIs"`
|
|
224
|
-
- Docs: `"GraphQL queries work without retailerId, but Event/Job/Batch APIs require it"`
|
|
225
|
-
|
|
226
|
-
**Not an error because:**
|
|
227
|
-
- retailerId is only required for Event/Job/Batch APIs
|
|
228
|
-
- GraphQL queries work without retailerId
|
|
229
|
-
- Can be set later via `client.setRetailerId()`
|
|
230
|
-
|
|
231
|
-
**Example:**
|
|
232
|
-
```typescript
|
|
233
|
-
// Scenario 1: retailerId in connection variables
|
|
234
|
-
const ctx = {
|
|
235
|
-
fetch: versoriManagedFetch,
|
|
236
|
-
log: versoriLog,
|
|
237
|
-
connectionVariables: { retailerId: '1' }
|
|
238
|
-
};
|
|
239
|
-
const client = await createClient(ctx);
|
|
240
|
-
// ✅ Log: "[fc-connect-sdk:client] Using retailerId from connection variables"
|
|
241
|
-
|
|
242
|
-
// Scenario 2: retailerId in baseUrl
|
|
243
|
-
const ctx = {
|
|
244
|
-
fetch: versoriManagedFetch,
|
|
245
|
-
log: versoriLog,
|
|
246
|
-
baseUrl: 'https://api.fluentcommerce.com/retailer/123'
|
|
247
|
-
};
|
|
248
|
-
const client = await createClient(ctx);
|
|
249
|
-
// ✅ Log: "[fc-connect-sdk:client] Extracted retailerId from baseUrl"
|
|
250
|
-
|
|
251
|
-
// Scenario 3: No retailerId
|
|
252
|
-
const ctx = {
|
|
253
|
-
fetch: versoriManagedFetch,
|
|
254
|
-
log: versoriLog,
|
|
255
|
-
baseUrl: 'https://api.fluentcommerce.com'
|
|
256
|
-
};
|
|
257
|
-
const client = await createClient(ctx);
|
|
258
|
-
// ⚠️ Warning: "No retailerId found..." (but still creates client)
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### 3. ctx.log Check
|
|
262
|
-
|
|
263
|
-
**Validates:** `ctx.log` exists
|
|
264
|
-
**Action:** Logs warning to console if missing (logs will be disabled)
|
|
265
|
-
**Does not throw:** SDK continues without logging
|
|
266
|
-
|
|
267
|
-
### When retailerId is REQUIRED
|
|
268
|
-
|
|
269
|
-
**✅ Required for:**
|
|
270
|
-
- `sendEvent()` - Validated before API call
|
|
271
|
-
- `createJob()` - Validated before API call
|
|
272
|
-
- Batch operations - Validated in job payload
|
|
273
|
-
|
|
274
|
-
**❌ NOT Required for:**
|
|
275
|
-
- `graphql()` - Works without retailerId
|
|
276
|
-
- `query()` - Works without retailerId
|
|
277
|
-
- `mutate()` - Works without retailerId
|
|
278
|
-
|
|
279
|
-
**Validation happens at API call time:**
|
|
280
|
-
```typescript
|
|
281
|
-
// Step 1: Create client (warning logged if no retailerId)
|
|
282
|
-
const client = await createClient(ctx);
|
|
283
|
-
// ⚠️ Warning: "No retailerId found..."
|
|
284
|
-
|
|
285
|
-
// Step 2: Try to use Event API (validation throws error)
|
|
286
|
-
await client.sendEvent(event);
|
|
287
|
-
// ❌ Error: "retailerId is required for Event API..."
|
|
288
|
-
|
|
289
|
-
// Step 3: Fix by setting retailerId
|
|
290
|
-
client.setRetailerId('1');
|
|
291
|
-
await client.sendEvent(event);
|
|
292
|
-
// ✅ Works!
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### Example Validation Flow
|
|
296
|
-
|
|
297
|
-
**Complete validation flow with all checks:**
|
|
298
|
-
```typescript
|
|
299
|
-
export const workflow = http('inventory-sync', {
|
|
300
|
-
connection: 'fluent_commerce'
|
|
301
|
-
}, async (ctx) => {
|
|
302
|
-
// STEP 1: Automatic validation during createClient()
|
|
303
|
-
const client = await createClient(ctx);
|
|
304
|
-
// ✅ ctx.fetch validated (throws if missing)
|
|
305
|
-
// ⚠️ retailerId detection attempted (warning if missing)
|
|
306
|
-
// ✅ ctx.log checked (console warning if missing)
|
|
307
|
-
|
|
308
|
-
// STEP 2: Configure retailerId if using Event/Job/Batch APIs
|
|
309
|
-
const fluentRetailerId = ctx.activation?.getVariable('FLUENT_RETAILER_ID');
|
|
310
|
-
if (fluentRetailerId) {
|
|
311
|
-
client.setRetailerId(fluentRetailerId);
|
|
312
|
-
ctx.log?.info?.('retailerId configured', { retailerId: fluentRetailerId });
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// STEP 3: API call (automatic validation before request)
|
|
316
|
-
try {
|
|
317
|
-
await client.sendEvent(event);
|
|
318
|
-
// ✅ Validates retailerId exists before API call
|
|
319
|
-
} catch (error) {
|
|
320
|
-
if (error.message.includes('retailerId is required')) {
|
|
321
|
-
ctx.log?.error?.('retailerId not configured', {
|
|
322
|
-
hint: 'Set FLUENT_RETAILER_ID activation variable',
|
|
323
|
-
docs: 'See batch-api-guide.md for configuration options'
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
throw error;
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
### Configuration Best Practices
|
|
332
|
-
|
|
333
|
-
**Recommended:** Use connection variables for retailerId
|
|
334
|
-
```typescript
|
|
335
|
-
// Configure in Versori Connection UI:
|
|
336
|
-
// Custom Parameters (JSON):
|
|
337
|
-
{
|
|
338
|
-
"retailerId": "1"
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// SDK auto-detects - no code changes needed
|
|
342
|
-
const client = await createClient(ctx);
|
|
343
|
-
await client.sendEvent(event); // ✅ Works automatically
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
**Alternative:** Use activation variables
|
|
347
|
-
```typescript
|
|
348
|
-
// Set in Versori connector activation
|
|
349
|
-
const fluentRetailerId = ctx.activation?.getVariable('FLUENT_RETAILER_ID');
|
|
350
|
-
client.setRetailerId(fluentRetailerId);
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
**Last Resort:** Hardcode (not recommended for production)
|
|
354
|
-
```typescript
|
|
355
|
-
client.setRetailerId('1'); // ❌ Not environment-agnostic
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Template Update Checklist
|
|
361
|
-
|
|
362
|
-
When updating templates, add the pattern:
|
|
363
|
-
|
|
364
|
-
- [ ] Add comment explaining optional validation
|
|
365
|
-
- [ ] Check activation variable `validateConnectionOnStart`
|
|
366
|
-
- [ ] Pass options to `createClient()` conditionally
|
|
367
|
-
- [ ] Log success when validation is enabled
|
|
368
|
-
- [ ] Keep default behavior (fast, no validation)
|
|
369
|
-
|
|
370
|
-
---
|
|
371
|
-
|
|
372
|
-
## Production Patterns
|
|
373
|
-
|
|
374
|
-
### Pattern: Client Initialization with retailerId
|
|
375
|
-
|
|
376
|
-
When using Event API or Batch API operations, `retailerId` must be configured on the client after creation.
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
// ✅ Complete client initialization pattern
|
|
380
|
-
export const dailyInventorySync = schedule('daily-inventory-sync', '*/5 * * * *').then(
|
|
381
|
-
http('run-inventory-batch', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
382
|
-
const { log, activation } = ctx;
|
|
383
|
-
|
|
384
|
-
// Step 1: Create client (optionally with validation)
|
|
385
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
386
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
387
|
-
|
|
388
|
-
if (validateConnection) {
|
|
389
|
-
log.info('✅ Connection validated successfully - authentication confirmed');
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// Step 2: Configure retailerId for Event/Batch API operations
|
|
393
|
-
const fluentRetailerId = activation.getVariable('fluentRetailerId');
|
|
394
|
-
if (!fluentRetailerId) {
|
|
395
|
-
log.error('❌ Missing required fluentRetailerId activation variable');
|
|
396
|
-
return {
|
|
397
|
-
success: false,
|
|
398
|
-
error: 'fluentRetailerId activation variable is required for Event API operations',
|
|
399
|
-
recommendation: 'Please configure fluentRetailerId in the Activation Variables section',
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
client.setRetailerId(fluentRetailerId);
|
|
404
|
-
log.info('✅ Client initialized with retailerId', { retailerId: fluentRetailerId });
|
|
405
|
-
|
|
406
|
-
// Step 3: Proceed with Event/Batch API operations
|
|
407
|
-
// ... business logic
|
|
408
|
-
})
|
|
409
|
-
);
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### Pattern: Credential Retrieval from Connections
|
|
413
|
-
|
|
414
|
-
For workflows requiring SFTP or external service credentials:
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
import { Buffer } from 'node:buffer';
|
|
418
|
-
|
|
419
|
-
export const sftpIngestion = schedule('sftp-ingestion', '*/5 * * * *').then(
|
|
420
|
-
http('process-files', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
421
|
-
const { log } = ctx;
|
|
422
|
-
|
|
423
|
-
try {
|
|
424
|
-
// ✅ Retrieve credentials from connection configuration
|
|
425
|
-
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
426
|
-
|
|
427
|
-
if (!sftpCred?.accessToken) {
|
|
428
|
-
throw new Error('No SFTP credentials found in connection configuration');
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// Decode base64 accessToken to get "username:password"
|
|
432
|
-
const rawBasicAuth = Buffer.from(sftpCred.accessToken, 'base64').toString('utf-8');
|
|
433
|
-
const parts = rawBasicAuth.split(':');
|
|
434
|
-
|
|
435
|
-
if (parts.length !== 2) {
|
|
436
|
-
throw new Error('Invalid SFTP credential format - expected username:password');
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
const [sftpUsername, sftpPassword] = parts;
|
|
440
|
-
|
|
441
|
-
log.info('✅ SFTP credentials retrieved successfully', {
|
|
442
|
-
hasUsername: !!sftpUsername,
|
|
443
|
-
hasPassword: !!sftpPassword,
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
// Use credentials with SftpDataSource
|
|
447
|
-
const sftp = new SftpDataSource({
|
|
448
|
-
type: 'SFTP_XML',
|
|
449
|
-
connectionId: 'sftp-inventory-sync',
|
|
450
|
-
name: 'inventory-sync',
|
|
451
|
-
settings: {
|
|
452
|
-
host: activation.getVariable('sftpHost'),
|
|
453
|
-
port: parseInt(activation.getVariable('sftpPort') || '22', 10),
|
|
454
|
-
username: sftpUsername,
|
|
455
|
-
password: sftpPassword,
|
|
456
|
-
// ... other settings
|
|
457
|
-
},
|
|
458
|
-
}, log);
|
|
459
|
-
|
|
460
|
-
// Always dispose when done
|
|
461
|
-
try {
|
|
462
|
-
// ... file processing
|
|
463
|
-
} finally {
|
|
464
|
-
await sftp.dispose();
|
|
465
|
-
log.info('✅ SFTP connection disposed successfully');
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
} catch (error: any) {
|
|
469
|
-
log.error('❌ Failed to retrieve SFTP credentials', {
|
|
470
|
-
message: error instanceof Error ? error.message : String(error),
|
|
471
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
return {
|
|
475
|
-
success: false,
|
|
476
|
-
error: 'Failed to retrieve SFTP credentials from connection configuration',
|
|
477
|
-
details: error?.message,
|
|
478
|
-
recommendation: 'Please ensure the SFTP connection is configured with Basic Authentication',
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
})
|
|
482
|
-
);
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
### Pattern: Complete Error Handling with Recommendations
|
|
486
|
-
|
|
487
|
-
Production-ready error handling with actionable recommendations:
|
|
488
|
-
|
|
489
|
-
```typescript
|
|
490
|
-
try {
|
|
491
|
-
// Client creation and validation
|
|
492
|
-
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
493
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
494
|
-
|
|
495
|
-
if (validateConnection) {
|
|
496
|
-
log.info('✅ Connection validated successfully');
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// Business logic...
|
|
500
|
-
|
|
501
|
-
} catch (error: any) {
|
|
502
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
503
|
-
const errorType = error instanceof Error ? error.constructor.name : 'Error';
|
|
504
|
-
|
|
505
|
-
// 🔍 Enhanced error logging with contextual recommendations
|
|
506
|
-
log.error('❌ Workflow execution failed', {
|
|
507
|
-
error: errorMessage,
|
|
508
|
-
errorType,
|
|
509
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
510
|
-
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
511
|
-
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
512
|
-
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
513
|
-
? 'Check network connectivity and Fluent Commerce API availability'
|
|
514
|
-
: error.message?.includes('retailerId') || error.message?.includes('RETAILER_ID')
|
|
515
|
-
? 'Verify fluentRetailerId activation variable is configured for Event/Batch API operations'
|
|
516
|
-
: error.message?.includes('SFTP') || error.message?.includes('credentials')
|
|
517
|
-
? 'Verify SFTP connection is configured with valid Basic Authentication credentials'
|
|
518
|
-
: 'Review error details and verify workflow configuration',
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
return {
|
|
522
|
-
success: false,
|
|
523
|
-
error: errorMessage,
|
|
524
|
-
errorType,
|
|
525
|
-
recommendation: 'See logs for detailed troubleshooting guidance',
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### Pattern: Emoji Logging for Better Visibility
|
|
531
|
-
|
|
532
|
-
Use emojis consistently for visual scanning in logs:
|
|
533
|
-
|
|
534
|
-
```typescript
|
|
535
|
-
// ✅ Success states
|
|
536
|
-
log.info('✅ Connection validated successfully');
|
|
537
|
-
log.info('✅ Client initialized with retailerId', { retailerId });
|
|
538
|
-
log.info('✅ SFTP credentials retrieved successfully');
|
|
539
|
-
log.info('✅ File processed successfully', { fileName });
|
|
540
|
-
|
|
541
|
-
// ❌ Error states
|
|
542
|
-
log.error('❌ Missing required fluentRetailerId activation variable');
|
|
543
|
-
log.error('❌ Failed to retrieve SFTP credentials');
|
|
544
|
-
log.error('❌ Authentication failed');
|
|
545
|
-
|
|
546
|
-
// 🔍 Debugging/Investigation
|
|
547
|
-
log.info('🔍 Starting credential retrieval');
|
|
548
|
-
log.info('🔍 Processing file', { fileName });
|
|
549
|
-
|
|
550
|
-
// 📊 Stats/Metrics
|
|
551
|
-
log.info('📊 Processing complete', {
|
|
552
|
-
filesProcessed: 42,
|
|
553
|
-
filesSkipped: 3,
|
|
554
|
-
filesFailed: 1,
|
|
555
|
-
});
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
---
|
|
559
|
-
|
|
560
|
-
## Error Handling Best Practices
|
|
561
|
-
|
|
562
|
-
### 1. Structured Error Objects
|
|
563
|
-
|
|
564
|
-
Always include error type and actionable recommendations:
|
|
565
|
-
|
|
566
|
-
```typescript
|
|
567
|
-
catch (error: any) {
|
|
568
|
-
const errorDetails = {
|
|
569
|
-
message: error instanceof Error ? error.message : String(error),
|
|
570
|
-
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
571
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
572
|
-
recommendation: getRecommendation(error),
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
log.error('Operation failed', errorDetails);
|
|
576
|
-
return { success: false, ...errorDetails };
|
|
577
|
-
}
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
### 2. Context-Aware Recommendations
|
|
581
|
-
|
|
582
|
-
Provide specific guidance based on error patterns:
|
|
583
|
-
|
|
584
|
-
```typescript
|
|
585
|
-
function getRecommendation(error: any): string {
|
|
586
|
-
const message = error?.message?.toLowerCase() || '';
|
|
587
|
-
|
|
588
|
-
if (message.includes('authentication') || message.includes('401')) {
|
|
589
|
-
return 'Verify connection credentials in Connections section';
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
if (message.includes('connection') || message.includes('timeout')) {
|
|
593
|
-
return 'Check network connectivity and API availability';
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
if (message.includes('retailerid') || message.includes('retailer_id')) {
|
|
597
|
-
return 'Verify fluentRetailerId activation variable is configured';
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
if (message.includes('sftp') || message.includes('credentials')) {
|
|
601
|
-
return 'Verify SFTP connection with valid Basic Authentication';
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return 'Review error details and verify configuration';
|
|
605
|
-
}
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
### 3. Always Dispose Resources
|
|
609
|
-
|
|
610
|
-
Use try/finally to ensure cleanup:
|
|
611
|
-
|
|
612
|
-
```typescript
|
|
613
|
-
const sftp = new SftpDataSource(config, log);
|
|
614
|
-
|
|
615
|
-
try {
|
|
616
|
-
// File processing operations
|
|
617
|
-
const files = await sftp.listFiles();
|
|
618
|
-
// ... process files
|
|
619
|
-
} catch (error: any) {
|
|
620
|
-
log.error('Processing failed', { error: error.message });
|
|
621
|
-
throw error;
|
|
622
|
-
} finally {
|
|
623
|
-
// ✅ Always dispose, even on error
|
|
624
|
-
await sftp.dispose();
|
|
625
|
-
log.info('✅ SFTP connection disposed');
|
|
626
|
-
}
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
### 4. Validation Before Operations
|
|
630
|
-
|
|
631
|
-
Fail fast with clear error messages:
|
|
632
|
-
|
|
633
|
-
```typescript
|
|
634
|
-
// ✅ Validate required configuration early
|
|
635
|
-
const fluentRetailerId = activation.getVariable('fluentRetailerId');
|
|
636
|
-
|
|
637
|
-
if (!fluentRetailerId) {
|
|
638
|
-
log.error('❌ Missing required configuration');
|
|
639
|
-
return {
|
|
640
|
-
success: false,
|
|
641
|
-
error: 'fluentRetailerId activation variable is required',
|
|
642
|
-
recommendation: 'Configure fluentRetailerId in Activation Variables',
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// Proceed with validated configuration
|
|
647
|
-
client.setRetailerId(fluentRetailerId);
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
---
|
|
651
|
-
|
|
652
|
-
## Related Documentation
|
|
653
|
-
|
|
654
|
-
- [Client Architecture](../../../04-REFERENCE/architecture/architecture-02-client-architecture.md)
|
|
655
|
-
- [createClient API](../../../04-REFERENCE/architecture/architecture-02-client-architecture.md#best-practices)
|
|
656
|
-
|
|
1
|
+
# Connection Validation Pattern
|
|
2
|
+
|
|
3
|
+
**Pattern**: Optional connection validation for `createClient()` with fail-fast authentication checking
|
|
4
|
+
|
|
5
|
+
**Version**: SDK ^0.1.34+
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The `createClient()` function supports optional connection validation via the `validateConnection` option. When enabled, it executes a minimal GraphQL query (`query { me { ref } }`) to verify authentication immediately, providing fail-fast error detection.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Pattern: Make It Configurable
|
|
16
|
+
|
|
17
|
+
**Recommended Approach**: Use activation variable to enable/disable validation
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// ✅ OPTIONAL: Validate connection immediately (fail-fast mode)
|
|
21
|
+
// Set activation variable 'validateConnectionOnStart' = 'true' to enable
|
|
22
|
+
// When enabled: Executes query { me { ref } } to verify authentication
|
|
23
|
+
// When disabled: Fast creation, validation happens on first API call (default)
|
|
24
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
25
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
26
|
+
|
|
27
|
+
if (validateConnection) {
|
|
28
|
+
log.info('✅ Connection validated successfully - authentication confirmed', { jobId });
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## When to Use
|
|
35
|
+
|
|
36
|
+
### ✅ **Enable Validation** (`validateConnection: true`)
|
|
37
|
+
|
|
38
|
+
- **Webhook workflows** - Quick error responses to callers
|
|
39
|
+
- **Critical production workflows** - Fail-fast on auth errors
|
|
40
|
+
- **Long-running workflows** - Catch auth issues before processing
|
|
41
|
+
- **Debugging scenarios** - Verify credentials immediately
|
|
42
|
+
|
|
43
|
+
### ❌ **Disable Validation** (default)
|
|
44
|
+
|
|
45
|
+
- **High-frequency scheduled workflows** - Avoid extra API call overhead
|
|
46
|
+
- **Development/testing** - Speed matters more than early validation
|
|
47
|
+
- **Workflows that handle errors gracefully** - Errors surface on first API call anyway
|
|
48
|
+
- **Batch processing** - Multiple client creations per workflow
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Complete Examples
|
|
53
|
+
|
|
54
|
+
### Example 1: Webhook Workflow (Fail-Fast Recommended)
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
export const orderIngestion = webhook('order-ingestion')
|
|
58
|
+
.then(
|
|
59
|
+
http('process-order', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
60
|
+
const { log, activation } = ctx;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// ✅ Fail-fast: Validate connection immediately for webhooks
|
|
64
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
65
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
66
|
+
|
|
67
|
+
if (validateConnection) {
|
|
68
|
+
log.info('✅ Connection validated successfully - authentication confirmed');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Process order...
|
|
72
|
+
return { success: true };
|
|
73
|
+
|
|
74
|
+
} catch (error: any) {
|
|
75
|
+
// 🔍 Enhanced: Error logging with recommendations
|
|
76
|
+
log.error('[ConnectionValidation] Authentication failed', {
|
|
77
|
+
error: error instanceof Error ? error.message : String(error),
|
|
78
|
+
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
79
|
+
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
80
|
+
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
81
|
+
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
82
|
+
? 'Check network connectivity and Fluent Commerce API availability'
|
|
83
|
+
: 'Review error details and verify connection configuration'
|
|
84
|
+
});
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
)
|
|
89
|
+
.catch((ctx: Context<any>) => {
|
|
90
|
+
const error = ctx.data instanceof Error ? ctx.data : new Error(String(ctx.data));
|
|
91
|
+
const errorDetails = {
|
|
92
|
+
message: error instanceof Error ? error.message : String(error),
|
|
93
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
94
|
+
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
95
|
+
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
96
|
+
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
97
|
+
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
98
|
+
? 'Check network connectivity and Fluent Commerce API availability'
|
|
99
|
+
: 'Review error details and verify workflow configuration'
|
|
100
|
+
};
|
|
101
|
+
ctx.log.error('[ConnectionValidation] Workflow failed', errorDetails);
|
|
102
|
+
return { success: false, error: error.message, recommendation: errorDetails.recommendation };
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Example 2: Scheduled Workflow (Optional)
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
export const scheduledProductIngestion = schedule('product-ingestion', '0 * * * *')
|
|
110
|
+
.then(
|
|
111
|
+
http('execute-ingestion', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
112
|
+
const { log, activation } = ctx;
|
|
113
|
+
|
|
114
|
+
// ✅ Optional: Validate connection (configurable via activation variable)
|
|
115
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
116
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
117
|
+
|
|
118
|
+
if (validateConnection) {
|
|
119
|
+
log.info('✅ Connection validated successfully');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Process files...
|
|
123
|
+
return result;
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Example 3: Extraction Workflow
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
export async function executeInventoryPositionExtraction(
|
|
132
|
+
ctx: VersoriContext,
|
|
133
|
+
params: ExtractionParams
|
|
134
|
+
): Promise<ExtractionResult> {
|
|
135
|
+
const { log, openKv, activation } = ctx;
|
|
136
|
+
|
|
137
|
+
// ✅ Optional: Validate connection immediately (fail-fast mode)
|
|
138
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
139
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
140
|
+
|
|
141
|
+
if (validateConnection) {
|
|
142
|
+
log.info('✅ Connection validated successfully - authentication confirmed', { jobId });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Continue with extraction...
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Activation Variable Configuration
|
|
152
|
+
|
|
153
|
+
**Variable Name**: `validateConnectionOnStart`
|
|
154
|
+
|
|
155
|
+
**Values**:
|
|
156
|
+
- `'true'` - Enable validation (fail-fast mode)
|
|
157
|
+
- `'false'` or unset - Disable validation (fast creation, default)
|
|
158
|
+
|
|
159
|
+
**How to Set**:
|
|
160
|
+
1. Go to Versori Activation Variables
|
|
161
|
+
2. Add variable: `validateConnectionOnStart` = `true`
|
|
162
|
+
3. Save activation
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Benefits
|
|
167
|
+
|
|
168
|
+
✅ **Fail-Fast**: Catch auth errors immediately, not on first API call
|
|
169
|
+
✅ **Better Logging**: "authenticated" vs "instance created"
|
|
170
|
+
✅ **Configurable**: Enable only when needed
|
|
171
|
+
✅ **Performance**: No overhead when disabled (default)
|
|
172
|
+
✅ **Backward Compatible**: Existing templates work unchanged
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Default Behavior
|
|
177
|
+
|
|
178
|
+
**Without `validateConnection` option** (default):
|
|
179
|
+
- Fast client creation
|
|
180
|
+
- No API call during creation
|
|
181
|
+
- Validation happens on first API call
|
|
182
|
+
- Errors surface when you try to use the client
|
|
183
|
+
|
|
184
|
+
**With `validateConnection: true`**:
|
|
185
|
+
- Executes `query { me { ref } }` immediately
|
|
186
|
+
- Fails fast if authentication is invalid
|
|
187
|
+
- Logs "created and authenticated" on success
|
|
188
|
+
- Logs "Connection validation failed" on error
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Automatic Connection Validation (v0.1.40+)
|
|
193
|
+
|
|
194
|
+
**SDK Automatic Checks:**
|
|
195
|
+
|
|
196
|
+
When you call `createClient(ctx)`, the SDK automatically validates:
|
|
197
|
+
|
|
198
|
+
### 1. ctx.fetch Presence (CRITICAL)
|
|
199
|
+
|
|
200
|
+
**Validates:** `ctx.fetch` exists
|
|
201
|
+
**Throws:** `"Invalid Versori context: ctx.fetch is required. Ensure you are running in Versori platform and using createClient(ctx)."`
|
|
202
|
+
**Purpose:** Ensures running in Versori runtime environment
|
|
203
|
+
|
|
204
|
+
**Example:**
|
|
205
|
+
```typescript
|
|
206
|
+
// ❌ Wrong context - will throw
|
|
207
|
+
const invalidCtx = { log: console };
|
|
208
|
+
const client = await createClient(invalidCtx);
|
|
209
|
+
// Error: Invalid Versori context: ctx.fetch is required...
|
|
210
|
+
|
|
211
|
+
// ✅ Correct Versori context
|
|
212
|
+
const client = await createClient(ctx); // ctx from Versori workflow
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 2. retailerId Detection (WARNING)
|
|
216
|
+
|
|
217
|
+
**Attempts extraction from:**
|
|
218
|
+
1. `ctx.connectionVariables.retailerId` (priority 1)
|
|
219
|
+
2. `baseUrl` path regex `/\/retailer\/([^/]+)\/?$/` (priority 2)
|
|
220
|
+
|
|
221
|
+
**Logs WARNING if not found:**
|
|
222
|
+
- Message: `"[fc-connect-sdk:client] No retailerId found in connection config or baseUrl"`
|
|
223
|
+
- Hint: `"Set connection.retailerId or use client.setRetailerId() for Event/Job/Batch APIs"`
|
|
224
|
+
- Docs: `"GraphQL queries work without retailerId, but Event/Job/Batch APIs require it"`
|
|
225
|
+
|
|
226
|
+
**Not an error because:**
|
|
227
|
+
- retailerId is only required for Event/Job/Batch APIs
|
|
228
|
+
- GraphQL queries work without retailerId
|
|
229
|
+
- Can be set later via `client.setRetailerId()`
|
|
230
|
+
|
|
231
|
+
**Example:**
|
|
232
|
+
```typescript
|
|
233
|
+
// Scenario 1: retailerId in connection variables
|
|
234
|
+
const ctx = {
|
|
235
|
+
fetch: versoriManagedFetch,
|
|
236
|
+
log: versoriLog,
|
|
237
|
+
connectionVariables: { retailerId: '1' }
|
|
238
|
+
};
|
|
239
|
+
const client = await createClient(ctx);
|
|
240
|
+
// ✅ Log: "[fc-connect-sdk:client] Using retailerId from connection variables"
|
|
241
|
+
|
|
242
|
+
// Scenario 2: retailerId in baseUrl
|
|
243
|
+
const ctx = {
|
|
244
|
+
fetch: versoriManagedFetch,
|
|
245
|
+
log: versoriLog,
|
|
246
|
+
baseUrl: 'https://api.fluentcommerce.com/retailer/123'
|
|
247
|
+
};
|
|
248
|
+
const client = await createClient(ctx);
|
|
249
|
+
// ✅ Log: "[fc-connect-sdk:client] Extracted retailerId from baseUrl"
|
|
250
|
+
|
|
251
|
+
// Scenario 3: No retailerId
|
|
252
|
+
const ctx = {
|
|
253
|
+
fetch: versoriManagedFetch,
|
|
254
|
+
log: versoriLog,
|
|
255
|
+
baseUrl: 'https://api.fluentcommerce.com'
|
|
256
|
+
};
|
|
257
|
+
const client = await createClient(ctx);
|
|
258
|
+
// ⚠️ Warning: "No retailerId found..." (but still creates client)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 3. ctx.log Check
|
|
262
|
+
|
|
263
|
+
**Validates:** `ctx.log` exists
|
|
264
|
+
**Action:** Logs warning to console if missing (logs will be disabled)
|
|
265
|
+
**Does not throw:** SDK continues without logging
|
|
266
|
+
|
|
267
|
+
### When retailerId is REQUIRED
|
|
268
|
+
|
|
269
|
+
**✅ Required for:**
|
|
270
|
+
- `sendEvent()` - Validated before API call
|
|
271
|
+
- `createJob()` - Validated before API call
|
|
272
|
+
- Batch operations - Validated in job payload
|
|
273
|
+
|
|
274
|
+
**❌ NOT Required for:**
|
|
275
|
+
- `graphql()` - Works without retailerId
|
|
276
|
+
- `query()` - Works without retailerId
|
|
277
|
+
- `mutate()` - Works without retailerId
|
|
278
|
+
|
|
279
|
+
**Validation happens at API call time:**
|
|
280
|
+
```typescript
|
|
281
|
+
// Step 1: Create client (warning logged if no retailerId)
|
|
282
|
+
const client = await createClient(ctx);
|
|
283
|
+
// ⚠️ Warning: "No retailerId found..."
|
|
284
|
+
|
|
285
|
+
// Step 2: Try to use Event API (validation throws error)
|
|
286
|
+
await client.sendEvent(event);
|
|
287
|
+
// ❌ Error: "retailerId is required for Event API..."
|
|
288
|
+
|
|
289
|
+
// Step 3: Fix by setting retailerId
|
|
290
|
+
client.setRetailerId('1');
|
|
291
|
+
await client.sendEvent(event);
|
|
292
|
+
// ✅ Works!
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Example Validation Flow
|
|
296
|
+
|
|
297
|
+
**Complete validation flow with all checks:**
|
|
298
|
+
```typescript
|
|
299
|
+
export const workflow = http('inventory-sync', {
|
|
300
|
+
connection: 'fluent_commerce'
|
|
301
|
+
}, async (ctx) => {
|
|
302
|
+
// STEP 1: Automatic validation during createClient()
|
|
303
|
+
const client = await createClient(ctx);
|
|
304
|
+
// ✅ ctx.fetch validated (throws if missing)
|
|
305
|
+
// ⚠️ retailerId detection attempted (warning if missing)
|
|
306
|
+
// ✅ ctx.log checked (console warning if missing)
|
|
307
|
+
|
|
308
|
+
// STEP 2: Configure retailerId if using Event/Job/Batch APIs
|
|
309
|
+
const fluentRetailerId = ctx.activation?.getVariable('FLUENT_RETAILER_ID');
|
|
310
|
+
if (fluentRetailerId) {
|
|
311
|
+
client.setRetailerId(fluentRetailerId);
|
|
312
|
+
ctx.log?.info?.('retailerId configured', { retailerId: fluentRetailerId });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// STEP 3: API call (automatic validation before request)
|
|
316
|
+
try {
|
|
317
|
+
await client.sendEvent(event);
|
|
318
|
+
// ✅ Validates retailerId exists before API call
|
|
319
|
+
} catch (error) {
|
|
320
|
+
if (error.message.includes('retailerId is required')) {
|
|
321
|
+
ctx.log?.error?.('retailerId not configured', {
|
|
322
|
+
hint: 'Set FLUENT_RETAILER_ID activation variable',
|
|
323
|
+
docs: 'See batch-api-guide.md for configuration options'
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Configuration Best Practices
|
|
332
|
+
|
|
333
|
+
**Recommended:** Use connection variables for retailerId
|
|
334
|
+
```typescript
|
|
335
|
+
// Configure in Versori Connection UI:
|
|
336
|
+
// Custom Parameters (JSON):
|
|
337
|
+
{
|
|
338
|
+
"retailerId": "1"
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// SDK auto-detects - no code changes needed
|
|
342
|
+
const client = await createClient(ctx);
|
|
343
|
+
await client.sendEvent(event); // ✅ Works automatically
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Alternative:** Use activation variables
|
|
347
|
+
```typescript
|
|
348
|
+
// Set in Versori connector activation
|
|
349
|
+
const fluentRetailerId = ctx.activation?.getVariable('FLUENT_RETAILER_ID');
|
|
350
|
+
client.setRetailerId(fluentRetailerId);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Last Resort:** Hardcode (not recommended for production)
|
|
354
|
+
```typescript
|
|
355
|
+
client.setRetailerId('1'); // ❌ Not environment-agnostic
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Template Update Checklist
|
|
361
|
+
|
|
362
|
+
When updating templates, add the pattern:
|
|
363
|
+
|
|
364
|
+
- [ ] Add comment explaining optional validation
|
|
365
|
+
- [ ] Check activation variable `validateConnectionOnStart`
|
|
366
|
+
- [ ] Pass options to `createClient()` conditionally
|
|
367
|
+
- [ ] Log success when validation is enabled
|
|
368
|
+
- [ ] Keep default behavior (fast, no validation)
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Production Patterns
|
|
373
|
+
|
|
374
|
+
### Pattern: Client Initialization with retailerId
|
|
375
|
+
|
|
376
|
+
When using Event API or Batch API operations, `retailerId` must be configured on the client after creation.
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// ✅ Complete client initialization pattern
|
|
380
|
+
export const dailyInventorySync = schedule('daily-inventory-sync', '*/5 * * * *').then(
|
|
381
|
+
http('run-inventory-batch', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
382
|
+
const { log, activation } = ctx;
|
|
383
|
+
|
|
384
|
+
// Step 1: Create client (optionally with validation)
|
|
385
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
386
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
387
|
+
|
|
388
|
+
if (validateConnection) {
|
|
389
|
+
log.info('✅ Connection validated successfully - authentication confirmed');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Step 2: Configure retailerId for Event/Batch API operations
|
|
393
|
+
const fluentRetailerId = activation.getVariable('fluentRetailerId');
|
|
394
|
+
if (!fluentRetailerId) {
|
|
395
|
+
log.error('❌ Missing required fluentRetailerId activation variable');
|
|
396
|
+
return {
|
|
397
|
+
success: false,
|
|
398
|
+
error: 'fluentRetailerId activation variable is required for Event API operations',
|
|
399
|
+
recommendation: 'Please configure fluentRetailerId in the Activation Variables section',
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
client.setRetailerId(fluentRetailerId);
|
|
404
|
+
log.info('✅ Client initialized with retailerId', { retailerId: fluentRetailerId });
|
|
405
|
+
|
|
406
|
+
// Step 3: Proceed with Event/Batch API operations
|
|
407
|
+
// ... business logic
|
|
408
|
+
})
|
|
409
|
+
);
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Pattern: Credential Retrieval from Connections
|
|
413
|
+
|
|
414
|
+
For workflows requiring SFTP or external service credentials:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import { Buffer } from 'node:buffer';
|
|
418
|
+
|
|
419
|
+
export const sftpIngestion = schedule('sftp-ingestion', '*/5 * * * *').then(
|
|
420
|
+
http('process-files', { connection: 'fluent_commerce' }, async (ctx) => {
|
|
421
|
+
const { log } = ctx;
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
// ✅ Retrieve credentials from connection configuration
|
|
425
|
+
const sftpCred = await ctx.credentials().getAccessToken('SFTP');
|
|
426
|
+
|
|
427
|
+
if (!sftpCred?.accessToken) {
|
|
428
|
+
throw new Error('No SFTP credentials found in connection configuration');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Decode base64 accessToken to get "username:password"
|
|
432
|
+
const rawBasicAuth = Buffer.from(sftpCred.accessToken, 'base64').toString('utf-8');
|
|
433
|
+
const parts = rawBasicAuth.split(':');
|
|
434
|
+
|
|
435
|
+
if (parts.length !== 2) {
|
|
436
|
+
throw new Error('Invalid SFTP credential format - expected username:password');
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const [sftpUsername, sftpPassword] = parts;
|
|
440
|
+
|
|
441
|
+
log.info('✅ SFTP credentials retrieved successfully', {
|
|
442
|
+
hasUsername: !!sftpUsername,
|
|
443
|
+
hasPassword: !!sftpPassword,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Use credentials with SftpDataSource
|
|
447
|
+
const sftp = new SftpDataSource({
|
|
448
|
+
type: 'SFTP_XML',
|
|
449
|
+
connectionId: 'sftp-inventory-sync',
|
|
450
|
+
name: 'inventory-sync',
|
|
451
|
+
settings: {
|
|
452
|
+
host: activation.getVariable('sftpHost'),
|
|
453
|
+
port: parseInt(activation.getVariable('sftpPort') || '22', 10),
|
|
454
|
+
username: sftpUsername,
|
|
455
|
+
password: sftpPassword,
|
|
456
|
+
// ... other settings
|
|
457
|
+
},
|
|
458
|
+
}, log);
|
|
459
|
+
|
|
460
|
+
// Always dispose when done
|
|
461
|
+
try {
|
|
462
|
+
// ... file processing
|
|
463
|
+
} finally {
|
|
464
|
+
await sftp.dispose();
|
|
465
|
+
log.info('✅ SFTP connection disposed successfully');
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
} catch (error: any) {
|
|
469
|
+
log.error('❌ Failed to retrieve SFTP credentials', {
|
|
470
|
+
message: error instanceof Error ? error.message : String(error),
|
|
471
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
return {
|
|
475
|
+
success: false,
|
|
476
|
+
error: 'Failed to retrieve SFTP credentials from connection configuration',
|
|
477
|
+
details: error?.message,
|
|
478
|
+
recommendation: 'Please ensure the SFTP connection is configured with Basic Authentication',
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
})
|
|
482
|
+
);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Pattern: Complete Error Handling with Recommendations
|
|
486
|
+
|
|
487
|
+
Production-ready error handling with actionable recommendations:
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
try {
|
|
491
|
+
// Client creation and validation
|
|
492
|
+
const validateConnection = activation.getVariable('validateConnectionOnStart') === 'true';
|
|
493
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
494
|
+
|
|
495
|
+
if (validateConnection) {
|
|
496
|
+
log.info('✅ Connection validated successfully');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Business logic...
|
|
500
|
+
|
|
501
|
+
} catch (error: any) {
|
|
502
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
503
|
+
const errorType = error instanceof Error ? error.constructor.name : 'Error';
|
|
504
|
+
|
|
505
|
+
// 🔍 Enhanced error logging with contextual recommendations
|
|
506
|
+
log.error('❌ Workflow execution failed', {
|
|
507
|
+
error: errorMessage,
|
|
508
|
+
errorType,
|
|
509
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
510
|
+
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
511
|
+
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
512
|
+
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
513
|
+
? 'Check network connectivity and Fluent Commerce API availability'
|
|
514
|
+
: error.message?.includes('retailerId') || error.message?.includes('RETAILER_ID')
|
|
515
|
+
? 'Verify fluentRetailerId activation variable is configured for Event/Batch API operations'
|
|
516
|
+
: error.message?.includes('SFTP') || error.message?.includes('credentials')
|
|
517
|
+
? 'Verify SFTP connection is configured with valid Basic Authentication credentials'
|
|
518
|
+
: 'Review error details and verify workflow configuration',
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
return {
|
|
522
|
+
success: false,
|
|
523
|
+
error: errorMessage,
|
|
524
|
+
errorType,
|
|
525
|
+
recommendation: 'See logs for detailed troubleshooting guidance',
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Pattern: Emoji Logging for Better Visibility
|
|
531
|
+
|
|
532
|
+
Use emojis consistently for visual scanning in logs:
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
// ✅ Success states
|
|
536
|
+
log.info('✅ Connection validated successfully');
|
|
537
|
+
log.info('✅ Client initialized with retailerId', { retailerId });
|
|
538
|
+
log.info('✅ SFTP credentials retrieved successfully');
|
|
539
|
+
log.info('✅ File processed successfully', { fileName });
|
|
540
|
+
|
|
541
|
+
// ❌ Error states
|
|
542
|
+
log.error('❌ Missing required fluentRetailerId activation variable');
|
|
543
|
+
log.error('❌ Failed to retrieve SFTP credentials');
|
|
544
|
+
log.error('❌ Authentication failed');
|
|
545
|
+
|
|
546
|
+
// 🔍 Debugging/Investigation
|
|
547
|
+
log.info('🔍 Starting credential retrieval');
|
|
548
|
+
log.info('🔍 Processing file', { fileName });
|
|
549
|
+
|
|
550
|
+
// 📊 Stats/Metrics
|
|
551
|
+
log.info('📊 Processing complete', {
|
|
552
|
+
filesProcessed: 42,
|
|
553
|
+
filesSkipped: 3,
|
|
554
|
+
filesFailed: 1,
|
|
555
|
+
});
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## Error Handling Best Practices
|
|
561
|
+
|
|
562
|
+
### 1. Structured Error Objects
|
|
563
|
+
|
|
564
|
+
Always include error type and actionable recommendations:
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
catch (error: any) {
|
|
568
|
+
const errorDetails = {
|
|
569
|
+
message: error instanceof Error ? error.message : String(error),
|
|
570
|
+
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
571
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
572
|
+
recommendation: getRecommendation(error),
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
log.error('Operation failed', errorDetails);
|
|
576
|
+
return { success: false, ...errorDetails };
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### 2. Context-Aware Recommendations
|
|
581
|
+
|
|
582
|
+
Provide specific guidance based on error patterns:
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
function getRecommendation(error: any): string {
|
|
586
|
+
const message = error?.message?.toLowerCase() || '';
|
|
587
|
+
|
|
588
|
+
if (message.includes('authentication') || message.includes('401')) {
|
|
589
|
+
return 'Verify connection credentials in Connections section';
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (message.includes('connection') || message.includes('timeout')) {
|
|
593
|
+
return 'Check network connectivity and API availability';
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (message.includes('retailerid') || message.includes('retailer_id')) {
|
|
597
|
+
return 'Verify fluentRetailerId activation variable is configured';
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (message.includes('sftp') || message.includes('credentials')) {
|
|
601
|
+
return 'Verify SFTP connection with valid Basic Authentication';
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
return 'Review error details and verify configuration';
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### 3. Always Dispose Resources
|
|
609
|
+
|
|
610
|
+
Use try/finally to ensure cleanup:
|
|
611
|
+
|
|
612
|
+
```typescript
|
|
613
|
+
const sftp = new SftpDataSource(config, log);
|
|
614
|
+
|
|
615
|
+
try {
|
|
616
|
+
// File processing operations
|
|
617
|
+
const files = await sftp.listFiles();
|
|
618
|
+
// ... process files
|
|
619
|
+
} catch (error: any) {
|
|
620
|
+
log.error('Processing failed', { error: error.message });
|
|
621
|
+
throw error;
|
|
622
|
+
} finally {
|
|
623
|
+
// ✅ Always dispose, even on error
|
|
624
|
+
await sftp.dispose();
|
|
625
|
+
log.info('✅ SFTP connection disposed');
|
|
626
|
+
}
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### 4. Validation Before Operations
|
|
630
|
+
|
|
631
|
+
Fail fast with clear error messages:
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
// ✅ Validate required configuration early
|
|
635
|
+
const fluentRetailerId = activation.getVariable('fluentRetailerId');
|
|
636
|
+
|
|
637
|
+
if (!fluentRetailerId) {
|
|
638
|
+
log.error('❌ Missing required configuration');
|
|
639
|
+
return {
|
|
640
|
+
success: false,
|
|
641
|
+
error: 'fluentRetailerId activation variable is required',
|
|
642
|
+
recommendation: 'Configure fluentRetailerId in Activation Variables',
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Proceed with validated configuration
|
|
647
|
+
client.setRetailerId(fluentRetailerId);
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
## Related Documentation
|
|
653
|
+
|
|
654
|
+
- [Client Architecture](../../../04-REFERENCE/architecture/architecture-02-client-architecture.md)
|
|
655
|
+
- [createClient API](../../../04-REFERENCE/architecture/architecture-02-client-architecture.md#best-practices)
|
|
656
|
+
|