@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md
CHANGED
|
@@ -1,1437 +1,1437 @@
|
|
|
1
|
-
# Resolver Helper Functions Reference
|
|
2
|
-
|
|
3
|
-
**Complete reference for all 57 helper utilities**
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
1. [Overview](#overview)
|
|
10
|
-
2. [Data Access](#data-access) (2 functions)
|
|
11
|
-
3. [Parsing](#parsing) (3 functions)
|
|
12
|
-
4. [Formatting](#formatting) (2 functions)
|
|
13
|
-
5. [Validation](#validation) (3 functions)
|
|
14
|
-
6. [String Utilities](#string-utilities) (8 functions)
|
|
15
|
-
7. [Object Utilities](#object-utilities) (7 functions)
|
|
16
|
-
8. [Array Transformation](#array-transformation) (8 functions)
|
|
17
|
-
9. [Array Aggregation](#array-aggregation) (5 functions)
|
|
18
|
-
10. [Date/Time](#datetime) (5 functions)
|
|
19
|
-
11. [Function Utilities](#function-utilities) (2 functions)
|
|
20
|
-
12. [Type Guards](#type-guards) (5 functions)
|
|
21
|
-
13. [Utility Functions](#utility-functions) (3 functions)
|
|
22
|
-
14. [Performance](#performance) (3 functions)
|
|
23
|
-
15. [XML/JSON Specific](#xmljson-specific) (5 functions)
|
|
24
|
-
|
|
25
|
-
**Total: 57 helper functions**
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Overview
|
|
30
|
-
|
|
31
|
-
Helper functions are available through the `helpers` parameter in every resolver:
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
import { ResolverHelpers } from '@fluentcommerce/fc-connect-sdk';
|
|
35
|
-
|
|
36
|
-
// In resolvers
|
|
37
|
-
builder.field('input.ref', (data, config, helpers) => {
|
|
38
|
-
// helpers.get(), helpers.parseFloatSafe(), etc.
|
|
39
|
-
return helpers.get(data, 'order.orderNo');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Standalone usage
|
|
43
|
-
const value = ResolverHelpers.get(data, 'order.orderNo');
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Import Options
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// Import all helpers
|
|
50
|
-
import { ResolverHelpers } from '@fluentcommerce/fc-connect-sdk';
|
|
51
|
-
|
|
52
|
-
// Import specific helpers
|
|
53
|
-
import {
|
|
54
|
-
get,
|
|
55
|
-
formatDate,
|
|
56
|
-
formatCurrency,
|
|
57
|
-
parseFloatSafe
|
|
58
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Data Access
|
|
64
|
-
|
|
65
|
-
### `get(obj, path, defaultValue?)`
|
|
66
|
-
|
|
67
|
-
Safe nested property getter with dot notation. Never throws errors.
|
|
68
|
-
|
|
69
|
-
**Signature:**
|
|
70
|
-
```typescript
|
|
71
|
-
get(obj: any, path: string, defaultValue?: any): any
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Supported Path Syntax:**
|
|
75
|
-
- Dot notation: `'order.customer.email'`
|
|
76
|
-
- Array indexing: `'items[0].name'`
|
|
77
|
-
- XML attributes: `'order@order-no'` (note: NO dot before @)
|
|
78
|
-
- Filters: `'custom-attribute[attribute-id=value]'`
|
|
79
|
-
|
|
80
|
-
**Examples:**
|
|
81
|
-
```typescript
|
|
82
|
-
// Simple path
|
|
83
|
-
const email = helpers.get(data, 'orders.order.customer.customer-email');
|
|
84
|
-
|
|
85
|
-
// With default
|
|
86
|
-
const currency = helpers.get(data, 'orders.order.currency', 'USD');
|
|
87
|
-
|
|
88
|
-
// Array access
|
|
89
|
-
const firstItem = helpers.get(data, 'orders.order.product-lineitems.product-lineitem[0]');
|
|
90
|
-
|
|
91
|
-
// XML attribute (NO dot before @)
|
|
92
|
-
const orderNo = helpers.get(data, 'orders.order@order-no');
|
|
93
|
-
|
|
94
|
-
// Nested with default
|
|
95
|
-
const street = helpers.get(data, 'customer.address.street1', 'N/A');
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**Returns:** Value at path or `defaultValue` (or `undefined`)
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
### `ensureArray(value)`
|
|
103
|
-
|
|
104
|
-
Convert single items to arrays. Returns empty array for null/undefined.
|
|
105
|
-
|
|
106
|
-
**Signature:**
|
|
107
|
-
```typescript
|
|
108
|
-
ensureArray<T>(val: T | T[] | null | undefined): T[]
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**Behavior:**
|
|
112
|
-
- `undefined` or `null` → `[]`
|
|
113
|
-
- Array → Returns array unchanged
|
|
114
|
-
- Single object → `[object]`
|
|
115
|
-
- Primitive → `[primitive]`
|
|
116
|
-
|
|
117
|
-
**Examples:**
|
|
118
|
-
```typescript
|
|
119
|
-
helpers.ensureArray([1, 2, 3]); // => [1, 2, 3]
|
|
120
|
-
helpers.ensureArray('single'); // => ['single']
|
|
121
|
-
helpers.ensureArray(null); // => []
|
|
122
|
-
helpers.ensureArray({ id: 1 }); // => [{ id: 1 }]
|
|
123
|
-
|
|
124
|
-
// Real-world: Handle XML single vs multiple elements
|
|
125
|
-
const items = helpers.get(data, 'orders.order.product-lineitems.product-lineitem');
|
|
126
|
-
// items might be object (1 item) or array (multiple items)
|
|
127
|
-
const itemsArray = helpers.ensureArray(items);
|
|
128
|
-
itemsArray.forEach(item => { ... }); // Always works!
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Use Case:** XML parsing where single elements return object, multiple return array.
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Parsing
|
|
136
|
-
|
|
137
|
-
### `parseFloatSafe(value, defaultValue?)`
|
|
138
|
-
|
|
139
|
-
Parse float with safe fallback. Never throws.
|
|
140
|
-
|
|
141
|
-
**Signature:**
|
|
142
|
-
```typescript
|
|
143
|
-
parseFloatSafe(value: any, defaultValue?: number): number
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
**Examples:**
|
|
147
|
-
```typescript
|
|
148
|
-
helpers.parseFloatSafe('10.50', 0); // => 10.5
|
|
149
|
-
helpers.parseFloatSafe('invalid', 0); // => 0
|
|
150
|
-
helpers.parseFloatSafe(null, 99.99); // => 99.99
|
|
151
|
-
helpers.parseFloatSafe('123.456'); // => 123.456
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**Returns:** Parsed number or `defaultValue` (or `0`)
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
### `parseIntSafe(value, defaultValue?)`
|
|
159
|
-
|
|
160
|
-
Parse integer with safe fallback. Never throws.
|
|
161
|
-
|
|
162
|
-
**Signature:**
|
|
163
|
-
```typescript
|
|
164
|
-
parseIntSafe(value: any, defaultValue?: number): number
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Examples:**
|
|
168
|
-
```typescript
|
|
169
|
-
helpers.parseIntSafe('5', 1); // => 5
|
|
170
|
-
helpers.parseIntSafe('5.7', 1); // => 5 (truncates)
|
|
171
|
-
helpers.parseIntSafe('invalid', 1); // => 1
|
|
172
|
-
helpers.parseIntSafe(null, 100); // => 100
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Returns:** Parsed integer or `defaultValue` (or `0`)
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
### `safeJsonParse(jsonString, defaultValue?)`
|
|
180
|
-
|
|
181
|
-
Parse JSON with safe fallback. Never throws.
|
|
182
|
-
|
|
183
|
-
**Signature:**
|
|
184
|
-
```typescript
|
|
185
|
-
safeJsonParse<T = any>(jsonString: string, defaultValue?: T): T
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**Examples:**
|
|
189
|
-
```typescript
|
|
190
|
-
helpers.safeJsonParse('{"key":"value"}', {});
|
|
191
|
-
// => { key: 'value' }
|
|
192
|
-
|
|
193
|
-
helpers.safeJsonParse('invalid json', {});
|
|
194
|
-
// => {}
|
|
195
|
-
|
|
196
|
-
helpers.safeJsonParse('["a","b"]', []);
|
|
197
|
-
// => ['a', 'b']
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Returns:** Parsed object or `defaultValue` (or `{}`)
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## Formatting
|
|
205
|
-
|
|
206
|
-
### `formatDate(date)`
|
|
207
|
-
|
|
208
|
-
Format date to ISO8601 string.
|
|
209
|
-
|
|
210
|
-
**Signature:**
|
|
211
|
-
```typescript
|
|
212
|
-
formatDate(date: Date | string): string
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Examples:**
|
|
216
|
-
```typescript
|
|
217
|
-
helpers.formatDate('2025-01-14');
|
|
218
|
-
// => '2025-01-14T00:00:00.000Z'
|
|
219
|
-
|
|
220
|
-
helpers.formatDate(new Date('2025-01-14T10:30:00Z'));
|
|
221
|
-
// => '2025-01-14T10:30:00.000Z'
|
|
222
|
-
|
|
223
|
-
helpers.formatDate(1705227000000); // Timestamp
|
|
224
|
-
// => '2025-01-14T06:30:00.000Z'
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Returns:** ISO8601 formatted string
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
|
-
### `formatCurrency(amount, scale?)`
|
|
232
|
-
|
|
233
|
-
Format currency with specified decimal places. Uses half-down rounding.
|
|
234
|
-
|
|
235
|
-
**Signature:**
|
|
236
|
-
```typescript
|
|
237
|
-
formatCurrency(amount: number, scale?: number): string
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
**Parameters:**
|
|
241
|
-
- `amount: number` - Amount to format
|
|
242
|
-
- `scale?: number` - Decimal places (default: 2)
|
|
243
|
-
|
|
244
|
-
**Rounding:** Half-down (0.5 rounds toward zero)
|
|
245
|
-
- `10.555` → `'10.55'`
|
|
246
|
-
- `10.556` → `'10.56'`
|
|
247
|
-
|
|
248
|
-
**Examples:**
|
|
249
|
-
```typescript
|
|
250
|
-
helpers.formatCurrency(10.555, 2); // => '10.55'
|
|
251
|
-
helpers.formatCurrency(10.556, 2); // => '10.56'
|
|
252
|
-
helpers.formatCurrency(99.999, 2); // => '100.00'
|
|
253
|
-
helpers.formatCurrency(1234.5, 2); // => '1234.50'
|
|
254
|
-
helpers.formatCurrency(7.123456, 4); // => '7.1235'
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
**Returns:** Formatted currency string
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## Validation
|
|
262
|
-
|
|
263
|
-
### `isValidEmail(email)`
|
|
264
|
-
|
|
265
|
-
Validate email format using regex.
|
|
266
|
-
|
|
267
|
-
**Signature:**
|
|
268
|
-
```typescript
|
|
269
|
-
isValidEmail(email: string): boolean
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
**Examples:**
|
|
273
|
-
```typescript
|
|
274
|
-
helpers.isValidEmail('test@example.com'); // => true
|
|
275
|
-
helpers.isValidEmail('user+tag@domain.co.uk'); // => true
|
|
276
|
-
helpers.isValidEmail('invalid-email'); // => false
|
|
277
|
-
helpers.isValidEmail('missing@domain'); // => false
|
|
278
|
-
helpers.isValidEmail(''); // => false
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
**Returns:** `true` if valid email, `false` otherwise
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
### `requireField(value, fieldName)`
|
|
286
|
-
|
|
287
|
-
Validate required field. Throws error if missing/empty.
|
|
288
|
-
|
|
289
|
-
**Signature:**
|
|
290
|
-
```typescript
|
|
291
|
-
requireField(value: any, fieldName: string): void
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Throws:** Error if value is `null`, `undefined`, or empty string
|
|
295
|
-
|
|
296
|
-
**Examples:**
|
|
297
|
-
```typescript
|
|
298
|
-
helpers.requireField(orderRef, 'Order Reference');
|
|
299
|
-
// OK if orderRef has value
|
|
300
|
-
|
|
301
|
-
helpers.requireField(null, 'Customer ID');
|
|
302
|
-
// Throws: 'Required field missing: Customer ID'
|
|
303
|
-
|
|
304
|
-
helpers.requireField('', 'Email');
|
|
305
|
-
// Throws: 'Required field missing: Email'
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Use Case:** Enforce required fields in resolvers
|
|
309
|
-
|
|
310
|
-
---
|
|
311
|
-
|
|
312
|
-
### `mapValue(value, mapping, defaultValue?)`
|
|
313
|
-
|
|
314
|
-
Map value using mapping object.
|
|
315
|
-
|
|
316
|
-
**Signature:**
|
|
317
|
-
```typescript
|
|
318
|
-
mapValue<T>(value: any, mapping: Record<string, T>, defaultValue?: T): T
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**Examples:**
|
|
322
|
-
```typescript
|
|
323
|
-
const channelMapping = {
|
|
324
|
-
'Storefront': 'HD',
|
|
325
|
-
'CallCenter': 'CC',
|
|
326
|
-
'Mobile': 'MOBILE'
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
helpers.mapValue('Storefront', channelMapping, 'UNKNOWN'); // => 'HD'
|
|
330
|
-
helpers.mapValue('POS', channelMapping, 'STORE'); // => 'STORE' (default)
|
|
331
|
-
helpers.mapValue('CallCenter', channelMapping); // => 'CC'
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**Returns:** Mapped value or `defaultValue` (or `undefined`)
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
## String Utilities
|
|
339
|
-
|
|
340
|
-
### `fullName(firstName?, lastName?)`
|
|
341
|
-
|
|
342
|
-
Combine first and last name with space.
|
|
343
|
-
|
|
344
|
-
**Signature:**
|
|
345
|
-
```typescript
|
|
346
|
-
fullName(firstName?: string, lastName?: string): string
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**Examples:**
|
|
350
|
-
```typescript
|
|
351
|
-
helpers.fullName('John', 'Doe'); // => 'John Doe'
|
|
352
|
-
helpers.fullName('John', ''); // => 'John'
|
|
353
|
-
helpers.fullName('', 'Doe'); // => 'Doe'
|
|
354
|
-
helpers.fullName('', ''); // => ''
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
### `truncate(str, maxLength)`
|
|
360
|
-
|
|
361
|
-
Truncate string to max length, preserving words when possible.
|
|
362
|
-
|
|
363
|
-
**Signature:**
|
|
364
|
-
```typescript
|
|
365
|
-
truncate(str: string, maxLength: number): string
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**Examples:**
|
|
369
|
-
```typescript
|
|
370
|
-
helpers.truncate('This is a very long text', 10);
|
|
371
|
-
// => 'This is...'
|
|
372
|
-
|
|
373
|
-
helpers.truncate('Short', 10);
|
|
374
|
-
// => 'Short'
|
|
375
|
-
|
|
376
|
-
helpers.truncate('OneVeryLongWord', 8);
|
|
377
|
-
// => 'OneVery...'
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
---
|
|
381
|
-
|
|
382
|
-
### `normalizeWhitespace(str)`
|
|
383
|
-
|
|
384
|
-
Collapse multiple spaces into single space, trim edges.
|
|
385
|
-
|
|
386
|
-
**Signature:**
|
|
387
|
-
```typescript
|
|
388
|
-
normalizeWhitespace(str: string): string
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
**Examples:**
|
|
392
|
-
```typescript
|
|
393
|
-
helpers.normalizeWhitespace('Hello World \n !');
|
|
394
|
-
// => 'Hello World !'
|
|
395
|
-
|
|
396
|
-
helpers.normalizeWhitespace(' Too many spaces ');
|
|
397
|
-
// => 'Too many spaces'
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
---
|
|
401
|
-
|
|
402
|
-
### `toCamelCase(str)`
|
|
403
|
-
|
|
404
|
-
Convert string to camelCase.
|
|
405
|
-
|
|
406
|
-
**Signature:**
|
|
407
|
-
```typescript
|
|
408
|
-
toCamelCase(str: string): string
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
**Examples:**
|
|
412
|
-
```typescript
|
|
413
|
-
helpers.toCamelCase('order-number'); // => 'orderNumber'
|
|
414
|
-
helpers.toCamelCase('order_number'); // => 'orderNumber'
|
|
415
|
-
helpers.toCamelCase('Order Number'); // => 'orderNumber'
|
|
416
|
-
helpers.toCamelCase('ORDER-NUMBER'); // => 'orderNumber'
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
### `toSnakeCase(str)`
|
|
422
|
-
|
|
423
|
-
Convert string to snake_case.
|
|
424
|
-
|
|
425
|
-
**Signature:**
|
|
426
|
-
```typescript
|
|
427
|
-
toSnakeCase(str: string): string
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
**Examples:**
|
|
431
|
-
```typescript
|
|
432
|
-
helpers.toSnakeCase('orderNumber'); // => 'order_number'
|
|
433
|
-
helpers.toSnakeCase('OrderNumber'); // => '_order_number'
|
|
434
|
-
helpers.toSnakeCase('order-number'); // => 'order_number'
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
---
|
|
438
|
-
|
|
439
|
-
### `template(str, vars)`
|
|
440
|
-
|
|
441
|
-
String interpolation with `{{variable}}` syntax.
|
|
442
|
-
|
|
443
|
-
**Signature:**
|
|
444
|
-
```typescript
|
|
445
|
-
template(str: string, vars: Record<string, any>): string
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
**Examples:**
|
|
449
|
-
```typescript
|
|
450
|
-
helpers.template('Hello {{name}}!', { name: 'World' });
|
|
451
|
-
// => 'Hello World!'
|
|
452
|
-
|
|
453
|
-
helpers.template('Order {{id}} for {{customer}}', {
|
|
454
|
-
id: '123',
|
|
455
|
-
customer: 'John Doe'
|
|
456
|
-
});
|
|
457
|
-
// => 'Order 123 for John Doe'
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
---
|
|
461
|
-
|
|
462
|
-
### `slugify(str)`
|
|
463
|
-
|
|
464
|
-
Convert string to URL-safe slug.
|
|
465
|
-
|
|
466
|
-
**Signature:**
|
|
467
|
-
```typescript
|
|
468
|
-
slugify(str: string): string
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
**Examples:**
|
|
472
|
-
```typescript
|
|
473
|
-
helpers.slugify('Hello World!'); // => 'hello-world'
|
|
474
|
-
helpers.slugify('Product Name (2024)'); // => 'product-name-2024'
|
|
475
|
-
helpers.slugify('Café & Restaurant'); // => 'cafe-restaurant'
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
---
|
|
479
|
-
|
|
480
|
-
### `uuid()`
|
|
481
|
-
|
|
482
|
-
Generate UUID v4.
|
|
483
|
-
|
|
484
|
-
**Signature:**
|
|
485
|
-
```typescript
|
|
486
|
-
uuid(): string
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
**Examples:**
|
|
490
|
-
```typescript
|
|
491
|
-
helpers.uuid();
|
|
492
|
-
// => '550e8400-e29b-41d4-a716-446655440000'
|
|
493
|
-
|
|
494
|
-
// Use for unique IDs
|
|
495
|
-
const uniqueRef = `ORDER-${helpers.uuid()}`;
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
## Object Utilities
|
|
501
|
-
|
|
502
|
-
### `isEmpty(value)`
|
|
503
|
-
|
|
504
|
-
Check if value is empty (null, undefined, '', [], {}).
|
|
505
|
-
|
|
506
|
-
**Signature:**
|
|
507
|
-
```typescript
|
|
508
|
-
isEmpty(value: any): boolean
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
**Examples:**
|
|
512
|
-
```typescript
|
|
513
|
-
helpers.isEmpty(null); // => true
|
|
514
|
-
helpers.isEmpty(undefined); // => true
|
|
515
|
-
helpers.isEmpty(''); // => true
|
|
516
|
-
helpers.isEmpty([]); // => true
|
|
517
|
-
helpers.isEmpty({}); // => true
|
|
518
|
-
helpers.isEmpty('text'); // => false
|
|
519
|
-
helpers.isEmpty([1, 2]); // => false
|
|
520
|
-
helpers.isEmpty({ key: 'value' }); // => false
|
|
521
|
-
helpers.isEmpty(0); // => false (0 is not empty)
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
---
|
|
525
|
-
|
|
526
|
-
### `pick(obj, keys)`
|
|
527
|
-
|
|
528
|
-
Pick specific fields from object.
|
|
529
|
-
|
|
530
|
-
**Signature:**
|
|
531
|
-
```typescript
|
|
532
|
-
pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
**Examples:**
|
|
536
|
-
```typescript
|
|
537
|
-
const order = { id: '1', ref: 'ORD-1', status: 'OPEN', total: 100 };
|
|
538
|
-
helpers.pick(order, ['id', 'ref']);
|
|
539
|
-
// => { id: '1', ref: 'ORD-1' }
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
---
|
|
543
|
-
|
|
544
|
-
### `omit(obj, keys)`
|
|
545
|
-
|
|
546
|
-
Omit specific fields from object.
|
|
547
|
-
|
|
548
|
-
**Signature:**
|
|
549
|
-
```typescript
|
|
550
|
-
omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
**Examples:**
|
|
554
|
-
```typescript
|
|
555
|
-
const order = { id: '1', ref: 'ORD-1', status: 'OPEN', total: 100 };
|
|
556
|
-
helpers.omit(order, ['status', 'total']);
|
|
557
|
-
// => { id: '1', ref: 'ORD-1' }
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
---
|
|
561
|
-
|
|
562
|
-
### `deepClone(obj)`
|
|
563
|
-
|
|
564
|
-
Deep clone object using JSON serialization.
|
|
565
|
-
|
|
566
|
-
**Signature:**
|
|
567
|
-
```typescript
|
|
568
|
-
deepClone<T>(obj: T): T
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
**Examples:**
|
|
572
|
-
```typescript
|
|
573
|
-
const original = { a: { b: { c: 1 } } };
|
|
574
|
-
const cloned = helpers.deepClone(original);
|
|
575
|
-
cloned.a.b.c = 2;
|
|
576
|
-
console.log(original.a.b.c); // => 1 (unchanged)
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
**Warning:** Only works with JSON-serializable objects (no functions, undefined, etc.)
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
### `deepMerge(target, source)`
|
|
584
|
-
|
|
585
|
-
Merge objects deeply.
|
|
586
|
-
|
|
587
|
-
**Signature:**
|
|
588
|
-
```typescript
|
|
589
|
-
deepMerge<T extends object>(target: T, source: Partial<T>): T
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
**Examples:**
|
|
593
|
-
```typescript
|
|
594
|
-
const target = { a: { b: 1, c: 2 } };
|
|
595
|
-
const source = { a: { c: 3, d: 4 }, e: 5 };
|
|
596
|
-
helpers.deepMerge(target, source);
|
|
597
|
-
// => { a: { b: 1, c: 3, d: 4 }, e: 5 }
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
---
|
|
601
|
-
|
|
602
|
-
### `set(obj, path, value)`
|
|
603
|
-
|
|
604
|
-
Set nested property value with dot notation. Creates intermediate objects as needed.
|
|
605
|
-
|
|
606
|
-
**Signature:**
|
|
607
|
-
```typescript
|
|
608
|
-
set(obj: any, path: string, value: any): void
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
**Examples:**
|
|
612
|
-
```typescript
|
|
613
|
-
const data = {};
|
|
614
|
-
helpers.set(data, 'order.customer.email', 'test@example.com');
|
|
615
|
-
// => { order: { customer: { email: 'test@example.com' } } }
|
|
616
|
-
|
|
617
|
-
helpers.set(data, 'order.total', 100);
|
|
618
|
-
// => { order: { customer: {...}, total: 100 } }
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
---
|
|
622
|
-
|
|
623
|
-
### `merge(...objects)`
|
|
624
|
-
|
|
625
|
-
Shallow merge multiple objects.
|
|
626
|
-
|
|
627
|
-
**Signature:**
|
|
628
|
-
```typescript
|
|
629
|
-
merge<T extends object>(...objects: Partial<T>[]): T
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
**Examples:**
|
|
633
|
-
```typescript
|
|
634
|
-
const defaults = { currency: 'USD', tax: 0 };
|
|
635
|
-
const order = { total: 100, tax: 10 };
|
|
636
|
-
helpers.merge(defaults, order);
|
|
637
|
-
// => { currency: 'USD', tax: 10, total: 100 }
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
---
|
|
641
|
-
|
|
642
|
-
## Array Transformation
|
|
643
|
-
|
|
644
|
-
### `groupBy(array, key)`
|
|
645
|
-
|
|
646
|
-
Group array items by key or function.
|
|
647
|
-
|
|
648
|
-
**Signature:**
|
|
649
|
-
```typescript
|
|
650
|
-
groupBy<T>(array: T[], key: keyof T | ((item: T) => string)): Record<string, T[]>
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
**Examples:**
|
|
654
|
-
```typescript
|
|
655
|
-
const items = [
|
|
656
|
-
{ sku: 'A', category: 'electronics' },
|
|
657
|
-
{ sku: 'B', category: 'electronics' },
|
|
658
|
-
{ sku: 'C', category: 'clothing' }
|
|
659
|
-
];
|
|
660
|
-
|
|
661
|
-
helpers.groupBy(items, 'category');
|
|
662
|
-
// => {
|
|
663
|
-
// electronics: [{ sku: 'A', ... }, { sku: 'B', ... }],
|
|
664
|
-
// clothing: [{ sku: 'C', ... }]
|
|
665
|
-
// }
|
|
666
|
-
|
|
667
|
-
helpers.groupBy(items, item => item.sku[0]);
|
|
668
|
-
// => { A: [...], B: [...], C: [...] }
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
---
|
|
672
|
-
|
|
673
|
-
### `keyBy(array, key)`
|
|
674
|
-
|
|
675
|
-
Convert array to object keyed by property.
|
|
676
|
-
|
|
677
|
-
**Signature:**
|
|
678
|
-
```typescript
|
|
679
|
-
keyBy<T>(array: T[], key: keyof T | ((item: T) => string)): Record<string, T>
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
**Examples:**
|
|
683
|
-
```typescript
|
|
684
|
-
const items = [
|
|
685
|
-
{ sku: 'SKU-1', name: 'Product 1' },
|
|
686
|
-
{ sku: 'SKU-2', name: 'Product 2' }
|
|
687
|
-
];
|
|
688
|
-
|
|
689
|
-
helpers.keyBy(items, 'sku');
|
|
690
|
-
// => {
|
|
691
|
-
// 'SKU-1': { sku: 'SKU-1', name: 'Product 1' },
|
|
692
|
-
// 'SKU-2': { sku: 'SKU-2', name: 'Product 2' }
|
|
693
|
-
// }
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
---
|
|
697
|
-
|
|
698
|
-
### `chunk(array, size)`
|
|
699
|
-
|
|
700
|
-
Split array into chunks of specified size.
|
|
701
|
-
|
|
702
|
-
**Signature:**
|
|
703
|
-
```typescript
|
|
704
|
-
chunk<T>(array: T[], size: number): T[][]
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
**Examples:**
|
|
708
|
-
```typescript
|
|
709
|
-
helpers.chunk([1, 2, 3, 4, 5], 2);
|
|
710
|
-
// => [[1, 2], [3, 4], [5]]
|
|
711
|
-
|
|
712
|
-
helpers.chunk(['a', 'b', 'c', 'd', 'e', 'f'], 3);
|
|
713
|
-
// => [['a', 'b', 'c'], ['d', 'e', 'f']]
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
---
|
|
717
|
-
|
|
718
|
-
### `flatten(array, depth)`
|
|
719
|
-
|
|
720
|
-
Flatten nested arrays to specified depth.
|
|
721
|
-
|
|
722
|
-
**Signature:**
|
|
723
|
-
```typescript
|
|
724
|
-
flatten<T>(array: any[], depth?: number): T[]
|
|
725
|
-
```
|
|
726
|
-
|
|
727
|
-
**Examples:**
|
|
728
|
-
```typescript
|
|
729
|
-
helpers.flatten([[1, 2], [3, 4]], 1);
|
|
730
|
-
// => [1, 2, 3, 4]
|
|
731
|
-
|
|
732
|
-
helpers.flatten([[[1, 2]], [[3, 4]]], 2);
|
|
733
|
-
// => [1, 2, 3, 4]
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
---
|
|
737
|
-
|
|
738
|
-
### `unique(array, key?)`
|
|
739
|
-
|
|
740
|
-
Get unique values from array, optionally by key for objects.
|
|
741
|
-
|
|
742
|
-
**Signature:**
|
|
743
|
-
```typescript
|
|
744
|
-
unique<T>(array: T[], key?: keyof T | ((item: T) => any)): T[]
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
**Examples:**
|
|
748
|
-
```typescript
|
|
749
|
-
helpers.unique([1, 2, 2, 3, 3, 3]);
|
|
750
|
-
// => [1, 2, 3]
|
|
751
|
-
|
|
752
|
-
const items = [
|
|
753
|
-
{ sku: 'A', qty: 1 },
|
|
754
|
-
{ sku: 'B', qty: 2 },
|
|
755
|
-
{ sku: 'A', qty: 3 }
|
|
756
|
-
];
|
|
757
|
-
helpers.unique(items, 'sku');
|
|
758
|
-
// => [{ sku: 'A', qty: 1 }, { sku: 'B', qty: 2 }]
|
|
759
|
-
```
|
|
760
|
-
|
|
761
|
-
---
|
|
762
|
-
|
|
763
|
-
### `sortBy(array, key, order)`
|
|
764
|
-
|
|
765
|
-
Sort array by key or function.
|
|
766
|
-
|
|
767
|
-
**Signature:**
|
|
768
|
-
```typescript
|
|
769
|
-
sortBy<T>(array: T[], key: keyof T | ((item: T) => any), order?: 'asc' | 'desc'): T[]
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
**Examples:**
|
|
773
|
-
```typescript
|
|
774
|
-
const items = [
|
|
775
|
-
{ sku: 'C', price: 30 },
|
|
776
|
-
{ sku: 'A', price: 10 },
|
|
777
|
-
{ sku: 'B', price: 20 }
|
|
778
|
-
];
|
|
779
|
-
|
|
780
|
-
helpers.sortBy(items, 'price', 'asc');
|
|
781
|
-
// => [{ sku: 'A', price: 10 }, { sku: 'B', price: 20 }, { sku: 'C', price: 30 }]
|
|
782
|
-
|
|
783
|
-
helpers.sortBy(items, 'sku', 'desc');
|
|
784
|
-
// => [{ sku: 'C', ... }, { sku: 'B', ... }, { sku: 'A', ... }]
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
---
|
|
788
|
-
|
|
789
|
-
### `compact(array)`
|
|
790
|
-
|
|
791
|
-
Remove falsy values (null, undefined, false, 0, '') from array.
|
|
792
|
-
|
|
793
|
-
**Signature:**
|
|
794
|
-
```typescript
|
|
795
|
-
compact<T>(array: (T | null | undefined | false | 0 | '')[]): T[]
|
|
796
|
-
```
|
|
797
|
-
|
|
798
|
-
**Examples:**
|
|
799
|
-
```typescript
|
|
800
|
-
helpers.compact([1, null, 2, undefined, 3, false, 0, '']);
|
|
801
|
-
// => [1, 2, 3]
|
|
802
|
-
|
|
803
|
-
helpers.compact(['a', '', 'b', null, 'c']);
|
|
804
|
-
// => ['a', 'b', 'c']
|
|
805
|
-
```
|
|
806
|
-
|
|
807
|
-
---
|
|
808
|
-
|
|
809
|
-
### `coalesce(...values)`
|
|
810
|
-
|
|
811
|
-
Return first non-null/undefined value (like SQL COALESCE).
|
|
812
|
-
|
|
813
|
-
**Signature:**
|
|
814
|
-
```typescript
|
|
815
|
-
coalesce<T>(...values: (T | null | undefined)[]): T | undefined
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
**Examples:**
|
|
819
|
-
```typescript
|
|
820
|
-
helpers.coalesce(null, undefined, 'first', 'second'); // => 'first'
|
|
821
|
-
helpers.coalesce(null, 0, 1); // => 0
|
|
822
|
-
helpers.coalesce(null, '', 'value'); // => ''
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
---
|
|
826
|
-
|
|
827
|
-
## Array Aggregation
|
|
828
|
-
|
|
829
|
-
### `sum(array, key?)`
|
|
830
|
-
|
|
831
|
-
Sum numeric values in array, optionally by key for objects.
|
|
832
|
-
|
|
833
|
-
**Signature:**
|
|
834
|
-
```typescript
|
|
835
|
-
sum<T>(array: T[], key?: keyof T | ((item: T) => number)): number
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
**Examples:**
|
|
839
|
-
```typescript
|
|
840
|
-
helpers.sum([1, 2, 3, 4, 5]); // => 15
|
|
841
|
-
|
|
842
|
-
const items = [
|
|
843
|
-
{ price: 10 },
|
|
844
|
-
{ price: 20 },
|
|
845
|
-
{ price: 30 }
|
|
846
|
-
];
|
|
847
|
-
helpers.sum(items, 'price'); // => 60
|
|
848
|
-
|
|
849
|
-
helpers.sum(items, item => item.price * 1.1); // => 66 (with markup)
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
---
|
|
853
|
-
|
|
854
|
-
### `avg(array, key?)`
|
|
855
|
-
|
|
856
|
-
Calculate average of numeric values.
|
|
857
|
-
|
|
858
|
-
**Signature:**
|
|
859
|
-
```typescript
|
|
860
|
-
avg<T>(array: T[], key?: keyof T | ((item: T) => number)): number
|
|
861
|
-
```
|
|
862
|
-
|
|
863
|
-
**Examples:**
|
|
864
|
-
```typescript
|
|
865
|
-
helpers.avg([10, 20, 30]); // => 20
|
|
866
|
-
|
|
867
|
-
const items = [{ score: 80 }, { score: 90 }, { score: 70 }];
|
|
868
|
-
helpers.avg(items, 'score'); // => 80
|
|
869
|
-
```
|
|
870
|
-
|
|
871
|
-
---
|
|
872
|
-
|
|
873
|
-
### `min(array, key?)`
|
|
874
|
-
|
|
875
|
-
Find minimum value in array.
|
|
876
|
-
|
|
877
|
-
**Signature:**
|
|
878
|
-
```typescript
|
|
879
|
-
min<T>(array: T[], key?: keyof T | ((item: T) => number)): number | undefined
|
|
880
|
-
```
|
|
881
|
-
|
|
882
|
-
**Examples:**
|
|
883
|
-
```typescript
|
|
884
|
-
helpers.min([10, 5, 20, 3]); // => 3
|
|
885
|
-
|
|
886
|
-
const items = [{ price: 10 }, { price: 5 }, { price: 20 }];
|
|
887
|
-
helpers.min(items, 'price'); // => 5
|
|
888
|
-
```
|
|
889
|
-
|
|
890
|
-
---
|
|
891
|
-
|
|
892
|
-
### `max(array, key?)`
|
|
893
|
-
|
|
894
|
-
Find maximum value in array.
|
|
895
|
-
|
|
896
|
-
**Signature:**
|
|
897
|
-
```typescript
|
|
898
|
-
max<T>(array: T[], key?: keyof T | ((item: T) => number)): number | undefined
|
|
899
|
-
```
|
|
900
|
-
|
|
901
|
-
**Examples:**
|
|
902
|
-
```typescript
|
|
903
|
-
helpers.max([10, 5, 20, 3]); // => 20
|
|
904
|
-
|
|
905
|
-
const items = [{ quantity: 10 }, { quantity: 5 }, { quantity: 20 }];
|
|
906
|
-
helpers.max(items, 'quantity'); // => 20
|
|
907
|
-
```
|
|
908
|
-
|
|
909
|
-
---
|
|
910
|
-
|
|
911
|
-
### `clamp(num, min, max)`
|
|
912
|
-
|
|
913
|
-
Clamp number to specified range.
|
|
914
|
-
|
|
915
|
-
**Signature:**
|
|
916
|
-
```typescript
|
|
917
|
-
clamp(num: number, min: number, max: number): number
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
**Examples:**
|
|
921
|
-
```typescript
|
|
922
|
-
helpers.clamp(5, 0, 10); // => 5
|
|
923
|
-
helpers.clamp(-5, 0, 10); // => 0
|
|
924
|
-
helpers.clamp(15, 0, 10); // => 10
|
|
925
|
-
```
|
|
926
|
-
|
|
927
|
-
---
|
|
928
|
-
|
|
929
|
-
## Date/Time
|
|
930
|
-
|
|
931
|
-
### `addDays(date, days)`
|
|
932
|
-
|
|
933
|
-
Add days to date.
|
|
934
|
-
|
|
935
|
-
**Signature:**
|
|
936
|
-
```typescript
|
|
937
|
-
addDays(date: Date | string, days: number): Date
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
**Examples:**
|
|
941
|
-
```typescript
|
|
942
|
-
helpers.addDays(new Date('2025-01-14'), 7);
|
|
943
|
-
// => Date('2025-01-21')
|
|
944
|
-
|
|
945
|
-
helpers.addDays('2025-01-14', 30);
|
|
946
|
-
// => Date('2025-02-13')
|
|
947
|
-
```
|
|
948
|
-
|
|
949
|
-
---
|
|
950
|
-
|
|
951
|
-
### `subtractDays(date, days)`
|
|
952
|
-
|
|
953
|
-
Subtract days from date.
|
|
954
|
-
|
|
955
|
-
**Signature:**
|
|
956
|
-
```typescript
|
|
957
|
-
subtractDays(date: Date | string, days: number): Date
|
|
958
|
-
```
|
|
959
|
-
|
|
960
|
-
**Examples:**
|
|
961
|
-
```typescript
|
|
962
|
-
helpers.subtractDays(new Date('2025-01-14'), 7);
|
|
963
|
-
// => Date('2025-01-07')
|
|
964
|
-
```
|
|
965
|
-
|
|
966
|
-
---
|
|
967
|
-
|
|
968
|
-
### `dateDiff(date1, date2)`
|
|
969
|
-
|
|
970
|
-
Get difference between dates in days.
|
|
971
|
-
|
|
972
|
-
**Signature:**
|
|
973
|
-
```typescript
|
|
974
|
-
dateDiff(date1: Date | string, date2: Date | string): number
|
|
975
|
-
```
|
|
976
|
-
|
|
977
|
-
**Examples:**
|
|
978
|
-
```typescript
|
|
979
|
-
helpers.dateDiff('2025-01-14', '2025-01-21'); // => 7
|
|
980
|
-
helpers.dateDiff('2025-01-21', '2025-01-14'); // => -7
|
|
981
|
-
```
|
|
982
|
-
|
|
983
|
-
---
|
|
984
|
-
|
|
985
|
-
### `parseDate(dateStr, format?)`
|
|
986
|
-
|
|
987
|
-
Parse date with multiple format support.
|
|
988
|
-
|
|
989
|
-
**Signature:**
|
|
990
|
-
```typescript
|
|
991
|
-
parseDate(dateStr: string, format?: string): Date | null
|
|
992
|
-
```
|
|
993
|
-
|
|
994
|
-
**Supported Formats:**
|
|
995
|
-
- ISO: `'2025-01-14'`
|
|
996
|
-
- US: `'01/14/2025'`
|
|
997
|
-
- EU: `'14-01-2025'`
|
|
998
|
-
- Compact: `'20250114'`
|
|
999
|
-
|
|
1000
|
-
**Examples:**
|
|
1001
|
-
```typescript
|
|
1002
|
-
helpers.parseDate('2025-01-14'); // ISO
|
|
1003
|
-
helpers.parseDate('01/14/2025'); // MM/DD/YYYY
|
|
1004
|
-
helpers.parseDate('14-01-2025'); // DD-MM-YYYY
|
|
1005
|
-
helpers.parseDate('20250114'); // YYYYMMDD
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
|
-
**Returns:** `Date` object or `null` if parsing fails
|
|
1009
|
-
|
|
1010
|
-
---
|
|
1011
|
-
|
|
1012
|
-
## Function Utilities
|
|
1013
|
-
|
|
1014
|
-
### `debounce(fn, delayMs)`
|
|
1015
|
-
|
|
1016
|
-
Delay function execution until after delay period.
|
|
1017
|
-
|
|
1018
|
-
**Signature:**
|
|
1019
|
-
```typescript
|
|
1020
|
-
debounce<T extends (...args: any[]) => any>(fn: T, delayMs: number): T
|
|
1021
|
-
```
|
|
1022
|
-
|
|
1023
|
-
**Examples:**
|
|
1024
|
-
```typescript
|
|
1025
|
-
const logMessage = (msg: string) => console.log(msg);
|
|
1026
|
-
const debouncedLog = helpers.debounce(logMessage, 1000);
|
|
1027
|
-
|
|
1028
|
-
debouncedLog('Message 1'); // Cancelled
|
|
1029
|
-
debouncedLog('Message 2'); // Cancelled
|
|
1030
|
-
debouncedLog('Message 3'); // Executed after 1000ms
|
|
1031
|
-
```
|
|
1032
|
-
|
|
1033
|
-
---
|
|
1034
|
-
|
|
1035
|
-
### `throttle(fn, limitMs)`
|
|
1036
|
-
|
|
1037
|
-
Limit function execution rate.
|
|
1038
|
-
|
|
1039
|
-
**Signature:**
|
|
1040
|
-
```typescript
|
|
1041
|
-
throttle<T extends (...args: any[]) => any>(fn: T, limitMs: number): T
|
|
1042
|
-
```
|
|
1043
|
-
|
|
1044
|
-
**Examples:**
|
|
1045
|
-
```typescript
|
|
1046
|
-
const logMessage = (msg: string) => console.log(msg);
|
|
1047
|
-
const throttledLog = helpers.throttle(logMessage, 1000);
|
|
1048
|
-
|
|
1049
|
-
throttledLog('Message 1'); // Executed immediately
|
|
1050
|
-
throttledLog('Message 2'); // Ignored (within 1000ms)
|
|
1051
|
-
// Wait 1000ms
|
|
1052
|
-
throttledLog('Message 3'); // Executed
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
---
|
|
1056
|
-
|
|
1057
|
-
## Type Guards
|
|
1058
|
-
|
|
1059
|
-
### `isString(value)`, `isNumber(value)`, `isArray(value)`, `isObject(value)`, `isDate(value)`
|
|
1060
|
-
|
|
1061
|
-
Type checking utilities.
|
|
1062
|
-
|
|
1063
|
-
**Signatures:**
|
|
1064
|
-
```typescript
|
|
1065
|
-
isString(value: any): boolean
|
|
1066
|
-
isNumber(value: any): boolean
|
|
1067
|
-
isArray(value: any): boolean
|
|
1068
|
-
isObject(value: any): boolean
|
|
1069
|
-
isDate(value: any): boolean
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
**Examples:**
|
|
1073
|
-
```typescript
|
|
1074
|
-
helpers.isString('hello'); // => true
|
|
1075
|
-
helpers.isNumber(123); // => true
|
|
1076
|
-
helpers.isNumber(NaN); // => false
|
|
1077
|
-
helpers.isArray([1, 2, 3]); // => true
|
|
1078
|
-
helpers.isObject({ key: 'value' }); // => true
|
|
1079
|
-
helpers.isObject([1, 2, 3]); // => false
|
|
1080
|
-
helpers.isDate(new Date()); // => true
|
|
1081
|
-
helpers.isDate('2025-01-14'); // => false
|
|
1082
|
-
```
|
|
1083
|
-
|
|
1084
|
-
---
|
|
1085
|
-
|
|
1086
|
-
## Utility Functions
|
|
1087
|
-
|
|
1088
|
-
### `defaultTo(value, defaultValue)`
|
|
1089
|
-
|
|
1090
|
-
Return default if value is null/undefined.
|
|
1091
|
-
|
|
1092
|
-
**Signature:**
|
|
1093
|
-
```typescript
|
|
1094
|
-
defaultTo<T>(value: T | null | undefined, defaultValue: T): T
|
|
1095
|
-
```
|
|
1096
|
-
|
|
1097
|
-
**Examples:**
|
|
1098
|
-
```typescript
|
|
1099
|
-
helpers.defaultTo(null, 'default'); // => 'default'
|
|
1100
|
-
helpers.defaultTo(undefined, 'default'); // => 'default'
|
|
1101
|
-
helpers.defaultTo('value', 'default'); // => 'value'
|
|
1102
|
-
helpers.defaultTo(0, 10); // => 0 (0 is not null/undefined)
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
---
|
|
1106
|
-
|
|
1107
|
-
### `range(start, end?, step?)`
|
|
1108
|
-
|
|
1109
|
-
Generate numeric ranges.
|
|
1110
|
-
|
|
1111
|
-
**Signature:**
|
|
1112
|
-
```typescript
|
|
1113
|
-
range(start: number, end?: number, step?: number): number[]
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
**Examples:**
|
|
1117
|
-
```typescript
|
|
1118
|
-
helpers.range(5); // => [0, 1, 2, 3, 4]
|
|
1119
|
-
helpers.range(1, 6); // => [1, 2, 3, 4, 5]
|
|
1120
|
-
helpers.range(0, 10, 2); // => [0, 2, 4, 6, 8]
|
|
1121
|
-
helpers.range(10, 0, -2); // => [10, 8, 6, 4, 2]
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
---
|
|
1125
|
-
|
|
1126
|
-
### `hashString(str)`
|
|
1127
|
-
|
|
1128
|
-
Generate deterministic hash from string (not cryptographically secure).
|
|
1129
|
-
|
|
1130
|
-
**Signature:**
|
|
1131
|
-
```typescript
|
|
1132
|
-
hashString(str: string): string
|
|
1133
|
-
```
|
|
1134
|
-
|
|
1135
|
-
**Examples:**
|
|
1136
|
-
```typescript
|
|
1137
|
-
helpers.hashString('hello'); // => '4x93m' (deterministic)
|
|
1138
|
-
helpers.hashString('hello'); // => '4x93m' (same input = same output)
|
|
1139
|
-
```
|
|
1140
|
-
|
|
1141
|
-
**Use Case:** Stable keys, content-based IDs, deduplication keys
|
|
1142
|
-
|
|
1143
|
-
---
|
|
1144
|
-
|
|
1145
|
-
## Performance
|
|
1146
|
-
|
|
1147
|
-
### `memoize(fn)`
|
|
1148
|
-
|
|
1149
|
-
Memoize expensive function.
|
|
1150
|
-
|
|
1151
|
-
**Signature:**
|
|
1152
|
-
```typescript
|
|
1153
|
-
memoize<T extends (...args: any[]) => any>(fn: T): T
|
|
1154
|
-
```
|
|
1155
|
-
|
|
1156
|
-
**Examples:**
|
|
1157
|
-
```typescript
|
|
1158
|
-
const expensiveCalculation = (a, b) => {
|
|
1159
|
-
console.log('Calculating...');
|
|
1160
|
-
return a + b;
|
|
1161
|
-
};
|
|
1162
|
-
|
|
1163
|
-
const memoized = helpers.memoize(expensiveCalculation);
|
|
1164
|
-
|
|
1165
|
-
memoized(1, 2); // => Logs "Calculating...", returns 3
|
|
1166
|
-
memoized(1, 2); // => Returns 3 (from cache, no log)
|
|
1167
|
-
memoized(2, 3); // => Logs "Calculating...", returns 5
|
|
1168
|
-
```
|
|
1169
|
-
|
|
1170
|
-
---
|
|
1171
|
-
|
|
1172
|
-
### `retry(fn, maxRetries?, delayMs?)`
|
|
1173
|
-
|
|
1174
|
-
Retry function with exponential backoff.
|
|
1175
|
-
|
|
1176
|
-
**Signature:**
|
|
1177
|
-
```typescript
|
|
1178
|
-
retry<T>(fn: () => Promise<T>, maxRetries?: number, delayMs?: number): Promise<T>
|
|
1179
|
-
```
|
|
1180
|
-
|
|
1181
|
-
**Parameters:**
|
|
1182
|
-
- `fn` - Async function to retry
|
|
1183
|
-
- `maxRetries` - Max attempts (default: 3)
|
|
1184
|
-
- `delayMs` - Initial delay (default: 100ms)
|
|
1185
|
-
|
|
1186
|
-
**Examples:**
|
|
1187
|
-
```typescript
|
|
1188
|
-
const result = await helpers.retry(
|
|
1189
|
-
async () => {
|
|
1190
|
-
const response = await fetch('https://api.example.com/data');
|
|
1191
|
-
return response.json();
|
|
1192
|
-
},
|
|
1193
|
-
3, // Max 3 retries
|
|
1194
|
-
100 // Start with 100ms delay
|
|
1195
|
-
);
|
|
1196
|
-
```
|
|
1197
|
-
|
|
1198
|
-
---
|
|
1199
|
-
|
|
1200
|
-
### `batchProcess(items, processor, batchSize?)`
|
|
1201
|
-
|
|
1202
|
-
Process array in batches (async, default: 50 items/batch).
|
|
1203
|
-
|
|
1204
|
-
**Signature:**
|
|
1205
|
-
```typescript
|
|
1206
|
-
batchProcess<T, R>(
|
|
1207
|
-
items: T[],
|
|
1208
|
-
processor: (item: T, index: number) => Promise<R>,
|
|
1209
|
-
batchSize?: number
|
|
1210
|
-
): Promise<R[]>
|
|
1211
|
-
```
|
|
1212
|
-
|
|
1213
|
-
**Examples:**
|
|
1214
|
-
```typescript
|
|
1215
|
-
const items = [1, 2, 3, 4, 5];
|
|
1216
|
-
const results = await helpers.batchProcess(
|
|
1217
|
-
items,
|
|
1218
|
-
async (item, index) => {
|
|
1219
|
-
// Call external API
|
|
1220
|
-
return await fetchData(item);
|
|
1221
|
-
},
|
|
1222
|
-
2 // Process 2 items at a time
|
|
1223
|
-
);
|
|
1224
|
-
```
|
|
1225
|
-
|
|
1226
|
-
---
|
|
1227
|
-
|
|
1228
|
-
## XML/JSON Specific
|
|
1229
|
-
|
|
1230
|
-
### `extractCustomAttribute(customAttributes, attributeId, defaultValue?)`
|
|
1231
|
-
|
|
1232
|
-
Extract custom attribute by ID from XML/JSON custom attributes.
|
|
1233
|
-
|
|
1234
|
-
**Signature:**
|
|
1235
|
-
```typescript
|
|
1236
|
-
extractCustomAttribute(customAttributes: any, attributeId: string, defaultValue?: any): any
|
|
1237
|
-
```
|
|
1238
|
-
|
|
1239
|
-
**Handles Multiple Formats:**
|
|
1240
|
-
- Array of attributes: `[{ '@attribute-id': 'id', '#text': 'value' }, ...]`
|
|
1241
|
-
- Single attribute object: `{ '@attribute-id': 'id', '#text': 'value' }`
|
|
1242
|
-
- Object with keys: `{ 'key1': 'value1', 'key2': 'value2' }`
|
|
1243
|
-
|
|
1244
|
-
**Examples:**
|
|
1245
|
-
```typescript
|
|
1246
|
-
// Array format (SFCC XML)
|
|
1247
|
-
const attrs = [
|
|
1248
|
-
{ '@attribute-id': 'retailerId', '#text': '123' },
|
|
1249
|
-
{ '@attribute-id': 'orderType', '#text': 'HD' }
|
|
1250
|
-
];
|
|
1251
|
-
helpers.extractCustomAttribute(attrs, 'retailerId');
|
|
1252
|
-
// => '123'
|
|
1253
|
-
|
|
1254
|
-
// Object format
|
|
1255
|
-
const attrs2 = { 'retailerId': '123', 'orderType': 'HD' };
|
|
1256
|
-
helpers.extractCustomAttribute(attrs2, 'orderType');
|
|
1257
|
-
// => 'HD'
|
|
1258
|
-
|
|
1259
|
-
// With default
|
|
1260
|
-
helpers.extractCustomAttribute(attrs, 'missing', 'DEFAULT');
|
|
1261
|
-
// => 'DEFAULT'
|
|
1262
|
-
```
|
|
1263
|
-
|
|
1264
|
-
---
|
|
1265
|
-
|
|
1266
|
-
### `getXmlAttribute(obj, attrName, defaultValue?)`
|
|
1267
|
-
|
|
1268
|
-
Extract XML attribute from object with multi-format support. Automatically handles different XML parser formats.
|
|
1269
|
-
|
|
1270
|
-
**Signature:**
|
|
1271
|
-
```typescript
|
|
1272
|
-
getXmlAttribute(obj: any, attrName: string, defaultValue?: any): any
|
|
1273
|
-
```
|
|
1274
|
-
|
|
1275
|
-
**Supported XML Attribute Formats:**
|
|
1276
|
-
The function tries multiple formats in priority order:
|
|
1277
|
-
1. `$attr-name` - Versori/xml2js with $ prefix as direct key
|
|
1278
|
-
2. `$['attr-name']` - Nested in $ object (Versori platform format)
|
|
1279
|
-
3. `@attr-name` - SDK XMLParserService default format
|
|
1280
|
-
4. `@['attr-name']` - Nested in @ object (alternative format)
|
|
1281
|
-
5. `attr-name` - Direct attribute (fallback)
|
|
1282
|
-
6. `_attributes['attr-name']` - xml2js _attributes format
|
|
1283
|
-
|
|
1284
|
-
**Why This Exists:**
|
|
1285
|
-
Different XML parsers store attributes in different formats. This helper eliminates the need to manually check multiple formats in resolvers.
|
|
1286
|
-
|
|
1287
|
-
**Examples:**
|
|
1288
|
-
```typescript
|
|
1289
|
-
// Versori format (nested $ object)
|
|
1290
|
-
const versoriData = { $: { 'shipment-id': '02408380' } };
|
|
1291
|
-
helpers.getXmlAttribute(versoriData, 'shipment-id');
|
|
1292
|
-
// => '02408380'
|
|
1293
|
-
|
|
1294
|
-
// SDK format (@ prefix)
|
|
1295
|
-
const sdkData = { '@shipment-id': '02408380' };
|
|
1296
|
-
helpers.getXmlAttribute(sdkData, 'shipment-id');
|
|
1297
|
-
// => '02408380'
|
|
1298
|
-
|
|
1299
|
-
// Direct format
|
|
1300
|
-
const directData = { 'shipment-id': '02408380' };
|
|
1301
|
-
helpers.getXmlAttribute(directData, 'shipment-id');
|
|
1302
|
-
// => '02408380'
|
|
1303
|
-
|
|
1304
|
-
// With default value
|
|
1305
|
-
helpers.getXmlAttribute({}, 'shipment-id', 'DEFAULT');
|
|
1306
|
-
// => 'DEFAULT'
|
|
1307
|
-
|
|
1308
|
-
// Real-world usage in resolver
|
|
1309
|
-
'custom.createFulfilmentChoiceRef': (value, data, config, helpers) => {
|
|
1310
|
-
const shipmentData = value || data || {};
|
|
1311
|
-
const shipmentId = helpers.getXmlAttribute(shipmentData, 'shipment-id');
|
|
1312
|
-
return `fc_${shipmentId}`;
|
|
1313
|
-
}
|
|
1314
|
-
```
|
|
1315
|
-
|
|
1316
|
-
**Use Cases:**
|
|
1317
|
-
- Extracting XML attributes in custom resolvers
|
|
1318
|
-
- Handling multiple XML parser formats (Versori, SDK, xml2js)
|
|
1319
|
-
- Simplifying resolver code (no need to check multiple formats manually)
|
|
1320
|
-
|
|
1321
|
-
**Returns:** Attribute value or `defaultValue` (or `undefined`)
|
|
1322
|
-
|
|
1323
|
-
---
|
|
1324
|
-
|
|
1325
|
-
### `getXmlTextContent(obj, defaultValue?)`
|
|
1326
|
-
|
|
1327
|
-
Extract XML text content from object with multi-format support. Automatically handles different XML parser formats for text content.
|
|
1328
|
-
|
|
1329
|
-
**Signature:**
|
|
1330
|
-
```typescript
|
|
1331
|
-
getXmlTextContent(obj: any, defaultValue?: any): any
|
|
1332
|
-
```
|
|
1333
|
-
|
|
1334
|
-
**Supported XML Text Content Formats:**
|
|
1335
|
-
The function tries multiple formats in priority order:
|
|
1336
|
-
1. `_` - Versori platform format (text content)
|
|
1337
|
-
2. `#text` - SDK XMLParserService default format (text content)
|
|
1338
|
-
3. `value` - Fallback property
|
|
1339
|
-
4. Direct value - If already a string/primitive
|
|
1340
|
-
|
|
1341
|
-
**Why This Exists:**
|
|
1342
|
-
Different XML parsers store text content in different properties. This helper eliminates the need to manually check multiple formats in resolvers.
|
|
1343
|
-
|
|
1344
|
-
**Examples:**
|
|
1345
|
-
```typescript
|
|
1346
|
-
// Versori format (text in _ property)
|
|
1347
|
-
const versoriData = { $: { unit: '1' }, _: '1.0' };
|
|
1348
|
-
helpers.getXmlTextContent(versoriData);
|
|
1349
|
-
// => '1.0'
|
|
1350
|
-
|
|
1351
|
-
// SDK format (text in #text property)
|
|
1352
|
-
const sdkData = { '@unit': '1', '#text': '1.0' };
|
|
1353
|
-
helpers.getXmlTextContent(sdkData);
|
|
1354
|
-
// => '1.0'
|
|
1355
|
-
|
|
1356
|
-
// Direct string
|
|
1357
|
-
helpers.getXmlTextContent('1.0');
|
|
1358
|
-
// => '1.0'
|
|
1359
|
-
|
|
1360
|
-
// With default value
|
|
1361
|
-
helpers.getXmlTextContent({}, 'DEFAULT');
|
|
1362
|
-
// => 'DEFAULT'
|
|
1363
|
-
|
|
1364
|
-
// Real-world usage in resolver
|
|
1365
|
-
'custom.parseQuantity': (value, data, config, helpers) => {
|
|
1366
|
-
const qty = helpers.getXmlTextContent(value) ?? value;
|
|
1367
|
-
return parseFloat(String(qty));
|
|
1368
|
-
}
|
|
1369
|
-
```
|
|
1370
|
-
|
|
1371
|
-
**Use Cases:**
|
|
1372
|
-
- Extracting XML text content in custom resolvers
|
|
1373
|
-
- Handling multiple XML parser formats (Versori, SDK, xml2js)
|
|
1374
|
-
- Simplifying resolver code (no need to check multiple formats manually)
|
|
1375
|
-
|
|
1376
|
-
**Returns:** Text content value or `defaultValue` (or `undefined`)
|
|
1377
|
-
|
|
1378
|
-
---
|
|
1379
|
-
|
|
1380
|
-
### `normalizeEmpty(value, defaultValue?, trimWhitespace?)`
|
|
1381
|
-
|
|
1382
|
-
Normalize empty value handling null, undefined, empty string, and whitespace. Useful for CSV and JSON data where empty values may be represented differently.
|
|
1383
|
-
|
|
1384
|
-
**Signature:**
|
|
1385
|
-
```typescript
|
|
1386
|
-
normalizeEmpty(value: any, defaultValue?: any, trimWhitespace?: boolean): any
|
|
1387
|
-
```
|
|
1388
|
-
|
|
1389
|
-
**Normalization Rules:**
|
|
1390
|
-
- `null` → defaultValue
|
|
1391
|
-
- `undefined` → defaultValue
|
|
1392
|
-
- `''` (empty string) → defaultValue
|
|
1393
|
-
- `' '` (whitespace-only) → defaultValue (if trimWhitespace: true, default)
|
|
1394
|
-
- Other values → returned as-is
|
|
1395
|
-
|
|
1396
|
-
**Parameters:**
|
|
1397
|
-
- `value` - Value to normalize
|
|
1398
|
-
- `defaultValue` - Value to return if empty (default: undefined)
|
|
1399
|
-
- `trimWhitespace` - Whether to treat whitespace-only strings as empty (default: true)
|
|
1400
|
-
|
|
1401
|
-
**Examples:**
|
|
1402
|
-
```typescript
|
|
1403
|
-
// CSV empty values
|
|
1404
|
-
helpers.normalizeEmpty(null, 'N/A'); // => 'N/A'
|
|
1405
|
-
helpers.normalizeEmpty(undefined, 'N/A'); // => 'N/A'
|
|
1406
|
-
helpers.normalizeEmpty('', 'N/A'); // => 'N/A'
|
|
1407
|
-
helpers.normalizeEmpty(' ', 'N/A'); // => 'N/A' (trimWhitespace: true)
|
|
1408
|
-
helpers.normalizeEmpty('value', 'N/A'); // => 'value'
|
|
1409
|
-
|
|
1410
|
-
// JSON null handling
|
|
1411
|
-
helpers.normalizeEmpty(jsonData.field, 'DEFAULT'); // => 'DEFAULT' if null/undefined/empty
|
|
1412
|
-
|
|
1413
|
-
// Preserve whitespace when needed
|
|
1414
|
-
helpers.normalizeEmpty(' ', 'N/A', false); // => ' ' (preserves whitespace)
|
|
1415
|
-
```
|
|
1416
|
-
|
|
1417
|
-
**Use Cases:**
|
|
1418
|
-
- Normalizing CSV empty values (null, '', whitespace)
|
|
1419
|
-
- Handling JSON null/undefined values
|
|
1420
|
-
- Consistent empty value handling across data sources
|
|
1421
|
-
- Simplifying resolver code (no need to check multiple empty formats)
|
|
1422
|
-
|
|
1423
|
-
**Returns:** Normalized value or `defaultValue` (or `undefined`)
|
|
1424
|
-
|
|
1425
|
-
---
|
|
1426
|
-
|
|
1427
|
-
## See Also
|
|
1428
|
-
|
|
1429
|
-
- [Main Resolver Guide](./mapping-resolvers-resolver-guide.md) - Getting started
|
|
1430
|
-
- [API Reference](./mapping-resolvers-resolver-api-reference.md) - ResolverBuilder methods
|
|
1431
|
-
- [Parameters Reference](./mapping-resolvers-resolver-parameters-reference.md) - value, data, config, helpers
|
|
1432
|
-
- [Troubleshooting](./mapping-resolvers-resolver-troubleshooting.md) - Common issues
|
|
1433
|
-
- [Cookbook](./mapping-resolvers-resolver-cookbook.md) - Advanced patterns
|
|
1434
|
-
|
|
1435
|
-
---
|
|
1436
|
-
|
|
1437
|
-
**License:** MIT
|
|
1
|
+
# Resolver Helper Functions Reference
|
|
2
|
+
|
|
3
|
+
**Complete reference for all 57 helper utilities**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Overview](#overview)
|
|
10
|
+
2. [Data Access](#data-access) (2 functions)
|
|
11
|
+
3. [Parsing](#parsing) (3 functions)
|
|
12
|
+
4. [Formatting](#formatting) (2 functions)
|
|
13
|
+
5. [Validation](#validation) (3 functions)
|
|
14
|
+
6. [String Utilities](#string-utilities) (8 functions)
|
|
15
|
+
7. [Object Utilities](#object-utilities) (7 functions)
|
|
16
|
+
8. [Array Transformation](#array-transformation) (8 functions)
|
|
17
|
+
9. [Array Aggregation](#array-aggregation) (5 functions)
|
|
18
|
+
10. [Date/Time](#datetime) (5 functions)
|
|
19
|
+
11. [Function Utilities](#function-utilities) (2 functions)
|
|
20
|
+
12. [Type Guards](#type-guards) (5 functions)
|
|
21
|
+
13. [Utility Functions](#utility-functions) (3 functions)
|
|
22
|
+
14. [Performance](#performance) (3 functions)
|
|
23
|
+
15. [XML/JSON Specific](#xmljson-specific) (5 functions)
|
|
24
|
+
|
|
25
|
+
**Total: 57 helper functions**
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Overview
|
|
30
|
+
|
|
31
|
+
Helper functions are available through the `helpers` parameter in every resolver:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { ResolverHelpers } from '@fluentcommerce/fc-connect-sdk';
|
|
35
|
+
|
|
36
|
+
// In resolvers
|
|
37
|
+
builder.field('input.ref', (data, config, helpers) => {
|
|
38
|
+
// helpers.get(), helpers.parseFloatSafe(), etc.
|
|
39
|
+
return helpers.get(data, 'order.orderNo');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Standalone usage
|
|
43
|
+
const value = ResolverHelpers.get(data, 'order.orderNo');
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Import Options
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Import all helpers
|
|
50
|
+
import { ResolverHelpers } from '@fluentcommerce/fc-connect-sdk';
|
|
51
|
+
|
|
52
|
+
// Import specific helpers
|
|
53
|
+
import {
|
|
54
|
+
get,
|
|
55
|
+
formatDate,
|
|
56
|
+
formatCurrency,
|
|
57
|
+
parseFloatSafe
|
|
58
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Data Access
|
|
64
|
+
|
|
65
|
+
### `get(obj, path, defaultValue?)`
|
|
66
|
+
|
|
67
|
+
Safe nested property getter with dot notation. Never throws errors.
|
|
68
|
+
|
|
69
|
+
**Signature:**
|
|
70
|
+
```typescript
|
|
71
|
+
get(obj: any, path: string, defaultValue?: any): any
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Supported Path Syntax:**
|
|
75
|
+
- Dot notation: `'order.customer.email'`
|
|
76
|
+
- Array indexing: `'items[0].name'`
|
|
77
|
+
- XML attributes: `'order@order-no'` (note: NO dot before @)
|
|
78
|
+
- Filters: `'custom-attribute[attribute-id=value]'`
|
|
79
|
+
|
|
80
|
+
**Examples:**
|
|
81
|
+
```typescript
|
|
82
|
+
// Simple path
|
|
83
|
+
const email = helpers.get(data, 'orders.order.customer.customer-email');
|
|
84
|
+
|
|
85
|
+
// With default
|
|
86
|
+
const currency = helpers.get(data, 'orders.order.currency', 'USD');
|
|
87
|
+
|
|
88
|
+
// Array access
|
|
89
|
+
const firstItem = helpers.get(data, 'orders.order.product-lineitems.product-lineitem[0]');
|
|
90
|
+
|
|
91
|
+
// XML attribute (NO dot before @)
|
|
92
|
+
const orderNo = helpers.get(data, 'orders.order@order-no');
|
|
93
|
+
|
|
94
|
+
// Nested with default
|
|
95
|
+
const street = helpers.get(data, 'customer.address.street1', 'N/A');
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Returns:** Value at path or `defaultValue` (or `undefined`)
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### `ensureArray(value)`
|
|
103
|
+
|
|
104
|
+
Convert single items to arrays. Returns empty array for null/undefined.
|
|
105
|
+
|
|
106
|
+
**Signature:**
|
|
107
|
+
```typescript
|
|
108
|
+
ensureArray<T>(val: T | T[] | null | undefined): T[]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Behavior:**
|
|
112
|
+
- `undefined` or `null` → `[]`
|
|
113
|
+
- Array → Returns array unchanged
|
|
114
|
+
- Single object → `[object]`
|
|
115
|
+
- Primitive → `[primitive]`
|
|
116
|
+
|
|
117
|
+
**Examples:**
|
|
118
|
+
```typescript
|
|
119
|
+
helpers.ensureArray([1, 2, 3]); // => [1, 2, 3]
|
|
120
|
+
helpers.ensureArray('single'); // => ['single']
|
|
121
|
+
helpers.ensureArray(null); // => []
|
|
122
|
+
helpers.ensureArray({ id: 1 }); // => [{ id: 1 }]
|
|
123
|
+
|
|
124
|
+
// Real-world: Handle XML single vs multiple elements
|
|
125
|
+
const items = helpers.get(data, 'orders.order.product-lineitems.product-lineitem');
|
|
126
|
+
// items might be object (1 item) or array (multiple items)
|
|
127
|
+
const itemsArray = helpers.ensureArray(items);
|
|
128
|
+
itemsArray.forEach(item => { ... }); // Always works!
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Use Case:** XML parsing where single elements return object, multiple return array.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Parsing
|
|
136
|
+
|
|
137
|
+
### `parseFloatSafe(value, defaultValue?)`
|
|
138
|
+
|
|
139
|
+
Parse float with safe fallback. Never throws.
|
|
140
|
+
|
|
141
|
+
**Signature:**
|
|
142
|
+
```typescript
|
|
143
|
+
parseFloatSafe(value: any, defaultValue?: number): number
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Examples:**
|
|
147
|
+
```typescript
|
|
148
|
+
helpers.parseFloatSafe('10.50', 0); // => 10.5
|
|
149
|
+
helpers.parseFloatSafe('invalid', 0); // => 0
|
|
150
|
+
helpers.parseFloatSafe(null, 99.99); // => 99.99
|
|
151
|
+
helpers.parseFloatSafe('123.456'); // => 123.456
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Returns:** Parsed number or `defaultValue` (or `0`)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### `parseIntSafe(value, defaultValue?)`
|
|
159
|
+
|
|
160
|
+
Parse integer with safe fallback. Never throws.
|
|
161
|
+
|
|
162
|
+
**Signature:**
|
|
163
|
+
```typescript
|
|
164
|
+
parseIntSafe(value: any, defaultValue?: number): number
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Examples:**
|
|
168
|
+
```typescript
|
|
169
|
+
helpers.parseIntSafe('5', 1); // => 5
|
|
170
|
+
helpers.parseIntSafe('5.7', 1); // => 5 (truncates)
|
|
171
|
+
helpers.parseIntSafe('invalid', 1); // => 1
|
|
172
|
+
helpers.parseIntSafe(null, 100); // => 100
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Returns:** Parsed integer or `defaultValue` (or `0`)
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `safeJsonParse(jsonString, defaultValue?)`
|
|
180
|
+
|
|
181
|
+
Parse JSON with safe fallback. Never throws.
|
|
182
|
+
|
|
183
|
+
**Signature:**
|
|
184
|
+
```typescript
|
|
185
|
+
safeJsonParse<T = any>(jsonString: string, defaultValue?: T): T
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Examples:**
|
|
189
|
+
```typescript
|
|
190
|
+
helpers.safeJsonParse('{"key":"value"}', {});
|
|
191
|
+
// => { key: 'value' }
|
|
192
|
+
|
|
193
|
+
helpers.safeJsonParse('invalid json', {});
|
|
194
|
+
// => {}
|
|
195
|
+
|
|
196
|
+
helpers.safeJsonParse('["a","b"]', []);
|
|
197
|
+
// => ['a', 'b']
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Returns:** Parsed object or `defaultValue` (or `{}`)
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Formatting
|
|
205
|
+
|
|
206
|
+
### `formatDate(date)`
|
|
207
|
+
|
|
208
|
+
Format date to ISO8601 string.
|
|
209
|
+
|
|
210
|
+
**Signature:**
|
|
211
|
+
```typescript
|
|
212
|
+
formatDate(date: Date | string): string
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Examples:**
|
|
216
|
+
```typescript
|
|
217
|
+
helpers.formatDate('2025-01-14');
|
|
218
|
+
// => '2025-01-14T00:00:00.000Z'
|
|
219
|
+
|
|
220
|
+
helpers.formatDate(new Date('2025-01-14T10:30:00Z'));
|
|
221
|
+
// => '2025-01-14T10:30:00.000Z'
|
|
222
|
+
|
|
223
|
+
helpers.formatDate(1705227000000); // Timestamp
|
|
224
|
+
// => '2025-01-14T06:30:00.000Z'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Returns:** ISO8601 formatted string
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### `formatCurrency(amount, scale?)`
|
|
232
|
+
|
|
233
|
+
Format currency with specified decimal places. Uses half-down rounding.
|
|
234
|
+
|
|
235
|
+
**Signature:**
|
|
236
|
+
```typescript
|
|
237
|
+
formatCurrency(amount: number, scale?: number): string
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Parameters:**
|
|
241
|
+
- `amount: number` - Amount to format
|
|
242
|
+
- `scale?: number` - Decimal places (default: 2)
|
|
243
|
+
|
|
244
|
+
**Rounding:** Half-down (0.5 rounds toward zero)
|
|
245
|
+
- `10.555` → `'10.55'`
|
|
246
|
+
- `10.556` → `'10.56'`
|
|
247
|
+
|
|
248
|
+
**Examples:**
|
|
249
|
+
```typescript
|
|
250
|
+
helpers.formatCurrency(10.555, 2); // => '10.55'
|
|
251
|
+
helpers.formatCurrency(10.556, 2); // => '10.56'
|
|
252
|
+
helpers.formatCurrency(99.999, 2); // => '100.00'
|
|
253
|
+
helpers.formatCurrency(1234.5, 2); // => '1234.50'
|
|
254
|
+
helpers.formatCurrency(7.123456, 4); // => '7.1235'
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Returns:** Formatted currency string
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Validation
|
|
262
|
+
|
|
263
|
+
### `isValidEmail(email)`
|
|
264
|
+
|
|
265
|
+
Validate email format using regex.
|
|
266
|
+
|
|
267
|
+
**Signature:**
|
|
268
|
+
```typescript
|
|
269
|
+
isValidEmail(email: string): boolean
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Examples:**
|
|
273
|
+
```typescript
|
|
274
|
+
helpers.isValidEmail('test@example.com'); // => true
|
|
275
|
+
helpers.isValidEmail('user+tag@domain.co.uk'); // => true
|
|
276
|
+
helpers.isValidEmail('invalid-email'); // => false
|
|
277
|
+
helpers.isValidEmail('missing@domain'); // => false
|
|
278
|
+
helpers.isValidEmail(''); // => false
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Returns:** `true` if valid email, `false` otherwise
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### `requireField(value, fieldName)`
|
|
286
|
+
|
|
287
|
+
Validate required field. Throws error if missing/empty.
|
|
288
|
+
|
|
289
|
+
**Signature:**
|
|
290
|
+
```typescript
|
|
291
|
+
requireField(value: any, fieldName: string): void
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Throws:** Error if value is `null`, `undefined`, or empty string
|
|
295
|
+
|
|
296
|
+
**Examples:**
|
|
297
|
+
```typescript
|
|
298
|
+
helpers.requireField(orderRef, 'Order Reference');
|
|
299
|
+
// OK if orderRef has value
|
|
300
|
+
|
|
301
|
+
helpers.requireField(null, 'Customer ID');
|
|
302
|
+
// Throws: 'Required field missing: Customer ID'
|
|
303
|
+
|
|
304
|
+
helpers.requireField('', 'Email');
|
|
305
|
+
// Throws: 'Required field missing: Email'
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Use Case:** Enforce required fields in resolvers
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### `mapValue(value, mapping, defaultValue?)`
|
|
313
|
+
|
|
314
|
+
Map value using mapping object.
|
|
315
|
+
|
|
316
|
+
**Signature:**
|
|
317
|
+
```typescript
|
|
318
|
+
mapValue<T>(value: any, mapping: Record<string, T>, defaultValue?: T): T
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Examples:**
|
|
322
|
+
```typescript
|
|
323
|
+
const channelMapping = {
|
|
324
|
+
'Storefront': 'HD',
|
|
325
|
+
'CallCenter': 'CC',
|
|
326
|
+
'Mobile': 'MOBILE'
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
helpers.mapValue('Storefront', channelMapping, 'UNKNOWN'); // => 'HD'
|
|
330
|
+
helpers.mapValue('POS', channelMapping, 'STORE'); // => 'STORE' (default)
|
|
331
|
+
helpers.mapValue('CallCenter', channelMapping); // => 'CC'
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Returns:** Mapped value or `defaultValue` (or `undefined`)
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## String Utilities
|
|
339
|
+
|
|
340
|
+
### `fullName(firstName?, lastName?)`
|
|
341
|
+
|
|
342
|
+
Combine first and last name with space.
|
|
343
|
+
|
|
344
|
+
**Signature:**
|
|
345
|
+
```typescript
|
|
346
|
+
fullName(firstName?: string, lastName?: string): string
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Examples:**
|
|
350
|
+
```typescript
|
|
351
|
+
helpers.fullName('John', 'Doe'); // => 'John Doe'
|
|
352
|
+
helpers.fullName('John', ''); // => 'John'
|
|
353
|
+
helpers.fullName('', 'Doe'); // => 'Doe'
|
|
354
|
+
helpers.fullName('', ''); // => ''
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
### `truncate(str, maxLength)`
|
|
360
|
+
|
|
361
|
+
Truncate string to max length, preserving words when possible.
|
|
362
|
+
|
|
363
|
+
**Signature:**
|
|
364
|
+
```typescript
|
|
365
|
+
truncate(str: string, maxLength: number): string
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Examples:**
|
|
369
|
+
```typescript
|
|
370
|
+
helpers.truncate('This is a very long text', 10);
|
|
371
|
+
// => 'This is...'
|
|
372
|
+
|
|
373
|
+
helpers.truncate('Short', 10);
|
|
374
|
+
// => 'Short'
|
|
375
|
+
|
|
376
|
+
helpers.truncate('OneVeryLongWord', 8);
|
|
377
|
+
// => 'OneVery...'
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### `normalizeWhitespace(str)`
|
|
383
|
+
|
|
384
|
+
Collapse multiple spaces into single space, trim edges.
|
|
385
|
+
|
|
386
|
+
**Signature:**
|
|
387
|
+
```typescript
|
|
388
|
+
normalizeWhitespace(str: string): string
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Examples:**
|
|
392
|
+
```typescript
|
|
393
|
+
helpers.normalizeWhitespace('Hello World \n !');
|
|
394
|
+
// => 'Hello World !'
|
|
395
|
+
|
|
396
|
+
helpers.normalizeWhitespace(' Too many spaces ');
|
|
397
|
+
// => 'Too many spaces'
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
### `toCamelCase(str)`
|
|
403
|
+
|
|
404
|
+
Convert string to camelCase.
|
|
405
|
+
|
|
406
|
+
**Signature:**
|
|
407
|
+
```typescript
|
|
408
|
+
toCamelCase(str: string): string
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Examples:**
|
|
412
|
+
```typescript
|
|
413
|
+
helpers.toCamelCase('order-number'); // => 'orderNumber'
|
|
414
|
+
helpers.toCamelCase('order_number'); // => 'orderNumber'
|
|
415
|
+
helpers.toCamelCase('Order Number'); // => 'orderNumber'
|
|
416
|
+
helpers.toCamelCase('ORDER-NUMBER'); // => 'orderNumber'
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### `toSnakeCase(str)`
|
|
422
|
+
|
|
423
|
+
Convert string to snake_case.
|
|
424
|
+
|
|
425
|
+
**Signature:**
|
|
426
|
+
```typescript
|
|
427
|
+
toSnakeCase(str: string): string
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Examples:**
|
|
431
|
+
```typescript
|
|
432
|
+
helpers.toSnakeCase('orderNumber'); // => 'order_number'
|
|
433
|
+
helpers.toSnakeCase('OrderNumber'); // => '_order_number'
|
|
434
|
+
helpers.toSnakeCase('order-number'); // => 'order_number'
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
### `template(str, vars)`
|
|
440
|
+
|
|
441
|
+
String interpolation with `{{variable}}` syntax.
|
|
442
|
+
|
|
443
|
+
**Signature:**
|
|
444
|
+
```typescript
|
|
445
|
+
template(str: string, vars: Record<string, any>): string
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Examples:**
|
|
449
|
+
```typescript
|
|
450
|
+
helpers.template('Hello {{name}}!', { name: 'World' });
|
|
451
|
+
// => 'Hello World!'
|
|
452
|
+
|
|
453
|
+
helpers.template('Order {{id}} for {{customer}}', {
|
|
454
|
+
id: '123',
|
|
455
|
+
customer: 'John Doe'
|
|
456
|
+
});
|
|
457
|
+
// => 'Order 123 for John Doe'
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
### `slugify(str)`
|
|
463
|
+
|
|
464
|
+
Convert string to URL-safe slug.
|
|
465
|
+
|
|
466
|
+
**Signature:**
|
|
467
|
+
```typescript
|
|
468
|
+
slugify(str: string): string
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
**Examples:**
|
|
472
|
+
```typescript
|
|
473
|
+
helpers.slugify('Hello World!'); // => 'hello-world'
|
|
474
|
+
helpers.slugify('Product Name (2024)'); // => 'product-name-2024'
|
|
475
|
+
helpers.slugify('Café & Restaurant'); // => 'cafe-restaurant'
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
### `uuid()`
|
|
481
|
+
|
|
482
|
+
Generate UUID v4.
|
|
483
|
+
|
|
484
|
+
**Signature:**
|
|
485
|
+
```typescript
|
|
486
|
+
uuid(): string
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Examples:**
|
|
490
|
+
```typescript
|
|
491
|
+
helpers.uuid();
|
|
492
|
+
// => '550e8400-e29b-41d4-a716-446655440000'
|
|
493
|
+
|
|
494
|
+
// Use for unique IDs
|
|
495
|
+
const uniqueRef = `ORDER-${helpers.uuid()}`;
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Object Utilities
|
|
501
|
+
|
|
502
|
+
### `isEmpty(value)`
|
|
503
|
+
|
|
504
|
+
Check if value is empty (null, undefined, '', [], {}).
|
|
505
|
+
|
|
506
|
+
**Signature:**
|
|
507
|
+
```typescript
|
|
508
|
+
isEmpty(value: any): boolean
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Examples:**
|
|
512
|
+
```typescript
|
|
513
|
+
helpers.isEmpty(null); // => true
|
|
514
|
+
helpers.isEmpty(undefined); // => true
|
|
515
|
+
helpers.isEmpty(''); // => true
|
|
516
|
+
helpers.isEmpty([]); // => true
|
|
517
|
+
helpers.isEmpty({}); // => true
|
|
518
|
+
helpers.isEmpty('text'); // => false
|
|
519
|
+
helpers.isEmpty([1, 2]); // => false
|
|
520
|
+
helpers.isEmpty({ key: 'value' }); // => false
|
|
521
|
+
helpers.isEmpty(0); // => false (0 is not empty)
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
### `pick(obj, keys)`
|
|
527
|
+
|
|
528
|
+
Pick specific fields from object.
|
|
529
|
+
|
|
530
|
+
**Signature:**
|
|
531
|
+
```typescript
|
|
532
|
+
pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
**Examples:**
|
|
536
|
+
```typescript
|
|
537
|
+
const order = { id: '1', ref: 'ORD-1', status: 'OPEN', total: 100 };
|
|
538
|
+
helpers.pick(order, ['id', 'ref']);
|
|
539
|
+
// => { id: '1', ref: 'ORD-1' }
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
### `omit(obj, keys)`
|
|
545
|
+
|
|
546
|
+
Omit specific fields from object.
|
|
547
|
+
|
|
548
|
+
**Signature:**
|
|
549
|
+
```typescript
|
|
550
|
+
omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Examples:**
|
|
554
|
+
```typescript
|
|
555
|
+
const order = { id: '1', ref: 'ORD-1', status: 'OPEN', total: 100 };
|
|
556
|
+
helpers.omit(order, ['status', 'total']);
|
|
557
|
+
// => { id: '1', ref: 'ORD-1' }
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
### `deepClone(obj)`
|
|
563
|
+
|
|
564
|
+
Deep clone object using JSON serialization.
|
|
565
|
+
|
|
566
|
+
**Signature:**
|
|
567
|
+
```typescript
|
|
568
|
+
deepClone<T>(obj: T): T
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Examples:**
|
|
572
|
+
```typescript
|
|
573
|
+
const original = { a: { b: { c: 1 } } };
|
|
574
|
+
const cloned = helpers.deepClone(original);
|
|
575
|
+
cloned.a.b.c = 2;
|
|
576
|
+
console.log(original.a.b.c); // => 1 (unchanged)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Warning:** Only works with JSON-serializable objects (no functions, undefined, etc.)
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
### `deepMerge(target, source)`
|
|
584
|
+
|
|
585
|
+
Merge objects deeply.
|
|
586
|
+
|
|
587
|
+
**Signature:**
|
|
588
|
+
```typescript
|
|
589
|
+
deepMerge<T extends object>(target: T, source: Partial<T>): T
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Examples:**
|
|
593
|
+
```typescript
|
|
594
|
+
const target = { a: { b: 1, c: 2 } };
|
|
595
|
+
const source = { a: { c: 3, d: 4 }, e: 5 };
|
|
596
|
+
helpers.deepMerge(target, source);
|
|
597
|
+
// => { a: { b: 1, c: 3, d: 4 }, e: 5 }
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
### `set(obj, path, value)`
|
|
603
|
+
|
|
604
|
+
Set nested property value with dot notation. Creates intermediate objects as needed.
|
|
605
|
+
|
|
606
|
+
**Signature:**
|
|
607
|
+
```typescript
|
|
608
|
+
set(obj: any, path: string, value: any): void
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**Examples:**
|
|
612
|
+
```typescript
|
|
613
|
+
const data = {};
|
|
614
|
+
helpers.set(data, 'order.customer.email', 'test@example.com');
|
|
615
|
+
// => { order: { customer: { email: 'test@example.com' } } }
|
|
616
|
+
|
|
617
|
+
helpers.set(data, 'order.total', 100);
|
|
618
|
+
// => { order: { customer: {...}, total: 100 } }
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
### `merge(...objects)`
|
|
624
|
+
|
|
625
|
+
Shallow merge multiple objects.
|
|
626
|
+
|
|
627
|
+
**Signature:**
|
|
628
|
+
```typescript
|
|
629
|
+
merge<T extends object>(...objects: Partial<T>[]): T
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**Examples:**
|
|
633
|
+
```typescript
|
|
634
|
+
const defaults = { currency: 'USD', tax: 0 };
|
|
635
|
+
const order = { total: 100, tax: 10 };
|
|
636
|
+
helpers.merge(defaults, order);
|
|
637
|
+
// => { currency: 'USD', tax: 10, total: 100 }
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
## Array Transformation
|
|
643
|
+
|
|
644
|
+
### `groupBy(array, key)`
|
|
645
|
+
|
|
646
|
+
Group array items by key or function.
|
|
647
|
+
|
|
648
|
+
**Signature:**
|
|
649
|
+
```typescript
|
|
650
|
+
groupBy<T>(array: T[], key: keyof T | ((item: T) => string)): Record<string, T[]>
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
**Examples:**
|
|
654
|
+
```typescript
|
|
655
|
+
const items = [
|
|
656
|
+
{ sku: 'A', category: 'electronics' },
|
|
657
|
+
{ sku: 'B', category: 'electronics' },
|
|
658
|
+
{ sku: 'C', category: 'clothing' }
|
|
659
|
+
];
|
|
660
|
+
|
|
661
|
+
helpers.groupBy(items, 'category');
|
|
662
|
+
// => {
|
|
663
|
+
// electronics: [{ sku: 'A', ... }, { sku: 'B', ... }],
|
|
664
|
+
// clothing: [{ sku: 'C', ... }]
|
|
665
|
+
// }
|
|
666
|
+
|
|
667
|
+
helpers.groupBy(items, item => item.sku[0]);
|
|
668
|
+
// => { A: [...], B: [...], C: [...] }
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
### `keyBy(array, key)`
|
|
674
|
+
|
|
675
|
+
Convert array to object keyed by property.
|
|
676
|
+
|
|
677
|
+
**Signature:**
|
|
678
|
+
```typescript
|
|
679
|
+
keyBy<T>(array: T[], key: keyof T | ((item: T) => string)): Record<string, T>
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**Examples:**
|
|
683
|
+
```typescript
|
|
684
|
+
const items = [
|
|
685
|
+
{ sku: 'SKU-1', name: 'Product 1' },
|
|
686
|
+
{ sku: 'SKU-2', name: 'Product 2' }
|
|
687
|
+
];
|
|
688
|
+
|
|
689
|
+
helpers.keyBy(items, 'sku');
|
|
690
|
+
// => {
|
|
691
|
+
// 'SKU-1': { sku: 'SKU-1', name: 'Product 1' },
|
|
692
|
+
// 'SKU-2': { sku: 'SKU-2', name: 'Product 2' }
|
|
693
|
+
// }
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
### `chunk(array, size)`
|
|
699
|
+
|
|
700
|
+
Split array into chunks of specified size.
|
|
701
|
+
|
|
702
|
+
**Signature:**
|
|
703
|
+
```typescript
|
|
704
|
+
chunk<T>(array: T[], size: number): T[][]
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Examples:**
|
|
708
|
+
```typescript
|
|
709
|
+
helpers.chunk([1, 2, 3, 4, 5], 2);
|
|
710
|
+
// => [[1, 2], [3, 4], [5]]
|
|
711
|
+
|
|
712
|
+
helpers.chunk(['a', 'b', 'c', 'd', 'e', 'f'], 3);
|
|
713
|
+
// => [['a', 'b', 'c'], ['d', 'e', 'f']]
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
### `flatten(array, depth)`
|
|
719
|
+
|
|
720
|
+
Flatten nested arrays to specified depth.
|
|
721
|
+
|
|
722
|
+
**Signature:**
|
|
723
|
+
```typescript
|
|
724
|
+
flatten<T>(array: any[], depth?: number): T[]
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
**Examples:**
|
|
728
|
+
```typescript
|
|
729
|
+
helpers.flatten([[1, 2], [3, 4]], 1);
|
|
730
|
+
// => [1, 2, 3, 4]
|
|
731
|
+
|
|
732
|
+
helpers.flatten([[[1, 2]], [[3, 4]]], 2);
|
|
733
|
+
// => [1, 2, 3, 4]
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
### `unique(array, key?)`
|
|
739
|
+
|
|
740
|
+
Get unique values from array, optionally by key for objects.
|
|
741
|
+
|
|
742
|
+
**Signature:**
|
|
743
|
+
```typescript
|
|
744
|
+
unique<T>(array: T[], key?: keyof T | ((item: T) => any)): T[]
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**Examples:**
|
|
748
|
+
```typescript
|
|
749
|
+
helpers.unique([1, 2, 2, 3, 3, 3]);
|
|
750
|
+
// => [1, 2, 3]
|
|
751
|
+
|
|
752
|
+
const items = [
|
|
753
|
+
{ sku: 'A', qty: 1 },
|
|
754
|
+
{ sku: 'B', qty: 2 },
|
|
755
|
+
{ sku: 'A', qty: 3 }
|
|
756
|
+
];
|
|
757
|
+
helpers.unique(items, 'sku');
|
|
758
|
+
// => [{ sku: 'A', qty: 1 }, { sku: 'B', qty: 2 }]
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
### `sortBy(array, key, order)`
|
|
764
|
+
|
|
765
|
+
Sort array by key or function.
|
|
766
|
+
|
|
767
|
+
**Signature:**
|
|
768
|
+
```typescript
|
|
769
|
+
sortBy<T>(array: T[], key: keyof T | ((item: T) => any), order?: 'asc' | 'desc'): T[]
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
**Examples:**
|
|
773
|
+
```typescript
|
|
774
|
+
const items = [
|
|
775
|
+
{ sku: 'C', price: 30 },
|
|
776
|
+
{ sku: 'A', price: 10 },
|
|
777
|
+
{ sku: 'B', price: 20 }
|
|
778
|
+
];
|
|
779
|
+
|
|
780
|
+
helpers.sortBy(items, 'price', 'asc');
|
|
781
|
+
// => [{ sku: 'A', price: 10 }, { sku: 'B', price: 20 }, { sku: 'C', price: 30 }]
|
|
782
|
+
|
|
783
|
+
helpers.sortBy(items, 'sku', 'desc');
|
|
784
|
+
// => [{ sku: 'C', ... }, { sku: 'B', ... }, { sku: 'A', ... }]
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
### `compact(array)`
|
|
790
|
+
|
|
791
|
+
Remove falsy values (null, undefined, false, 0, '') from array.
|
|
792
|
+
|
|
793
|
+
**Signature:**
|
|
794
|
+
```typescript
|
|
795
|
+
compact<T>(array: (T | null | undefined | false | 0 | '')[]): T[]
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
**Examples:**
|
|
799
|
+
```typescript
|
|
800
|
+
helpers.compact([1, null, 2, undefined, 3, false, 0, '']);
|
|
801
|
+
// => [1, 2, 3]
|
|
802
|
+
|
|
803
|
+
helpers.compact(['a', '', 'b', null, 'c']);
|
|
804
|
+
// => ['a', 'b', 'c']
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
---
|
|
808
|
+
|
|
809
|
+
### `coalesce(...values)`
|
|
810
|
+
|
|
811
|
+
Return first non-null/undefined value (like SQL COALESCE).
|
|
812
|
+
|
|
813
|
+
**Signature:**
|
|
814
|
+
```typescript
|
|
815
|
+
coalesce<T>(...values: (T | null | undefined)[]): T | undefined
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
**Examples:**
|
|
819
|
+
```typescript
|
|
820
|
+
helpers.coalesce(null, undefined, 'first', 'second'); // => 'first'
|
|
821
|
+
helpers.coalesce(null, 0, 1); // => 0
|
|
822
|
+
helpers.coalesce(null, '', 'value'); // => ''
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
---
|
|
826
|
+
|
|
827
|
+
## Array Aggregation
|
|
828
|
+
|
|
829
|
+
### `sum(array, key?)`
|
|
830
|
+
|
|
831
|
+
Sum numeric values in array, optionally by key for objects.
|
|
832
|
+
|
|
833
|
+
**Signature:**
|
|
834
|
+
```typescript
|
|
835
|
+
sum<T>(array: T[], key?: keyof T | ((item: T) => number)): number
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
**Examples:**
|
|
839
|
+
```typescript
|
|
840
|
+
helpers.sum([1, 2, 3, 4, 5]); // => 15
|
|
841
|
+
|
|
842
|
+
const items = [
|
|
843
|
+
{ price: 10 },
|
|
844
|
+
{ price: 20 },
|
|
845
|
+
{ price: 30 }
|
|
846
|
+
];
|
|
847
|
+
helpers.sum(items, 'price'); // => 60
|
|
848
|
+
|
|
849
|
+
helpers.sum(items, item => item.price * 1.1); // => 66 (with markup)
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
---
|
|
853
|
+
|
|
854
|
+
### `avg(array, key?)`
|
|
855
|
+
|
|
856
|
+
Calculate average of numeric values.
|
|
857
|
+
|
|
858
|
+
**Signature:**
|
|
859
|
+
```typescript
|
|
860
|
+
avg<T>(array: T[], key?: keyof T | ((item: T) => number)): number
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
**Examples:**
|
|
864
|
+
```typescript
|
|
865
|
+
helpers.avg([10, 20, 30]); // => 20
|
|
866
|
+
|
|
867
|
+
const items = [{ score: 80 }, { score: 90 }, { score: 70 }];
|
|
868
|
+
helpers.avg(items, 'score'); // => 80
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
873
|
+
### `min(array, key?)`
|
|
874
|
+
|
|
875
|
+
Find minimum value in array.
|
|
876
|
+
|
|
877
|
+
**Signature:**
|
|
878
|
+
```typescript
|
|
879
|
+
min<T>(array: T[], key?: keyof T | ((item: T) => number)): number | undefined
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
**Examples:**
|
|
883
|
+
```typescript
|
|
884
|
+
helpers.min([10, 5, 20, 3]); // => 3
|
|
885
|
+
|
|
886
|
+
const items = [{ price: 10 }, { price: 5 }, { price: 20 }];
|
|
887
|
+
helpers.min(items, 'price'); // => 5
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
---
|
|
891
|
+
|
|
892
|
+
### `max(array, key?)`
|
|
893
|
+
|
|
894
|
+
Find maximum value in array.
|
|
895
|
+
|
|
896
|
+
**Signature:**
|
|
897
|
+
```typescript
|
|
898
|
+
max<T>(array: T[], key?: keyof T | ((item: T) => number)): number | undefined
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
**Examples:**
|
|
902
|
+
```typescript
|
|
903
|
+
helpers.max([10, 5, 20, 3]); // => 20
|
|
904
|
+
|
|
905
|
+
const items = [{ quantity: 10 }, { quantity: 5 }, { quantity: 20 }];
|
|
906
|
+
helpers.max(items, 'quantity'); // => 20
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
---
|
|
910
|
+
|
|
911
|
+
### `clamp(num, min, max)`
|
|
912
|
+
|
|
913
|
+
Clamp number to specified range.
|
|
914
|
+
|
|
915
|
+
**Signature:**
|
|
916
|
+
```typescript
|
|
917
|
+
clamp(num: number, min: number, max: number): number
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
**Examples:**
|
|
921
|
+
```typescript
|
|
922
|
+
helpers.clamp(5, 0, 10); // => 5
|
|
923
|
+
helpers.clamp(-5, 0, 10); // => 0
|
|
924
|
+
helpers.clamp(15, 0, 10); // => 10
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
---
|
|
928
|
+
|
|
929
|
+
## Date/Time
|
|
930
|
+
|
|
931
|
+
### `addDays(date, days)`
|
|
932
|
+
|
|
933
|
+
Add days to date.
|
|
934
|
+
|
|
935
|
+
**Signature:**
|
|
936
|
+
```typescript
|
|
937
|
+
addDays(date: Date | string, days: number): Date
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
**Examples:**
|
|
941
|
+
```typescript
|
|
942
|
+
helpers.addDays(new Date('2025-01-14'), 7);
|
|
943
|
+
// => Date('2025-01-21')
|
|
944
|
+
|
|
945
|
+
helpers.addDays('2025-01-14', 30);
|
|
946
|
+
// => Date('2025-02-13')
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
---
|
|
950
|
+
|
|
951
|
+
### `subtractDays(date, days)`
|
|
952
|
+
|
|
953
|
+
Subtract days from date.
|
|
954
|
+
|
|
955
|
+
**Signature:**
|
|
956
|
+
```typescript
|
|
957
|
+
subtractDays(date: Date | string, days: number): Date
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
**Examples:**
|
|
961
|
+
```typescript
|
|
962
|
+
helpers.subtractDays(new Date('2025-01-14'), 7);
|
|
963
|
+
// => Date('2025-01-07')
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
---
|
|
967
|
+
|
|
968
|
+
### `dateDiff(date1, date2)`
|
|
969
|
+
|
|
970
|
+
Get difference between dates in days.
|
|
971
|
+
|
|
972
|
+
**Signature:**
|
|
973
|
+
```typescript
|
|
974
|
+
dateDiff(date1: Date | string, date2: Date | string): number
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
**Examples:**
|
|
978
|
+
```typescript
|
|
979
|
+
helpers.dateDiff('2025-01-14', '2025-01-21'); // => 7
|
|
980
|
+
helpers.dateDiff('2025-01-21', '2025-01-14'); // => -7
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
---
|
|
984
|
+
|
|
985
|
+
### `parseDate(dateStr, format?)`
|
|
986
|
+
|
|
987
|
+
Parse date with multiple format support.
|
|
988
|
+
|
|
989
|
+
**Signature:**
|
|
990
|
+
```typescript
|
|
991
|
+
parseDate(dateStr: string, format?: string): Date | null
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
**Supported Formats:**
|
|
995
|
+
- ISO: `'2025-01-14'`
|
|
996
|
+
- US: `'01/14/2025'`
|
|
997
|
+
- EU: `'14-01-2025'`
|
|
998
|
+
- Compact: `'20250114'`
|
|
999
|
+
|
|
1000
|
+
**Examples:**
|
|
1001
|
+
```typescript
|
|
1002
|
+
helpers.parseDate('2025-01-14'); // ISO
|
|
1003
|
+
helpers.parseDate('01/14/2025'); // MM/DD/YYYY
|
|
1004
|
+
helpers.parseDate('14-01-2025'); // DD-MM-YYYY
|
|
1005
|
+
helpers.parseDate('20250114'); // YYYYMMDD
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
**Returns:** `Date` object or `null` if parsing fails
|
|
1009
|
+
|
|
1010
|
+
---
|
|
1011
|
+
|
|
1012
|
+
## Function Utilities
|
|
1013
|
+
|
|
1014
|
+
### `debounce(fn, delayMs)`
|
|
1015
|
+
|
|
1016
|
+
Delay function execution until after delay period.
|
|
1017
|
+
|
|
1018
|
+
**Signature:**
|
|
1019
|
+
```typescript
|
|
1020
|
+
debounce<T extends (...args: any[]) => any>(fn: T, delayMs: number): T
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
**Examples:**
|
|
1024
|
+
```typescript
|
|
1025
|
+
const logMessage = (msg: string) => console.log(msg);
|
|
1026
|
+
const debouncedLog = helpers.debounce(logMessage, 1000);
|
|
1027
|
+
|
|
1028
|
+
debouncedLog('Message 1'); // Cancelled
|
|
1029
|
+
debouncedLog('Message 2'); // Cancelled
|
|
1030
|
+
debouncedLog('Message 3'); // Executed after 1000ms
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
---
|
|
1034
|
+
|
|
1035
|
+
### `throttle(fn, limitMs)`
|
|
1036
|
+
|
|
1037
|
+
Limit function execution rate.
|
|
1038
|
+
|
|
1039
|
+
**Signature:**
|
|
1040
|
+
```typescript
|
|
1041
|
+
throttle<T extends (...args: any[]) => any>(fn: T, limitMs: number): T
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
**Examples:**
|
|
1045
|
+
```typescript
|
|
1046
|
+
const logMessage = (msg: string) => console.log(msg);
|
|
1047
|
+
const throttledLog = helpers.throttle(logMessage, 1000);
|
|
1048
|
+
|
|
1049
|
+
throttledLog('Message 1'); // Executed immediately
|
|
1050
|
+
throttledLog('Message 2'); // Ignored (within 1000ms)
|
|
1051
|
+
// Wait 1000ms
|
|
1052
|
+
throttledLog('Message 3'); // Executed
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
---
|
|
1056
|
+
|
|
1057
|
+
## Type Guards
|
|
1058
|
+
|
|
1059
|
+
### `isString(value)`, `isNumber(value)`, `isArray(value)`, `isObject(value)`, `isDate(value)`
|
|
1060
|
+
|
|
1061
|
+
Type checking utilities.
|
|
1062
|
+
|
|
1063
|
+
**Signatures:**
|
|
1064
|
+
```typescript
|
|
1065
|
+
isString(value: any): boolean
|
|
1066
|
+
isNumber(value: any): boolean
|
|
1067
|
+
isArray(value: any): boolean
|
|
1068
|
+
isObject(value: any): boolean
|
|
1069
|
+
isDate(value: any): boolean
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
**Examples:**
|
|
1073
|
+
```typescript
|
|
1074
|
+
helpers.isString('hello'); // => true
|
|
1075
|
+
helpers.isNumber(123); // => true
|
|
1076
|
+
helpers.isNumber(NaN); // => false
|
|
1077
|
+
helpers.isArray([1, 2, 3]); // => true
|
|
1078
|
+
helpers.isObject({ key: 'value' }); // => true
|
|
1079
|
+
helpers.isObject([1, 2, 3]); // => false
|
|
1080
|
+
helpers.isDate(new Date()); // => true
|
|
1081
|
+
helpers.isDate('2025-01-14'); // => false
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
---
|
|
1085
|
+
|
|
1086
|
+
## Utility Functions
|
|
1087
|
+
|
|
1088
|
+
### `defaultTo(value, defaultValue)`
|
|
1089
|
+
|
|
1090
|
+
Return default if value is null/undefined.
|
|
1091
|
+
|
|
1092
|
+
**Signature:**
|
|
1093
|
+
```typescript
|
|
1094
|
+
defaultTo<T>(value: T | null | undefined, defaultValue: T): T
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
**Examples:**
|
|
1098
|
+
```typescript
|
|
1099
|
+
helpers.defaultTo(null, 'default'); // => 'default'
|
|
1100
|
+
helpers.defaultTo(undefined, 'default'); // => 'default'
|
|
1101
|
+
helpers.defaultTo('value', 'default'); // => 'value'
|
|
1102
|
+
helpers.defaultTo(0, 10); // => 0 (0 is not null/undefined)
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
---
|
|
1106
|
+
|
|
1107
|
+
### `range(start, end?, step?)`
|
|
1108
|
+
|
|
1109
|
+
Generate numeric ranges.
|
|
1110
|
+
|
|
1111
|
+
**Signature:**
|
|
1112
|
+
```typescript
|
|
1113
|
+
range(start: number, end?: number, step?: number): number[]
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
**Examples:**
|
|
1117
|
+
```typescript
|
|
1118
|
+
helpers.range(5); // => [0, 1, 2, 3, 4]
|
|
1119
|
+
helpers.range(1, 6); // => [1, 2, 3, 4, 5]
|
|
1120
|
+
helpers.range(0, 10, 2); // => [0, 2, 4, 6, 8]
|
|
1121
|
+
helpers.range(10, 0, -2); // => [10, 8, 6, 4, 2]
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
---
|
|
1125
|
+
|
|
1126
|
+
### `hashString(str)`
|
|
1127
|
+
|
|
1128
|
+
Generate deterministic hash from string (not cryptographically secure).
|
|
1129
|
+
|
|
1130
|
+
**Signature:**
|
|
1131
|
+
```typescript
|
|
1132
|
+
hashString(str: string): string
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
**Examples:**
|
|
1136
|
+
```typescript
|
|
1137
|
+
helpers.hashString('hello'); // => '4x93m' (deterministic)
|
|
1138
|
+
helpers.hashString('hello'); // => '4x93m' (same input = same output)
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
**Use Case:** Stable keys, content-based IDs, deduplication keys
|
|
1142
|
+
|
|
1143
|
+
---
|
|
1144
|
+
|
|
1145
|
+
## Performance
|
|
1146
|
+
|
|
1147
|
+
### `memoize(fn)`
|
|
1148
|
+
|
|
1149
|
+
Memoize expensive function.
|
|
1150
|
+
|
|
1151
|
+
**Signature:**
|
|
1152
|
+
```typescript
|
|
1153
|
+
memoize<T extends (...args: any[]) => any>(fn: T): T
|
|
1154
|
+
```
|
|
1155
|
+
|
|
1156
|
+
**Examples:**
|
|
1157
|
+
```typescript
|
|
1158
|
+
const expensiveCalculation = (a, b) => {
|
|
1159
|
+
console.log('Calculating...');
|
|
1160
|
+
return a + b;
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
const memoized = helpers.memoize(expensiveCalculation);
|
|
1164
|
+
|
|
1165
|
+
memoized(1, 2); // => Logs "Calculating...", returns 3
|
|
1166
|
+
memoized(1, 2); // => Returns 3 (from cache, no log)
|
|
1167
|
+
memoized(2, 3); // => Logs "Calculating...", returns 5
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
---
|
|
1171
|
+
|
|
1172
|
+
### `retry(fn, maxRetries?, delayMs?)`
|
|
1173
|
+
|
|
1174
|
+
Retry function with exponential backoff.
|
|
1175
|
+
|
|
1176
|
+
**Signature:**
|
|
1177
|
+
```typescript
|
|
1178
|
+
retry<T>(fn: () => Promise<T>, maxRetries?: number, delayMs?: number): Promise<T>
|
|
1179
|
+
```
|
|
1180
|
+
|
|
1181
|
+
**Parameters:**
|
|
1182
|
+
- `fn` - Async function to retry
|
|
1183
|
+
- `maxRetries` - Max attempts (default: 3)
|
|
1184
|
+
- `delayMs` - Initial delay (default: 100ms)
|
|
1185
|
+
|
|
1186
|
+
**Examples:**
|
|
1187
|
+
```typescript
|
|
1188
|
+
const result = await helpers.retry(
|
|
1189
|
+
async () => {
|
|
1190
|
+
const response = await fetch('https://api.example.com/data');
|
|
1191
|
+
return response.json();
|
|
1192
|
+
},
|
|
1193
|
+
3, // Max 3 retries
|
|
1194
|
+
100 // Start with 100ms delay
|
|
1195
|
+
);
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
---
|
|
1199
|
+
|
|
1200
|
+
### `batchProcess(items, processor, batchSize?)`
|
|
1201
|
+
|
|
1202
|
+
Process array in batches (async, default: 50 items/batch).
|
|
1203
|
+
|
|
1204
|
+
**Signature:**
|
|
1205
|
+
```typescript
|
|
1206
|
+
batchProcess<T, R>(
|
|
1207
|
+
items: T[],
|
|
1208
|
+
processor: (item: T, index: number) => Promise<R>,
|
|
1209
|
+
batchSize?: number
|
|
1210
|
+
): Promise<R[]>
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
**Examples:**
|
|
1214
|
+
```typescript
|
|
1215
|
+
const items = [1, 2, 3, 4, 5];
|
|
1216
|
+
const results = await helpers.batchProcess(
|
|
1217
|
+
items,
|
|
1218
|
+
async (item, index) => {
|
|
1219
|
+
// Call external API
|
|
1220
|
+
return await fetchData(item);
|
|
1221
|
+
},
|
|
1222
|
+
2 // Process 2 items at a time
|
|
1223
|
+
);
|
|
1224
|
+
```
|
|
1225
|
+
|
|
1226
|
+
---
|
|
1227
|
+
|
|
1228
|
+
## XML/JSON Specific
|
|
1229
|
+
|
|
1230
|
+
### `extractCustomAttribute(customAttributes, attributeId, defaultValue?)`
|
|
1231
|
+
|
|
1232
|
+
Extract custom attribute by ID from XML/JSON custom attributes.
|
|
1233
|
+
|
|
1234
|
+
**Signature:**
|
|
1235
|
+
```typescript
|
|
1236
|
+
extractCustomAttribute(customAttributes: any, attributeId: string, defaultValue?: any): any
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
**Handles Multiple Formats:**
|
|
1240
|
+
- Array of attributes: `[{ '@attribute-id': 'id', '#text': 'value' }, ...]`
|
|
1241
|
+
- Single attribute object: `{ '@attribute-id': 'id', '#text': 'value' }`
|
|
1242
|
+
- Object with keys: `{ 'key1': 'value1', 'key2': 'value2' }`
|
|
1243
|
+
|
|
1244
|
+
**Examples:**
|
|
1245
|
+
```typescript
|
|
1246
|
+
// Array format (SFCC XML)
|
|
1247
|
+
const attrs = [
|
|
1248
|
+
{ '@attribute-id': 'retailerId', '#text': '123' },
|
|
1249
|
+
{ '@attribute-id': 'orderType', '#text': 'HD' }
|
|
1250
|
+
];
|
|
1251
|
+
helpers.extractCustomAttribute(attrs, 'retailerId');
|
|
1252
|
+
// => '123'
|
|
1253
|
+
|
|
1254
|
+
// Object format
|
|
1255
|
+
const attrs2 = { 'retailerId': '123', 'orderType': 'HD' };
|
|
1256
|
+
helpers.extractCustomAttribute(attrs2, 'orderType');
|
|
1257
|
+
// => 'HD'
|
|
1258
|
+
|
|
1259
|
+
// With default
|
|
1260
|
+
helpers.extractCustomAttribute(attrs, 'missing', 'DEFAULT');
|
|
1261
|
+
// => 'DEFAULT'
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
---
|
|
1265
|
+
|
|
1266
|
+
### `getXmlAttribute(obj, attrName, defaultValue?)`
|
|
1267
|
+
|
|
1268
|
+
Extract XML attribute from object with multi-format support. Automatically handles different XML parser formats.
|
|
1269
|
+
|
|
1270
|
+
**Signature:**
|
|
1271
|
+
```typescript
|
|
1272
|
+
getXmlAttribute(obj: any, attrName: string, defaultValue?: any): any
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
**Supported XML Attribute Formats:**
|
|
1276
|
+
The function tries multiple formats in priority order:
|
|
1277
|
+
1. `$attr-name` - Versori/xml2js with $ prefix as direct key
|
|
1278
|
+
2. `$['attr-name']` - Nested in $ object (Versori platform format)
|
|
1279
|
+
3. `@attr-name` - SDK XMLParserService default format
|
|
1280
|
+
4. `@['attr-name']` - Nested in @ object (alternative format)
|
|
1281
|
+
5. `attr-name` - Direct attribute (fallback)
|
|
1282
|
+
6. `_attributes['attr-name']` - xml2js _attributes format
|
|
1283
|
+
|
|
1284
|
+
**Why This Exists:**
|
|
1285
|
+
Different XML parsers store attributes in different formats. This helper eliminates the need to manually check multiple formats in resolvers.
|
|
1286
|
+
|
|
1287
|
+
**Examples:**
|
|
1288
|
+
```typescript
|
|
1289
|
+
// Versori format (nested $ object)
|
|
1290
|
+
const versoriData = { $: { 'shipment-id': '02408380' } };
|
|
1291
|
+
helpers.getXmlAttribute(versoriData, 'shipment-id');
|
|
1292
|
+
// => '02408380'
|
|
1293
|
+
|
|
1294
|
+
// SDK format (@ prefix)
|
|
1295
|
+
const sdkData = { '@shipment-id': '02408380' };
|
|
1296
|
+
helpers.getXmlAttribute(sdkData, 'shipment-id');
|
|
1297
|
+
// => '02408380'
|
|
1298
|
+
|
|
1299
|
+
// Direct format
|
|
1300
|
+
const directData = { 'shipment-id': '02408380' };
|
|
1301
|
+
helpers.getXmlAttribute(directData, 'shipment-id');
|
|
1302
|
+
// => '02408380'
|
|
1303
|
+
|
|
1304
|
+
// With default value
|
|
1305
|
+
helpers.getXmlAttribute({}, 'shipment-id', 'DEFAULT');
|
|
1306
|
+
// => 'DEFAULT'
|
|
1307
|
+
|
|
1308
|
+
// Real-world usage in resolver
|
|
1309
|
+
'custom.createFulfilmentChoiceRef': (value, data, config, helpers) => {
|
|
1310
|
+
const shipmentData = value || data || {};
|
|
1311
|
+
const shipmentId = helpers.getXmlAttribute(shipmentData, 'shipment-id');
|
|
1312
|
+
return `fc_${shipmentId}`;
|
|
1313
|
+
}
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
**Use Cases:**
|
|
1317
|
+
- Extracting XML attributes in custom resolvers
|
|
1318
|
+
- Handling multiple XML parser formats (Versori, SDK, xml2js)
|
|
1319
|
+
- Simplifying resolver code (no need to check multiple formats manually)
|
|
1320
|
+
|
|
1321
|
+
**Returns:** Attribute value or `defaultValue` (or `undefined`)
|
|
1322
|
+
|
|
1323
|
+
---
|
|
1324
|
+
|
|
1325
|
+
### `getXmlTextContent(obj, defaultValue?)`
|
|
1326
|
+
|
|
1327
|
+
Extract XML text content from object with multi-format support. Automatically handles different XML parser formats for text content.
|
|
1328
|
+
|
|
1329
|
+
**Signature:**
|
|
1330
|
+
```typescript
|
|
1331
|
+
getXmlTextContent(obj: any, defaultValue?: any): any
|
|
1332
|
+
```
|
|
1333
|
+
|
|
1334
|
+
**Supported XML Text Content Formats:**
|
|
1335
|
+
The function tries multiple formats in priority order:
|
|
1336
|
+
1. `_` - Versori platform format (text content)
|
|
1337
|
+
2. `#text` - SDK XMLParserService default format (text content)
|
|
1338
|
+
3. `value` - Fallback property
|
|
1339
|
+
4. Direct value - If already a string/primitive
|
|
1340
|
+
|
|
1341
|
+
**Why This Exists:**
|
|
1342
|
+
Different XML parsers store text content in different properties. This helper eliminates the need to manually check multiple formats in resolvers.
|
|
1343
|
+
|
|
1344
|
+
**Examples:**
|
|
1345
|
+
```typescript
|
|
1346
|
+
// Versori format (text in _ property)
|
|
1347
|
+
const versoriData = { $: { unit: '1' }, _: '1.0' };
|
|
1348
|
+
helpers.getXmlTextContent(versoriData);
|
|
1349
|
+
// => '1.0'
|
|
1350
|
+
|
|
1351
|
+
// SDK format (text in #text property)
|
|
1352
|
+
const sdkData = { '@unit': '1', '#text': '1.0' };
|
|
1353
|
+
helpers.getXmlTextContent(sdkData);
|
|
1354
|
+
// => '1.0'
|
|
1355
|
+
|
|
1356
|
+
// Direct string
|
|
1357
|
+
helpers.getXmlTextContent('1.0');
|
|
1358
|
+
// => '1.0'
|
|
1359
|
+
|
|
1360
|
+
// With default value
|
|
1361
|
+
helpers.getXmlTextContent({}, 'DEFAULT');
|
|
1362
|
+
// => 'DEFAULT'
|
|
1363
|
+
|
|
1364
|
+
// Real-world usage in resolver
|
|
1365
|
+
'custom.parseQuantity': (value, data, config, helpers) => {
|
|
1366
|
+
const qty = helpers.getXmlTextContent(value) ?? value;
|
|
1367
|
+
return parseFloat(String(qty));
|
|
1368
|
+
}
|
|
1369
|
+
```
|
|
1370
|
+
|
|
1371
|
+
**Use Cases:**
|
|
1372
|
+
- Extracting XML text content in custom resolvers
|
|
1373
|
+
- Handling multiple XML parser formats (Versori, SDK, xml2js)
|
|
1374
|
+
- Simplifying resolver code (no need to check multiple formats manually)
|
|
1375
|
+
|
|
1376
|
+
**Returns:** Text content value or `defaultValue` (or `undefined`)
|
|
1377
|
+
|
|
1378
|
+
---
|
|
1379
|
+
|
|
1380
|
+
### `normalizeEmpty(value, defaultValue?, trimWhitespace?)`
|
|
1381
|
+
|
|
1382
|
+
Normalize empty value handling null, undefined, empty string, and whitespace. Useful for CSV and JSON data where empty values may be represented differently.
|
|
1383
|
+
|
|
1384
|
+
**Signature:**
|
|
1385
|
+
```typescript
|
|
1386
|
+
normalizeEmpty(value: any, defaultValue?: any, trimWhitespace?: boolean): any
|
|
1387
|
+
```
|
|
1388
|
+
|
|
1389
|
+
**Normalization Rules:**
|
|
1390
|
+
- `null` → defaultValue
|
|
1391
|
+
- `undefined` → defaultValue
|
|
1392
|
+
- `''` (empty string) → defaultValue
|
|
1393
|
+
- `' '` (whitespace-only) → defaultValue (if trimWhitespace: true, default)
|
|
1394
|
+
- Other values → returned as-is
|
|
1395
|
+
|
|
1396
|
+
**Parameters:**
|
|
1397
|
+
- `value` - Value to normalize
|
|
1398
|
+
- `defaultValue` - Value to return if empty (default: undefined)
|
|
1399
|
+
- `trimWhitespace` - Whether to treat whitespace-only strings as empty (default: true)
|
|
1400
|
+
|
|
1401
|
+
**Examples:**
|
|
1402
|
+
```typescript
|
|
1403
|
+
// CSV empty values
|
|
1404
|
+
helpers.normalizeEmpty(null, 'N/A'); // => 'N/A'
|
|
1405
|
+
helpers.normalizeEmpty(undefined, 'N/A'); // => 'N/A'
|
|
1406
|
+
helpers.normalizeEmpty('', 'N/A'); // => 'N/A'
|
|
1407
|
+
helpers.normalizeEmpty(' ', 'N/A'); // => 'N/A' (trimWhitespace: true)
|
|
1408
|
+
helpers.normalizeEmpty('value', 'N/A'); // => 'value'
|
|
1409
|
+
|
|
1410
|
+
// JSON null handling
|
|
1411
|
+
helpers.normalizeEmpty(jsonData.field, 'DEFAULT'); // => 'DEFAULT' if null/undefined/empty
|
|
1412
|
+
|
|
1413
|
+
// Preserve whitespace when needed
|
|
1414
|
+
helpers.normalizeEmpty(' ', 'N/A', false); // => ' ' (preserves whitespace)
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
**Use Cases:**
|
|
1418
|
+
- Normalizing CSV empty values (null, '', whitespace)
|
|
1419
|
+
- Handling JSON null/undefined values
|
|
1420
|
+
- Consistent empty value handling across data sources
|
|
1421
|
+
- Simplifying resolver code (no need to check multiple empty formats)
|
|
1422
|
+
|
|
1423
|
+
**Returns:** Normalized value or `defaultValue` (or `undefined`)
|
|
1424
|
+
|
|
1425
|
+
---
|
|
1426
|
+
|
|
1427
|
+
## See Also
|
|
1428
|
+
|
|
1429
|
+
- [Main Resolver Guide](./mapping-resolvers-resolver-guide.md) - Getting started
|
|
1430
|
+
- [API Reference](./mapping-resolvers-resolver-api-reference.md) - ResolverBuilder methods
|
|
1431
|
+
- [Parameters Reference](./mapping-resolvers-resolver-parameters-reference.md) - value, data, config, helpers
|
|
1432
|
+
- [Troubleshooting](./mapping-resolvers-resolver-troubleshooting.md) - Common issues
|
|
1433
|
+
- [Cookbook](./mapping-resolvers-resolver-cookbook.md) - Advanced patterns
|
|
1434
|
+
|
|
1435
|
+
---
|
|
1436
|
+
|
|
1437
|
+
**License:** MIT
|