@fluentcommerce/fc-connect-sdk 0.1.53 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -2
- package/README.md +39 -0
- package/dist/cjs/auth/index.d.ts +3 -0
- package/dist/cjs/auth/index.js +13 -0
- package/dist/cjs/auth/profile-loader.d.ts +18 -0
- package/dist/cjs/auth/profile-loader.js +208 -0
- package/dist/cjs/client-factory.d.ts +4 -0
- package/dist/cjs/client-factory.js +10 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/auth/index.d.ts +3 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/profile-loader.d.ts +18 -0
- package/dist/esm/auth/profile-loader.js +169 -0
- package/dist/esm/client-factory.d.ts +4 -0
- package/dist/esm/client-factory.js +9 -0
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/auth/index.d.ts +3 -0
- package/dist/types/auth/profile-loader.d.ts +18 -0
- package/dist/types/client-factory.d.ts +4 -0
- package/dist/types/index.d.ts +3 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -482
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
|
@@ -1,701 +1,701 @@
|
|
|
1
|
-
# Pattern: Universal Field Mapping
|
|
2
|
-
|
|
3
|
-
**FC Connect SDK Use Case Guide**
|
|
4
|
-
|
|
5
|
-
> **SDK**: [@fluentcommerce/fc-connect-sdk](https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk)
|
|
6
|
-
> **Version**: Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
7
|
-
|
|
8
|
-
**Context**: Focused guide on UniversalMapper for transforming data between formats
|
|
9
|
-
|
|
10
|
-
**Type**: Reusable Pattern
|
|
11
|
-
|
|
12
|
-
**Complexity**: Low-Medium
|
|
13
|
-
|
|
14
|
-
**Lines**: ~200 lines
|
|
15
|
-
|
|
16
|
-
## When to Use This Pattern
|
|
17
|
-
|
|
18
|
-
- Transforming CSV/JSON/XML to Fluent format
|
|
19
|
-
- Extracting Fluent data for export
|
|
20
|
-
- Data normalization and validation
|
|
21
|
-
- Type conversions and formatting
|
|
22
|
-
- Building GraphQL mutation inputs
|
|
23
|
-
- Generating XML/JSON output structures
|
|
24
|
-
|
|
25
|
-
## SDK Methods
|
|
26
|
-
|
|
27
|
-
- `UniversalMapper(config, options)` - Create mapper instance
|
|
28
|
-
- `mapper.map(sourceData)` - Transform single record
|
|
29
|
-
- `mapper.registerResolver(name, fn)` - Add custom resolver
|
|
30
|
-
- `mapper.registerResolvers(map)` - Add multiple custom resolvers
|
|
31
|
-
- SDK Resolvers: `sdk.*` prefix (15 built-in)
|
|
32
|
-
- Custom resolvers: Your own transformation functions
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Basic Mapping
|
|
37
|
-
|
|
38
|
-
### Simple Field Mapping
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
// FC Connect SDK (latest)
|
|
42
|
-
// Install: npm install @fluentcommerce/fc-connect-sdk@latest
|
|
43
|
-
// Docs: https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk
|
|
44
|
-
// GitHub: https://github.com/fluentcommerce/fc-connect-sdk
|
|
45
|
-
|
|
46
|
-
import { UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
47
|
-
|
|
48
|
-
const config = {
|
|
49
|
-
fields: {
|
|
50
|
-
// Direct mapping - no transformation
|
|
51
|
-
customerEmail: {
|
|
52
|
-
source: 'email',
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
// Map with transformation
|
|
56
|
-
status: {
|
|
57
|
-
source: 'orderStatus',
|
|
58
|
-
resolver: 'sdk.uppercase',
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// Required field with validation
|
|
62
|
-
productSku: {
|
|
63
|
-
source: 'sku',
|
|
64
|
-
required: true,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const mapper = new UniversalMapper(config);
|
|
70
|
-
|
|
71
|
-
// Transform data
|
|
72
|
-
const sourceData = { email: 'john@example.com', orderStatus: 'pending', sku: 'PROD-001' };
|
|
73
|
-
const result = await mapper.map(sourceData);
|
|
74
|
-
|
|
75
|
-
if (result.success) {
|
|
76
|
-
console.log(result.data);
|
|
77
|
-
// { customerEmail: 'john@example.com', status: 'PENDING', productSku: 'PROD-001' }
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Static Values
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
const config = {
|
|
85
|
-
fields: {
|
|
86
|
-
type: {
|
|
87
|
-
value: 'STANDARD', // Always returns "STANDARD"
|
|
88
|
-
},
|
|
89
|
-
retailerId: {
|
|
90
|
-
value: 1, // Static numeric value
|
|
91
|
-
},
|
|
92
|
-
version: {
|
|
93
|
-
value: '2.0',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Default Values
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
const config = {
|
|
103
|
-
fields: {
|
|
104
|
-
status: {
|
|
105
|
-
source: 'orderStatus',
|
|
106
|
-
defaultValue: 'PENDING', // Used if source is missing/empty
|
|
107
|
-
},
|
|
108
|
-
quantity: {
|
|
109
|
-
source: 'qty',
|
|
110
|
-
resolver: 'sdk.parseInt',
|
|
111
|
-
defaultValue: 0, // Fallback for missing quantity
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## SDK Resolver Patterns
|
|
120
|
-
|
|
121
|
-
### String Transformations
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
const config = {
|
|
125
|
-
fields: {
|
|
126
|
-
// Convert to uppercase
|
|
127
|
-
countryCode: {
|
|
128
|
-
source: 'country',
|
|
129
|
-
resolver: 'sdk.uppercase', // "us" → "US"
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
// Convert to lowercase
|
|
133
|
-
email: {
|
|
134
|
-
source: 'customerEmail',
|
|
135
|
-
resolver: 'sdk.lowercase', // "JOHN@EXAMPLE.COM" → "john@example.com"
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
// Trim whitespace
|
|
139
|
-
sku: {
|
|
140
|
-
source: 'productSku',
|
|
141
|
-
resolver: 'sdk.trim', // " SKU123 " → "SKU123"
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
// Convert to string
|
|
145
|
-
orderId: {
|
|
146
|
-
source: 'order_id',
|
|
147
|
-
resolver: 'sdk.toString', // 12345 → "12345"
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Number Transformations
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
const config = {
|
|
157
|
-
fields: {
|
|
158
|
-
// Parse as integer
|
|
159
|
-
quantity: {
|
|
160
|
-
source: 'qty',
|
|
161
|
-
resolver: 'sdk.parseInt', // "123" → 123, "123.99" → 123
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
// Parse as float
|
|
165
|
-
price: {
|
|
166
|
-
source: 'total',
|
|
167
|
-
resolver: 'sdk.parseFloat', // "99.99" → 99.99, "$45.50" → 45.5
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
-
// Generic number parser (alias for parseFloat)
|
|
171
|
-
weight: {
|
|
172
|
-
source: 'weight_kg',
|
|
173
|
-
resolver: 'sdk.number', // "3.14" → 3.14
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Date Transformations
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
const config = {
|
|
183
|
-
fields: {
|
|
184
|
-
// Format to ISO8601 (Fluent API standard)
|
|
185
|
-
expectedOn: {
|
|
186
|
-
source: 'delivery_date',
|
|
187
|
-
resolver: 'sdk.formatDate', // "2024-01-15" → "2024-01-15T00:00:00.000Z"
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
// Format to YYYY-MM-DD
|
|
191
|
-
orderDate: {
|
|
192
|
-
source: 'created_at',
|
|
193
|
-
resolver: 'sdk.formatDateShort', // "2024-01-15T10:30:00Z" → "2024-01-15"
|
|
194
|
-
},
|
|
195
|
-
|
|
196
|
-
// Parse date string
|
|
197
|
-
scheduledDate: {
|
|
198
|
-
source: 'schedule',
|
|
199
|
-
resolver: 'sdk.parseDate', // "01/15/2024" → Date object
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Type Conversions
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
const config = {
|
|
209
|
-
fields: {
|
|
210
|
-
// Convert to boolean
|
|
211
|
-
isActive: {
|
|
212
|
-
source: 'active',
|
|
213
|
-
resolver: 'sdk.boolean', // "true", "1", "yes", "y" → true
|
|
214
|
-
},
|
|
215
|
-
|
|
216
|
-
// Parse JSON string
|
|
217
|
-
metadata: {
|
|
218
|
-
source: 'json_data',
|
|
219
|
-
resolver: 'sdk.parseJson', // '{"key":"value"}' → { key: "value" }
|
|
220
|
-
},
|
|
221
|
-
|
|
222
|
-
// Stringify to JSON
|
|
223
|
-
customAttributes: {
|
|
224
|
-
source: 'attributes',
|
|
225
|
-
resolver: 'sdk.toJson', // { name: "John" } → '{"name":"John"}'
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
};
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### Utility Resolvers
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
const config = {
|
|
235
|
-
fields: {
|
|
236
|
-
// Identity - no transformation
|
|
237
|
-
originalValue: {
|
|
238
|
-
source: 'rawData',
|
|
239
|
-
resolver: 'sdk.identity', // Pass through unchanged
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
// Coalesce - first non-null value
|
|
243
|
-
displayName: {
|
|
244
|
-
source: 'name',
|
|
245
|
-
resolver: 'sdk.coalesce',
|
|
246
|
-
defaultValue: 'Unknown', // Fallback if null/undefined
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
## Complete SDK Resolver Reference
|
|
255
|
-
|
|
256
|
-
### String Resolvers (4)
|
|
257
|
-
|
|
258
|
-
- `sdk.uppercase` - Convert to UPPERCASE
|
|
259
|
-
- `sdk.lowercase` - Convert to lowercase
|
|
260
|
-
- `sdk.trim` - Remove leading/trailing whitespace
|
|
261
|
-
- `sdk.toString` - Convert any value to string
|
|
262
|
-
|
|
263
|
-
### Number Resolvers (3)
|
|
264
|
-
|
|
265
|
-
- `sdk.parseInt` - Parse as integer (returns 0 for invalid)
|
|
266
|
-
- `sdk.parseFloat` - Parse as float (returns 0 for invalid)
|
|
267
|
-
- `sdk.number` - Alias for parseFloat
|
|
268
|
-
|
|
269
|
-
### Date Resolvers (3)
|
|
270
|
-
|
|
271
|
-
- `sdk.formatDate` - Format to ISO8601 (Fluent API standard)
|
|
272
|
-
- `sdk.formatDateShort` - Format to YYYY-MM-DD
|
|
273
|
-
- `sdk.parseDate` - Parse date string to Date object
|
|
274
|
-
|
|
275
|
-
### Type Conversion Resolvers (3)
|
|
276
|
-
|
|
277
|
-
- `sdk.boolean` - Convert to boolean (handles "true", "1", "yes", etc.)
|
|
278
|
-
- `sdk.parseJson` - Parse JSON string to object
|
|
279
|
-
- `sdk.toJson` - Stringify object to JSON
|
|
280
|
-
|
|
281
|
-
### Utility Resolvers (2)
|
|
282
|
-
|
|
283
|
-
- `sdk.identity` - Pass value through unchanged
|
|
284
|
-
- `sdk.coalesce` - Return first non-null value
|
|
285
|
-
|
|
286
|
-
**Total: 15 SDK Resolvers**
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
## Custom Resolver Patterns
|
|
291
|
-
|
|
292
|
-
### Basic Custom Resolver
|
|
293
|
-
|
|
294
|
-
```typescript
|
|
295
|
-
import { UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
296
|
-
|
|
297
|
-
const customResolvers = {
|
|
298
|
-
'custom.calculateTax': (value, sourceData, config, helpers) => {
|
|
299
|
-
const subtotal = helpers.parseFloatSafe(value, 0);
|
|
300
|
-
return subtotal * 0.1; // 10% tax
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
'custom.formatPhone': (value, sourceData, config, helpers) => {
|
|
304
|
-
// Remove non-digits
|
|
305
|
-
const digits = value.replace(/\D/g, '');
|
|
306
|
-
// Format as (XXX) XXX-XXXX
|
|
307
|
-
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
308
|
-
},
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
const mapper = new UniversalMapper(config, { customResolvers });
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Using Helper Functions
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
const customResolvers = {
|
|
318
|
-
'custom.cleanAndUpper': (value, sourceData, config, helpers) => {
|
|
319
|
-
// Use helpers for safe operations
|
|
320
|
-
const trimmed = helpers.normalizeWhitespace(value);
|
|
321
|
-
return trimmed.toUpperCase();
|
|
322
|
-
},
|
|
323
|
-
|
|
324
|
-
'custom.extractId': (value, sourceData, config, helpers) => {
|
|
325
|
-
// Safe nested property access
|
|
326
|
-
const product = helpers.get(sourceData, 'product.details') || {};
|
|
327
|
-
return product.id || 'UNKNOWN';
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Context-Aware Resolvers
|
|
333
|
-
|
|
334
|
-
> **⚠️ Important**: To use `helpers.fluentClient` or `helpers.context` in custom resolvers, you MUST pass them when creating the mapper. They are NOT available by default.
|
|
335
|
-
|
|
336
|
-
```typescript
|
|
337
|
-
const customResolvers = {
|
|
338
|
-
'custom.lookupCustomer': async (email, sourceData, config, helpers) => {
|
|
339
|
-
// Access fluentClient from helpers (passed via options)
|
|
340
|
-
if (!helpers.fluentClient) {
|
|
341
|
-
throw new Error('fluentClient not available');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const query = `query { customers(email: "${email}") { edges { node { id } } } }`;
|
|
345
|
-
const result = await helpers.fluentClient.graphql({ query });
|
|
346
|
-
return result.data.customers.edges[0]?.node.id;
|
|
347
|
-
},
|
|
348
|
-
|
|
349
|
-
'custom.addOrderContext': (value, sourceData, config, helpers) => {
|
|
350
|
-
// Access custom context
|
|
351
|
-
const orderId = helpers.context?.orderId;
|
|
352
|
-
return `${value}_${orderId}`;
|
|
353
|
-
},
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
// ✅ REQUIRED: Initialize mapper with fluentClient and context for async resolvers
|
|
357
|
-
const mapper = new UniversalMapper(config, {
|
|
358
|
-
customResolvers,
|
|
359
|
-
fluentClient: fluentClient, // ← Required for API access in resolvers
|
|
360
|
-
logger: console, // ← Required for helpers.log
|
|
361
|
-
context: { orderId: '12345', userId: '999' }, // ← Required for helpers.context
|
|
362
|
-
});
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
## Nested Field Patterns
|
|
368
|
-
|
|
369
|
-
### Nested Objects
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
const config = {
|
|
373
|
-
fields: {
|
|
374
|
-
// Simple nested field with dot notation
|
|
375
|
-
'customer.id': {
|
|
376
|
-
source: 'customerId',
|
|
377
|
-
resolver: 'sdk.parseInt',
|
|
378
|
-
},
|
|
379
|
-
'customer.email': {
|
|
380
|
-
source: 'email',
|
|
381
|
-
resolver: 'sdk.lowercase',
|
|
382
|
-
},
|
|
383
|
-
'customer.address.city': {
|
|
384
|
-
source: 'city',
|
|
385
|
-
},
|
|
386
|
-
},
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
// Output:
|
|
390
|
-
// {
|
|
391
|
-
// customer: {
|
|
392
|
-
// id: 12345,
|
|
393
|
-
// email: "john@example.com",
|
|
394
|
-
// address: { city: "New York" }
|
|
395
|
-
// }
|
|
396
|
-
// }
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Nested Object Structure
|
|
400
|
-
|
|
401
|
-
```typescript
|
|
402
|
-
const config = {
|
|
403
|
-
fields: {
|
|
404
|
-
customer: {
|
|
405
|
-
fields: {
|
|
406
|
-
id: { source: 'customerId' },
|
|
407
|
-
email: { source: 'email' },
|
|
408
|
-
address: {
|
|
409
|
-
fields: {
|
|
410
|
-
street: { source: 'street' },
|
|
411
|
-
city: { source: 'city' },
|
|
412
|
-
zip: { source: 'zipCode' },
|
|
413
|
-
},
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
};
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## Array Patterns
|
|
424
|
-
|
|
425
|
-
### Array with Nested Mapping
|
|
426
|
-
|
|
427
|
-
```typescript
|
|
428
|
-
const config = {
|
|
429
|
-
fields: {
|
|
430
|
-
items: {
|
|
431
|
-
source: 'orderItems',
|
|
432
|
-
isArray: true, // Map each array element
|
|
433
|
-
fields: {
|
|
434
|
-
ref: { source: 'id' },
|
|
435
|
-
productRef: { source: 'sku' },
|
|
436
|
-
quantity: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
},
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
// Source: { orderItems: [{ id: "1", sku: "SKU001", qty: "5" }] }
|
|
443
|
-
// Output: { items: [{ ref: "1", productRef: "SKU001", quantity: 5 }] }
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### GraphQL Edges/Nodes Pattern
|
|
447
|
-
|
|
448
|
-
```typescript
|
|
449
|
-
const config = {
|
|
450
|
-
fields: {
|
|
451
|
-
products: {
|
|
452
|
-
source: 'products.edges[*].node', // Wildcard extraction
|
|
453
|
-
isArray: true,
|
|
454
|
-
fields: {
|
|
455
|
-
id: { source: 'id' },
|
|
456
|
-
ref: { source: 'ref' },
|
|
457
|
-
name: { source: 'name' },
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
},
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
// Automatically extracts nodes from GraphQL pagination structure
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### Conditional Array Item Processing
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
const customResolvers = {
|
|
470
|
-
'custom.filterActive': (items, sourceData, config, helpers) => {
|
|
471
|
-
// Filter array items based on condition
|
|
472
|
-
return helpers.ensureArray(items).filter(item => item.status === 'ACTIVE');
|
|
473
|
-
},
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
const config = {
|
|
477
|
-
fields: {
|
|
478
|
-
activeItems: {
|
|
479
|
-
source: 'items',
|
|
480
|
-
resolver: 'custom.filterActive',
|
|
481
|
-
isArray: true,
|
|
482
|
-
fields: {
|
|
483
|
-
id: { source: 'id' },
|
|
484
|
-
name: { source: 'name' },
|
|
485
|
-
},
|
|
486
|
-
},
|
|
487
|
-
},
|
|
488
|
-
};
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
---
|
|
492
|
-
|
|
493
|
-
## Error Handling Patterns
|
|
494
|
-
|
|
495
|
-
### Required Field Validation
|
|
496
|
-
|
|
497
|
-
```typescript
|
|
498
|
-
const config = {
|
|
499
|
-
fields: {
|
|
500
|
-
skuRef: {
|
|
501
|
-
source: 'sku',
|
|
502
|
-
required: true, // Fails entire mapping if missing
|
|
503
|
-
},
|
|
504
|
-
locationRef: {
|
|
505
|
-
source: 'location',
|
|
506
|
-
required: true,
|
|
507
|
-
},
|
|
508
|
-
qty: {
|
|
509
|
-
source: 'quantity',
|
|
510
|
-
resolver: 'sdk.parseInt',
|
|
511
|
-
defaultValue: 0, // Optional field with default
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
const result = await mapper.map(sourceData);
|
|
517
|
-
|
|
518
|
-
if (!result.success) {
|
|
519
|
-
console.error('Mapping failed:', result.errors);
|
|
520
|
-
// ["Required field 'skuRef' is missing or empty (source: sku)"]
|
|
521
|
-
}
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
### Checking Mapping Results
|
|
525
|
-
|
|
526
|
-
```typescript
|
|
527
|
-
const result = await mapper.map(sourceData);
|
|
528
|
-
|
|
529
|
-
if (result.success) {
|
|
530
|
-
// All fields mapped successfully
|
|
531
|
-
console.log('Mapped data:', result.data);
|
|
532
|
-
batchEntities.push(result.data);
|
|
533
|
-
} else {
|
|
534
|
-
// One or more errors occurred
|
|
535
|
-
console.error('Mapping errors:', result.errors);
|
|
536
|
-
failedRecords.push({ sourceData, errors: result.errors });
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// Partial success - some optional fields failed
|
|
540
|
-
if (result.success && result.errors) {
|
|
541
|
-
console.warn('Mapping succeeded with warnings:', result.errors);
|
|
542
|
-
}
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### Safe Resolver with Error Handling
|
|
546
|
-
|
|
547
|
-
```typescript
|
|
548
|
-
const customResolvers = {
|
|
549
|
-
'custom.safeCalculate': (value, sourceData, config, helpers) => {
|
|
550
|
-
try {
|
|
551
|
-
const num = helpers.parseFloatSafe(value, 0);
|
|
552
|
-
if (num < 0) {
|
|
553
|
-
helpers.log.warn('Negative value found, using 0', { value });
|
|
554
|
-
return 0;
|
|
555
|
-
}
|
|
556
|
-
return num * 1.1; // Add 10%
|
|
557
|
-
} catch (error) {
|
|
558
|
-
helpers.log.error('Calculation failed', error);
|
|
559
|
-
return 0; // Safe fallback
|
|
560
|
-
}
|
|
561
|
-
},
|
|
562
|
-
};
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
---
|
|
566
|
-
|
|
567
|
-
## Common Use Case Patterns
|
|
568
|
-
|
|
569
|
-
### CSV to Batch API
|
|
570
|
-
|
|
571
|
-
```typescript
|
|
572
|
-
const config = {
|
|
573
|
-
fields: {
|
|
574
|
-
skuRef: { source: 'sku', required: true },
|
|
575
|
-
locationRef: { source: 'location', required: true },
|
|
576
|
-
qty: { source: 'quantity', resolver: 'sdk.parseInt', required: true },
|
|
577
|
-
status: { source: 'status', resolver: 'sdk.uppercase', defaultValue: 'ACTIVE' },
|
|
578
|
-
},
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
const mapper = new UniversalMapper(config);
|
|
582
|
-
|
|
583
|
-
for (const row of csvRows) {
|
|
584
|
-
const result = await mapper.map(row);
|
|
585
|
-
if (result.success) {
|
|
586
|
-
batchEntities.push(result.data);
|
|
587
|
-
} else {
|
|
588
|
-
console.error(`Row failed: ${JSON.stringify(row)}, errors: ${result.errors}`);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
await client.sendBatch(jobId, { entities: batchEntities });
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
### XML to GraphQL Structure
|
|
596
|
-
|
|
597
|
-
```typescript
|
|
598
|
-
const config = {
|
|
599
|
-
fields: {
|
|
600
|
-
ref: { source: 'order@id', required: true }, // XML attribute
|
|
601
|
-
'customer.email': { source: 'order.customer@email', resolver: 'sdk.lowercase' },
|
|
602
|
-
totalPrice: { source: 'order.total', resolver: 'sdk.parseFloat' },
|
|
603
|
-
items: {
|
|
604
|
-
source: 'order.items.item',
|
|
605
|
-
isArray: true,
|
|
606
|
-
fields: {
|
|
607
|
-
productRef: { source: 'sku' },
|
|
608
|
-
quantity: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
609
|
-
},
|
|
610
|
-
},
|
|
611
|
-
},
|
|
612
|
-
};
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### Fluent to JSON Export
|
|
616
|
-
|
|
617
|
-
```typescript
|
|
618
|
-
const config = {
|
|
619
|
-
fields: {
|
|
620
|
-
position_id: { source: 'id' },
|
|
621
|
-
sku: { source: 'productRef' },
|
|
622
|
-
available_qty: { source: 'quantity', resolver: 'sdk.parseInt' },
|
|
623
|
-
last_updated: { source: 'updatedOn', resolver: 'sdk.formatDate' },
|
|
624
|
-
},
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
const mapper = new UniversalMapper(config);
|
|
628
|
-
|
|
629
|
-
for (const edge of data.inventoryPositions.edges) {
|
|
630
|
-
const result = await mapper.map(edge.node);
|
|
631
|
-
if (result.success) {
|
|
632
|
-
extractedRecords.push(result.data);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
await writeJsonFile(extractedRecords);
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
---
|
|
640
|
-
|
|
641
|
-
## When NOT to Use This Pattern
|
|
642
|
-
|
|
643
|
-
### 1. Complex Multi-Step Transformations
|
|
644
|
-
|
|
645
|
-
If your transformation requires multiple passes or complex state management, use:
|
|
646
|
-
|
|
647
|
-
- Intermediate data structures to separate concerns
|
|
648
|
-
- Multiple mapper instances for each transformation step
|
|
649
|
-
- Custom service classes for domain-specific business logic
|
|
650
|
-
|
|
651
|
-
### 2. Performance-Critical Async Operations
|
|
652
|
-
|
|
653
|
-
For high-volume batch processing with async resolvers:
|
|
654
|
-
|
|
655
|
-
- Pre-fetch lookup data before mapping
|
|
656
|
-
- Use memoization for repeated lookups
|
|
657
|
-
- Consider batch API calls instead of individual resolver calls
|
|
658
|
-
|
|
659
|
-
### 3. Schema-Driven Code Generation
|
|
660
|
-
|
|
661
|
-
When you need type-safe generated code:
|
|
662
|
-
|
|
663
|
-
- Use GraphQLMutationMapper for XML/JSON to GraphQL mutations
|
|
664
|
-
- Use introspection tools to generate TypeScript types
|
|
665
|
-
- Consider schema-first development approaches
|
|
666
|
-
|
|
667
|
-
### 4. Real-Time Streaming
|
|
668
|
-
|
|
669
|
-
For streaming data transformations:
|
|
670
|
-
|
|
671
|
-
- Use data source streaming APIs (CSVParserService streaming mode)
|
|
672
|
-
- Consider event-driven architectures
|
|
673
|
-
- Use transform streams for pipeline processing
|
|
674
|
-
|
|
675
|
-
---
|
|
676
|
-
|
|
677
|
-
## Best Practices
|
|
678
|
-
|
|
679
|
-
1. **Use SDK Resolvers First** - Try built-in resolvers before creating custom ones
|
|
680
|
-
2. **Keep Resolvers Pure** - Same input should always produce same output
|
|
681
|
-
3. **Mark Critical Fields Required** - Fail fast for data integrity
|
|
682
|
-
4. **Provide Defaults for Optional Fields** - Prevent null/undefined in output
|
|
683
|
-
5. **Use Helper Functions** - Leverage parseIntSafe, parseFloatSafe for safety
|
|
684
|
-
6. **Document Custom Resolvers** - Add comments explaining transformation logic
|
|
685
|
-
7. **Test Edge Cases** - Null, undefined, empty string, invalid formats
|
|
686
|
-
8. **Handle Arrays Consistently** - Use isArray: true for uniform processing
|
|
687
|
-
9. **Single Resolver Per Field** - The `resolver` property accepts a single resolver name (string). If you need multiple steps (e.g., toString + trim), create one custom resolver (for example, `custom.toStringTrim`) and use that.
|
|
688
|
-
10. **Identifiers That Look Numeric** - For fields like SKU/GTIN/UPC that must remain strings, use `sdk.toString`. When parsing XML, set parser options to avoid numeric coercion (for example, `parseNumbers: false`) so leading zeros are preserved.
|
|
689
|
-
|
|
690
|
-
---
|
|
691
|
-
|
|
692
|
-
## Related Patterns
|
|
693
|
-
|
|
694
|
-
- **GraphQL Mutation Mapping** - XML/JSON to GraphQL mutations with GraphQLMutationMapper
|
|
695
|
-
- **XML Parser** - Detailed XML path syntax and parsing patterns
|
|
696
|
-
- **Batch Processing** - High-volume data ingestion patterns
|
|
697
|
-
- **State Management** - Preventing duplicate processing with StateService
|
|
698
|
-
|
|
699
|
-
---
|
|
700
|
-
|
|
701
|
-
**Remember**: UniversalMapper is the ONE mapping engine for ALL SDK transformations. Learn this pattern once, use it everywhere.
|
|
1
|
+
# Pattern: Universal Field Mapping
|
|
2
|
+
|
|
3
|
+
**FC Connect SDK Use Case Guide**
|
|
4
|
+
|
|
5
|
+
> **SDK**: [@fluentcommerce/fc-connect-sdk](https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk)
|
|
6
|
+
> **Version**: Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
7
|
+
|
|
8
|
+
**Context**: Focused guide on UniversalMapper for transforming data between formats
|
|
9
|
+
|
|
10
|
+
**Type**: Reusable Pattern
|
|
11
|
+
|
|
12
|
+
**Complexity**: Low-Medium
|
|
13
|
+
|
|
14
|
+
**Lines**: ~200 lines
|
|
15
|
+
|
|
16
|
+
## When to Use This Pattern
|
|
17
|
+
|
|
18
|
+
- Transforming CSV/JSON/XML to Fluent format
|
|
19
|
+
- Extracting Fluent data for export
|
|
20
|
+
- Data normalization and validation
|
|
21
|
+
- Type conversions and formatting
|
|
22
|
+
- Building GraphQL mutation inputs
|
|
23
|
+
- Generating XML/JSON output structures
|
|
24
|
+
|
|
25
|
+
## SDK Methods
|
|
26
|
+
|
|
27
|
+
- `UniversalMapper(config, options)` - Create mapper instance
|
|
28
|
+
- `mapper.map(sourceData)` - Transform single record
|
|
29
|
+
- `mapper.registerResolver(name, fn)` - Add custom resolver
|
|
30
|
+
- `mapper.registerResolvers(map)` - Add multiple custom resolvers
|
|
31
|
+
- SDK Resolvers: `sdk.*` prefix (15 built-in)
|
|
32
|
+
- Custom resolvers: Your own transformation functions
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Basic Mapping
|
|
37
|
+
|
|
38
|
+
### Simple Field Mapping
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// FC Connect SDK (latest)
|
|
42
|
+
// Install: npm install @fluentcommerce/fc-connect-sdk@latest
|
|
43
|
+
// Docs: https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk
|
|
44
|
+
// GitHub: https://github.com/fluentcommerce/fc-connect-sdk
|
|
45
|
+
|
|
46
|
+
import { UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
47
|
+
|
|
48
|
+
const config = {
|
|
49
|
+
fields: {
|
|
50
|
+
// Direct mapping - no transformation
|
|
51
|
+
customerEmail: {
|
|
52
|
+
source: 'email',
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// Map with transformation
|
|
56
|
+
status: {
|
|
57
|
+
source: 'orderStatus',
|
|
58
|
+
resolver: 'sdk.uppercase',
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Required field with validation
|
|
62
|
+
productSku: {
|
|
63
|
+
source: 'sku',
|
|
64
|
+
required: true,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const mapper = new UniversalMapper(config);
|
|
70
|
+
|
|
71
|
+
// Transform data
|
|
72
|
+
const sourceData = { email: 'john@example.com', orderStatus: 'pending', sku: 'PROD-001' };
|
|
73
|
+
const result = await mapper.map(sourceData);
|
|
74
|
+
|
|
75
|
+
if (result.success) {
|
|
76
|
+
console.log(result.data);
|
|
77
|
+
// { customerEmail: 'john@example.com', status: 'PENDING', productSku: 'PROD-001' }
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Static Values
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const config = {
|
|
85
|
+
fields: {
|
|
86
|
+
type: {
|
|
87
|
+
value: 'STANDARD', // Always returns "STANDARD"
|
|
88
|
+
},
|
|
89
|
+
retailerId: {
|
|
90
|
+
value: 1, // Static numeric value
|
|
91
|
+
},
|
|
92
|
+
version: {
|
|
93
|
+
value: '2.0',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Default Values
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const config = {
|
|
103
|
+
fields: {
|
|
104
|
+
status: {
|
|
105
|
+
source: 'orderStatus',
|
|
106
|
+
defaultValue: 'PENDING', // Used if source is missing/empty
|
|
107
|
+
},
|
|
108
|
+
quantity: {
|
|
109
|
+
source: 'qty',
|
|
110
|
+
resolver: 'sdk.parseInt',
|
|
111
|
+
defaultValue: 0, // Fallback for missing quantity
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## SDK Resolver Patterns
|
|
120
|
+
|
|
121
|
+
### String Transformations
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const config = {
|
|
125
|
+
fields: {
|
|
126
|
+
// Convert to uppercase
|
|
127
|
+
countryCode: {
|
|
128
|
+
source: 'country',
|
|
129
|
+
resolver: 'sdk.uppercase', // "us" → "US"
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// Convert to lowercase
|
|
133
|
+
email: {
|
|
134
|
+
source: 'customerEmail',
|
|
135
|
+
resolver: 'sdk.lowercase', // "JOHN@EXAMPLE.COM" → "john@example.com"
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// Trim whitespace
|
|
139
|
+
sku: {
|
|
140
|
+
source: 'productSku',
|
|
141
|
+
resolver: 'sdk.trim', // " SKU123 " → "SKU123"
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// Convert to string
|
|
145
|
+
orderId: {
|
|
146
|
+
source: 'order_id',
|
|
147
|
+
resolver: 'sdk.toString', // 12345 → "12345"
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Number Transformations
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const config = {
|
|
157
|
+
fields: {
|
|
158
|
+
// Parse as integer
|
|
159
|
+
quantity: {
|
|
160
|
+
source: 'qty',
|
|
161
|
+
resolver: 'sdk.parseInt', // "123" → 123, "123.99" → 123
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// Parse as float
|
|
165
|
+
price: {
|
|
166
|
+
source: 'total',
|
|
167
|
+
resolver: 'sdk.parseFloat', // "99.99" → 99.99, "$45.50" → 45.5
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Generic number parser (alias for parseFloat)
|
|
171
|
+
weight: {
|
|
172
|
+
source: 'weight_kg',
|
|
173
|
+
resolver: 'sdk.number', // "3.14" → 3.14
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Date Transformations
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const config = {
|
|
183
|
+
fields: {
|
|
184
|
+
// Format to ISO8601 (Fluent API standard)
|
|
185
|
+
expectedOn: {
|
|
186
|
+
source: 'delivery_date',
|
|
187
|
+
resolver: 'sdk.formatDate', // "2024-01-15" → "2024-01-15T00:00:00.000Z"
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
// Format to YYYY-MM-DD
|
|
191
|
+
orderDate: {
|
|
192
|
+
source: 'created_at',
|
|
193
|
+
resolver: 'sdk.formatDateShort', // "2024-01-15T10:30:00Z" → "2024-01-15"
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
// Parse date string
|
|
197
|
+
scheduledDate: {
|
|
198
|
+
source: 'schedule',
|
|
199
|
+
resolver: 'sdk.parseDate', // "01/15/2024" → Date object
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Type Conversions
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const config = {
|
|
209
|
+
fields: {
|
|
210
|
+
// Convert to boolean
|
|
211
|
+
isActive: {
|
|
212
|
+
source: 'active',
|
|
213
|
+
resolver: 'sdk.boolean', // "true", "1", "yes", "y" → true
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// Parse JSON string
|
|
217
|
+
metadata: {
|
|
218
|
+
source: 'json_data',
|
|
219
|
+
resolver: 'sdk.parseJson', // '{"key":"value"}' → { key: "value" }
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
// Stringify to JSON
|
|
223
|
+
customAttributes: {
|
|
224
|
+
source: 'attributes',
|
|
225
|
+
resolver: 'sdk.toJson', // { name: "John" } → '{"name":"John"}'
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Utility Resolvers
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
const config = {
|
|
235
|
+
fields: {
|
|
236
|
+
// Identity - no transformation
|
|
237
|
+
originalValue: {
|
|
238
|
+
source: 'rawData',
|
|
239
|
+
resolver: 'sdk.identity', // Pass through unchanged
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
// Coalesce - first non-null value
|
|
243
|
+
displayName: {
|
|
244
|
+
source: 'name',
|
|
245
|
+
resolver: 'sdk.coalesce',
|
|
246
|
+
defaultValue: 'Unknown', // Fallback if null/undefined
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Complete SDK Resolver Reference
|
|
255
|
+
|
|
256
|
+
### String Resolvers (4)
|
|
257
|
+
|
|
258
|
+
- `sdk.uppercase` - Convert to UPPERCASE
|
|
259
|
+
- `sdk.lowercase` - Convert to lowercase
|
|
260
|
+
- `sdk.trim` - Remove leading/trailing whitespace
|
|
261
|
+
- `sdk.toString` - Convert any value to string
|
|
262
|
+
|
|
263
|
+
### Number Resolvers (3)
|
|
264
|
+
|
|
265
|
+
- `sdk.parseInt` - Parse as integer (returns 0 for invalid)
|
|
266
|
+
- `sdk.parseFloat` - Parse as float (returns 0 for invalid)
|
|
267
|
+
- `sdk.number` - Alias for parseFloat
|
|
268
|
+
|
|
269
|
+
### Date Resolvers (3)
|
|
270
|
+
|
|
271
|
+
- `sdk.formatDate` - Format to ISO8601 (Fluent API standard)
|
|
272
|
+
- `sdk.formatDateShort` - Format to YYYY-MM-DD
|
|
273
|
+
- `sdk.parseDate` - Parse date string to Date object
|
|
274
|
+
|
|
275
|
+
### Type Conversion Resolvers (3)
|
|
276
|
+
|
|
277
|
+
- `sdk.boolean` - Convert to boolean (handles "true", "1", "yes", etc.)
|
|
278
|
+
- `sdk.parseJson` - Parse JSON string to object
|
|
279
|
+
- `sdk.toJson` - Stringify object to JSON
|
|
280
|
+
|
|
281
|
+
### Utility Resolvers (2)
|
|
282
|
+
|
|
283
|
+
- `sdk.identity` - Pass value through unchanged
|
|
284
|
+
- `sdk.coalesce` - Return first non-null value
|
|
285
|
+
|
|
286
|
+
**Total: 15 SDK Resolvers**
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Custom Resolver Patterns
|
|
291
|
+
|
|
292
|
+
### Basic Custom Resolver
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
import { UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
296
|
+
|
|
297
|
+
const customResolvers = {
|
|
298
|
+
'custom.calculateTax': (value, sourceData, config, helpers) => {
|
|
299
|
+
const subtotal = helpers.parseFloatSafe(value, 0);
|
|
300
|
+
return subtotal * 0.1; // 10% tax
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
'custom.formatPhone': (value, sourceData, config, helpers) => {
|
|
304
|
+
// Remove non-digits
|
|
305
|
+
const digits = value.replace(/\D/g, '');
|
|
306
|
+
// Format as (XXX) XXX-XXXX
|
|
307
|
+
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const mapper = new UniversalMapper(config, { customResolvers });
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Using Helper Functions
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
const customResolvers = {
|
|
318
|
+
'custom.cleanAndUpper': (value, sourceData, config, helpers) => {
|
|
319
|
+
// Use helpers for safe operations
|
|
320
|
+
const trimmed = helpers.normalizeWhitespace(value);
|
|
321
|
+
return trimmed.toUpperCase();
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
'custom.extractId': (value, sourceData, config, helpers) => {
|
|
325
|
+
// Safe nested property access
|
|
326
|
+
const product = helpers.get(sourceData, 'product.details') || {};
|
|
327
|
+
return product.id || 'UNKNOWN';
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Context-Aware Resolvers
|
|
333
|
+
|
|
334
|
+
> **⚠️ Important**: To use `helpers.fluentClient` or `helpers.context` in custom resolvers, you MUST pass them when creating the mapper. They are NOT available by default.
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
const customResolvers = {
|
|
338
|
+
'custom.lookupCustomer': async (email, sourceData, config, helpers) => {
|
|
339
|
+
// Access fluentClient from helpers (passed via options)
|
|
340
|
+
if (!helpers.fluentClient) {
|
|
341
|
+
throw new Error('fluentClient not available');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const query = `query { customers(email: "${email}") { edges { node { id } } } }`;
|
|
345
|
+
const result = await helpers.fluentClient.graphql({ query });
|
|
346
|
+
return result.data.customers.edges[0]?.node.id;
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
'custom.addOrderContext': (value, sourceData, config, helpers) => {
|
|
350
|
+
// Access custom context
|
|
351
|
+
const orderId = helpers.context?.orderId;
|
|
352
|
+
return `${value}_${orderId}`;
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// ✅ REQUIRED: Initialize mapper with fluentClient and context for async resolvers
|
|
357
|
+
const mapper = new UniversalMapper(config, {
|
|
358
|
+
customResolvers,
|
|
359
|
+
fluentClient: fluentClient, // ← Required for API access in resolvers
|
|
360
|
+
logger: console, // ← Required for helpers.log
|
|
361
|
+
context: { orderId: '12345', userId: '999' }, // ← Required for helpers.context
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Nested Field Patterns
|
|
368
|
+
|
|
369
|
+
### Nested Objects
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
const config = {
|
|
373
|
+
fields: {
|
|
374
|
+
// Simple nested field with dot notation
|
|
375
|
+
'customer.id': {
|
|
376
|
+
source: 'customerId',
|
|
377
|
+
resolver: 'sdk.parseInt',
|
|
378
|
+
},
|
|
379
|
+
'customer.email': {
|
|
380
|
+
source: 'email',
|
|
381
|
+
resolver: 'sdk.lowercase',
|
|
382
|
+
},
|
|
383
|
+
'customer.address.city': {
|
|
384
|
+
source: 'city',
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// Output:
|
|
390
|
+
// {
|
|
391
|
+
// customer: {
|
|
392
|
+
// id: 12345,
|
|
393
|
+
// email: "john@example.com",
|
|
394
|
+
// address: { city: "New York" }
|
|
395
|
+
// }
|
|
396
|
+
// }
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Nested Object Structure
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
const config = {
|
|
403
|
+
fields: {
|
|
404
|
+
customer: {
|
|
405
|
+
fields: {
|
|
406
|
+
id: { source: 'customerId' },
|
|
407
|
+
email: { source: 'email' },
|
|
408
|
+
address: {
|
|
409
|
+
fields: {
|
|
410
|
+
street: { source: 'street' },
|
|
411
|
+
city: { source: 'city' },
|
|
412
|
+
zip: { source: 'zipCode' },
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
};
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Array Patterns
|
|
424
|
+
|
|
425
|
+
### Array with Nested Mapping
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
const config = {
|
|
429
|
+
fields: {
|
|
430
|
+
items: {
|
|
431
|
+
source: 'orderItems',
|
|
432
|
+
isArray: true, // Map each array element
|
|
433
|
+
fields: {
|
|
434
|
+
ref: { source: 'id' },
|
|
435
|
+
productRef: { source: 'sku' },
|
|
436
|
+
quantity: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// Source: { orderItems: [{ id: "1", sku: "SKU001", qty: "5" }] }
|
|
443
|
+
// Output: { items: [{ ref: "1", productRef: "SKU001", quantity: 5 }] }
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### GraphQL Edges/Nodes Pattern
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
const config = {
|
|
450
|
+
fields: {
|
|
451
|
+
products: {
|
|
452
|
+
source: 'products.edges[*].node', // Wildcard extraction
|
|
453
|
+
isArray: true,
|
|
454
|
+
fields: {
|
|
455
|
+
id: { source: 'id' },
|
|
456
|
+
ref: { source: 'ref' },
|
|
457
|
+
name: { source: 'name' },
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// Automatically extracts nodes from GraphQL pagination structure
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Conditional Array Item Processing
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
const customResolvers = {
|
|
470
|
+
'custom.filterActive': (items, sourceData, config, helpers) => {
|
|
471
|
+
// Filter array items based on condition
|
|
472
|
+
return helpers.ensureArray(items).filter(item => item.status === 'ACTIVE');
|
|
473
|
+
},
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const config = {
|
|
477
|
+
fields: {
|
|
478
|
+
activeItems: {
|
|
479
|
+
source: 'items',
|
|
480
|
+
resolver: 'custom.filterActive',
|
|
481
|
+
isArray: true,
|
|
482
|
+
fields: {
|
|
483
|
+
id: { source: 'id' },
|
|
484
|
+
name: { source: 'name' },
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
};
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Error Handling Patterns
|
|
494
|
+
|
|
495
|
+
### Required Field Validation
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
const config = {
|
|
499
|
+
fields: {
|
|
500
|
+
skuRef: {
|
|
501
|
+
source: 'sku',
|
|
502
|
+
required: true, // Fails entire mapping if missing
|
|
503
|
+
},
|
|
504
|
+
locationRef: {
|
|
505
|
+
source: 'location',
|
|
506
|
+
required: true,
|
|
507
|
+
},
|
|
508
|
+
qty: {
|
|
509
|
+
source: 'quantity',
|
|
510
|
+
resolver: 'sdk.parseInt',
|
|
511
|
+
defaultValue: 0, // Optional field with default
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const result = await mapper.map(sourceData);
|
|
517
|
+
|
|
518
|
+
if (!result.success) {
|
|
519
|
+
console.error('Mapping failed:', result.errors);
|
|
520
|
+
// ["Required field 'skuRef' is missing or empty (source: sku)"]
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Checking Mapping Results
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
const result = await mapper.map(sourceData);
|
|
528
|
+
|
|
529
|
+
if (result.success) {
|
|
530
|
+
// All fields mapped successfully
|
|
531
|
+
console.log('Mapped data:', result.data);
|
|
532
|
+
batchEntities.push(result.data);
|
|
533
|
+
} else {
|
|
534
|
+
// One or more errors occurred
|
|
535
|
+
console.error('Mapping errors:', result.errors);
|
|
536
|
+
failedRecords.push({ sourceData, errors: result.errors });
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Partial success - some optional fields failed
|
|
540
|
+
if (result.success && result.errors) {
|
|
541
|
+
console.warn('Mapping succeeded with warnings:', result.errors);
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Safe Resolver with Error Handling
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
const customResolvers = {
|
|
549
|
+
'custom.safeCalculate': (value, sourceData, config, helpers) => {
|
|
550
|
+
try {
|
|
551
|
+
const num = helpers.parseFloatSafe(value, 0);
|
|
552
|
+
if (num < 0) {
|
|
553
|
+
helpers.log.warn('Negative value found, using 0', { value });
|
|
554
|
+
return 0;
|
|
555
|
+
}
|
|
556
|
+
return num * 1.1; // Add 10%
|
|
557
|
+
} catch (error) {
|
|
558
|
+
helpers.log.error('Calculation failed', error);
|
|
559
|
+
return 0; // Safe fallback
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## Common Use Case Patterns
|
|
568
|
+
|
|
569
|
+
### CSV to Batch API
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
const config = {
|
|
573
|
+
fields: {
|
|
574
|
+
skuRef: { source: 'sku', required: true },
|
|
575
|
+
locationRef: { source: 'location', required: true },
|
|
576
|
+
qty: { source: 'quantity', resolver: 'sdk.parseInt', required: true },
|
|
577
|
+
status: { source: 'status', resolver: 'sdk.uppercase', defaultValue: 'ACTIVE' },
|
|
578
|
+
},
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
const mapper = new UniversalMapper(config);
|
|
582
|
+
|
|
583
|
+
for (const row of csvRows) {
|
|
584
|
+
const result = await mapper.map(row);
|
|
585
|
+
if (result.success) {
|
|
586
|
+
batchEntities.push(result.data);
|
|
587
|
+
} else {
|
|
588
|
+
console.error(`Row failed: ${JSON.stringify(row)}, errors: ${result.errors}`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
await client.sendBatch(jobId, { entities: batchEntities });
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### XML to GraphQL Structure
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
const config = {
|
|
599
|
+
fields: {
|
|
600
|
+
ref: { source: 'order@id', required: true }, // XML attribute
|
|
601
|
+
'customer.email': { source: 'order.customer@email', resolver: 'sdk.lowercase' },
|
|
602
|
+
totalPrice: { source: 'order.total', resolver: 'sdk.parseFloat' },
|
|
603
|
+
items: {
|
|
604
|
+
source: 'order.items.item',
|
|
605
|
+
isArray: true,
|
|
606
|
+
fields: {
|
|
607
|
+
productRef: { source: 'sku' },
|
|
608
|
+
quantity: { source: 'qty', resolver: 'sdk.parseInt' },
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
};
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Fluent to JSON Export
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
const config = {
|
|
619
|
+
fields: {
|
|
620
|
+
position_id: { source: 'id' },
|
|
621
|
+
sku: { source: 'productRef' },
|
|
622
|
+
available_qty: { source: 'quantity', resolver: 'sdk.parseInt' },
|
|
623
|
+
last_updated: { source: 'updatedOn', resolver: 'sdk.formatDate' },
|
|
624
|
+
},
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
const mapper = new UniversalMapper(config);
|
|
628
|
+
|
|
629
|
+
for (const edge of data.inventoryPositions.edges) {
|
|
630
|
+
const result = await mapper.map(edge.node);
|
|
631
|
+
if (result.success) {
|
|
632
|
+
extractedRecords.push(result.data);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
await writeJsonFile(extractedRecords);
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## When NOT to Use This Pattern
|
|
642
|
+
|
|
643
|
+
### 1. Complex Multi-Step Transformations
|
|
644
|
+
|
|
645
|
+
If your transformation requires multiple passes or complex state management, use:
|
|
646
|
+
|
|
647
|
+
- Intermediate data structures to separate concerns
|
|
648
|
+
- Multiple mapper instances for each transformation step
|
|
649
|
+
- Custom service classes for domain-specific business logic
|
|
650
|
+
|
|
651
|
+
### 2. Performance-Critical Async Operations
|
|
652
|
+
|
|
653
|
+
For high-volume batch processing with async resolvers:
|
|
654
|
+
|
|
655
|
+
- Pre-fetch lookup data before mapping
|
|
656
|
+
- Use memoization for repeated lookups
|
|
657
|
+
- Consider batch API calls instead of individual resolver calls
|
|
658
|
+
|
|
659
|
+
### 3. Schema-Driven Code Generation
|
|
660
|
+
|
|
661
|
+
When you need type-safe generated code:
|
|
662
|
+
|
|
663
|
+
- Use GraphQLMutationMapper for XML/JSON to GraphQL mutations
|
|
664
|
+
- Use introspection tools to generate TypeScript types
|
|
665
|
+
- Consider schema-first development approaches
|
|
666
|
+
|
|
667
|
+
### 4. Real-Time Streaming
|
|
668
|
+
|
|
669
|
+
For streaming data transformations:
|
|
670
|
+
|
|
671
|
+
- Use data source streaming APIs (CSVParserService streaming mode)
|
|
672
|
+
- Consider event-driven architectures
|
|
673
|
+
- Use transform streams for pipeline processing
|
|
674
|
+
|
|
675
|
+
---
|
|
676
|
+
|
|
677
|
+
## Best Practices
|
|
678
|
+
|
|
679
|
+
1. **Use SDK Resolvers First** - Try built-in resolvers before creating custom ones
|
|
680
|
+
2. **Keep Resolvers Pure** - Same input should always produce same output
|
|
681
|
+
3. **Mark Critical Fields Required** - Fail fast for data integrity
|
|
682
|
+
4. **Provide Defaults for Optional Fields** - Prevent null/undefined in output
|
|
683
|
+
5. **Use Helper Functions** - Leverage parseIntSafe, parseFloatSafe for safety
|
|
684
|
+
6. **Document Custom Resolvers** - Add comments explaining transformation logic
|
|
685
|
+
7. **Test Edge Cases** - Null, undefined, empty string, invalid formats
|
|
686
|
+
8. **Handle Arrays Consistently** - Use isArray: true for uniform processing
|
|
687
|
+
9. **Single Resolver Per Field** - The `resolver` property accepts a single resolver name (string). If you need multiple steps (e.g., toString + trim), create one custom resolver (for example, `custom.toStringTrim`) and use that.
|
|
688
|
+
10. **Identifiers That Look Numeric** - For fields like SKU/GTIN/UPC that must remain strings, use `sdk.toString`. When parsing XML, set parser options to avoid numeric coercion (for example, `parseNumbers: false`) so leading zeros are preserved.
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
## Related Patterns
|
|
693
|
+
|
|
694
|
+
- **GraphQL Mutation Mapping** - XML/JSON to GraphQL mutations with GraphQLMutationMapper
|
|
695
|
+
- **XML Parser** - Detailed XML path syntax and parsing patterns
|
|
696
|
+
- **Batch Processing** - High-volume data ingestion patterns
|
|
697
|
+
- **State Management** - Preventing duplicate processing with StateService
|
|
698
|
+
|
|
699
|
+
---
|
|
700
|
+
|
|
701
|
+
**Remember**: UniversalMapper is the ONE mapping engine for ALL SDK transformations. Learn this pattern once, use it everywhere.
|