@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,789 +1,789 @@
|
|
|
1
|
-
# Module 3: JSON Parser
|
|
2
|
-
|
|
3
|
-
**Level:** Beginner
|
|
4
|
-
**Estimated Time:** 25 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module covers the JSON Parser (`JSONParserService`), essential for processing API responses, webhooks, and modern data formats. You'll learn how to parse JSON and JSONL, extract nested data, handle large files with streaming, and validate data structures.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Parse JSON and JSONL (JSON Lines) formats
|
|
14
|
-
- ✅ Extract nested data with path queries
|
|
15
|
-
- ✅ Stream large JSON files efficiently
|
|
16
|
-
- ✅ Validate JSON against schemas
|
|
17
|
-
- ✅ Parse and transform dates automatically
|
|
18
|
-
- ✅ Integrate with SDK transformation services
|
|
19
|
-
|
|
20
|
-
## What is JSON?
|
|
21
|
-
|
|
22
|
-
**JSON (JavaScript Object Notation)** is a lightweight data format that:
|
|
23
|
-
- Supports nested objects and arrays
|
|
24
|
-
- Uses key-value pairs
|
|
25
|
-
- Includes native types: string, number, boolean, null
|
|
26
|
-
- Is the standard format for modern APIs
|
|
27
|
-
|
|
28
|
-
**Example:**
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"products": [
|
|
32
|
-
{
|
|
33
|
-
"sku": "SKU001",
|
|
34
|
-
"name": "Wireless Mouse",
|
|
35
|
-
"price": 29.99,
|
|
36
|
-
"stock": {
|
|
37
|
-
"qty": 150,
|
|
38
|
-
"locations": ["WH-01", "WH-02"]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Basic JSON Parsing
|
|
46
|
-
|
|
47
|
-
### Simple Parsing
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
51
|
-
|
|
52
|
-
const jsonParser = new JSONParserService();
|
|
53
|
-
|
|
54
|
-
// Sample JSON data
|
|
55
|
-
const jsonContent = `{
|
|
56
|
-
"products": [
|
|
57
|
-
{
|
|
58
|
-
"sku": "SKU001",
|
|
59
|
-
"name": "Wireless Mouse",
|
|
60
|
-
"price": 29.99,
|
|
61
|
-
"stock": 150
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"sku": "SKU002",
|
|
65
|
-
"name": "Keyboard",
|
|
66
|
-
"price": 79.99,
|
|
67
|
-
"stock": 75
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
|
-
}`;
|
|
71
|
-
|
|
72
|
-
// Parse JSON
|
|
73
|
-
const parsed = await jsonParser.parse(jsonContent);
|
|
74
|
-
|
|
75
|
-
console.log('Parsed data:', parsed);
|
|
76
|
-
console.log(`Found ${parsed.products.length} products`);
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Type Safety with TypeScript
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
// Define your data structure
|
|
83
|
-
interface Product {
|
|
84
|
-
sku: string;
|
|
85
|
-
name: string;
|
|
86
|
-
price: number;
|
|
87
|
-
stock: number;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
interface ProductCatalog {
|
|
91
|
-
products: Product[];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Parse with type assertion
|
|
95
|
-
const catalog = await jsonParser.parse<ProductCatalog>(jsonContent);
|
|
96
|
-
|
|
97
|
-
// Now you have full type safety
|
|
98
|
-
catalog.products.forEach(product => {
|
|
99
|
-
console.log(`${product.sku}: ${product.name} - $${product.price}`);
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Nested Data Extraction
|
|
104
|
-
|
|
105
|
-
Extract specific parts of nested JSON using `dataPath`:
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
const nestedJSON = `{
|
|
109
|
-
"response": {
|
|
110
|
-
"status": "success",
|
|
111
|
-
"data": {
|
|
112
|
-
"inventory": {
|
|
113
|
-
"items": [
|
|
114
|
-
{"sku": "A001", "qty": 100},
|
|
115
|
-
{"sku": "A002", "qty": 50}
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}`;
|
|
121
|
-
|
|
122
|
-
// Extract nested data using dataPath
|
|
123
|
-
const items = await jsonParser.parse(nestedJSON, {
|
|
124
|
-
dataPath: 'response.data.inventory.items'
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
console.log('Extracted items:', items);
|
|
128
|
-
// Output: [{"sku": "A001", "qty": 100}, {"sku": "A002", "qty": 50}]
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## JSONL Format Support
|
|
132
|
-
|
|
133
|
-
**JSONL (JSON Lines)** is perfect for streaming large datasets where each line is a valid JSON object.
|
|
134
|
-
|
|
135
|
-
### Basic JSONL Parsing
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
const jsonlContent = `{"id": 1, "name": "Product 1", "price": 10.99}
|
|
139
|
-
{"id": 2, "name": "Product 2", "price": 20.99}
|
|
140
|
-
{"id": 3, "name": "Product 3", "price": 30.99}
|
|
141
|
-
{"id": 4, "name": "Product 4", "price": 40.99}`;
|
|
142
|
-
|
|
143
|
-
// Process each line individually
|
|
144
|
-
for await (const item of jsonParser.parseStreaming(jsonlContent, {
|
|
145
|
-
jsonLines: true,
|
|
146
|
-
batchSize: 1
|
|
147
|
-
})) {
|
|
148
|
-
console.log('Processing item:', item);
|
|
149
|
-
// Process each item as it's parsed
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Batch Processing JSONL
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
async function processBatchedJSONL(jsonlContent: string) {
|
|
157
|
-
const jsonParser = new JSONParserService();
|
|
158
|
-
|
|
159
|
-
// Process in batches of 100
|
|
160
|
-
for await (const batch of jsonParser.parseStreaming(jsonlContent, {
|
|
161
|
-
jsonLines: true,
|
|
162
|
-
batchSize: 100
|
|
163
|
-
})) {
|
|
164
|
-
console.log(`Processing batch of ${batch.length} items`);
|
|
165
|
-
await processBatch(batch);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function processBatch(items: unknown[]) {
|
|
170
|
-
// Send batch to Fluent Commerce
|
|
171
|
-
console.log(`Sending ${items.length} items to Fluent`);
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## Streaming for Large Files
|
|
176
|
-
|
|
177
|
-
Handle large JSON files without loading everything into memory.
|
|
178
|
-
|
|
179
|
-
### Memory-Efficient Streaming
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
import { Readable } from 'stream';
|
|
183
|
-
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
184
|
-
|
|
185
|
-
async function streamLargeFile(fileStream: Readable) {
|
|
186
|
-
const jsonParser = new JSONParserService();
|
|
187
|
-
|
|
188
|
-
// Configure streaming options
|
|
189
|
-
const streamOptions = {
|
|
190
|
-
batchSize: 50,
|
|
191
|
-
memoryLimit: 10 * 1024 * 1024, // 10MB limit
|
|
192
|
-
parseDates: true
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
let totalProcessed = 0;
|
|
196
|
-
|
|
197
|
-
for await (const batch of jsonParser.parseStreaming(fileStream, streamOptions)) {
|
|
198
|
-
// Process each batch
|
|
199
|
-
await processInventoryBatch(batch);
|
|
200
|
-
|
|
201
|
-
totalProcessed += Array.isArray(batch) ? batch.length : 1;
|
|
202
|
-
console.log(`Processed ${totalProcessed} items`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async function processInventoryBatch(items: unknown) {
|
|
207
|
-
// Transform and send to Fluent
|
|
208
|
-
console.log('Processing batch...');
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Streaming with Progress Tracking
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
async function streamWithProgress(jsonContent: string) {
|
|
216
|
-
const jsonParser = new JSONParserService();
|
|
217
|
-
const startTime = Date.now();
|
|
218
|
-
let itemCount = 0;
|
|
219
|
-
|
|
220
|
-
for await (const item of jsonParser.parseStreaming(jsonContent, {
|
|
221
|
-
batchSize: 1
|
|
222
|
-
})) {
|
|
223
|
-
itemCount++;
|
|
224
|
-
|
|
225
|
-
// Process item
|
|
226
|
-
await processItem(item);
|
|
227
|
-
|
|
228
|
-
// Report progress every 100 items
|
|
229
|
-
if (itemCount % 100 === 0) {
|
|
230
|
-
const elapsed = (Date.now() - startTime) / 1000;
|
|
231
|
-
const rate = itemCount / elapsed;
|
|
232
|
-
console.log(`Processed ${itemCount} items (${rate.toFixed(2)} items/sec)`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
console.log(`Completed: ${itemCount} total items`);
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## Schema Validation
|
|
241
|
-
|
|
242
|
-
Validate JSON against a schema to ensure data integrity.
|
|
243
|
-
|
|
244
|
-
### Basic Schema Validation
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
const schema = {
|
|
248
|
-
type: 'object',
|
|
249
|
-
required: ['sku', 'name', 'price'],
|
|
250
|
-
properties: {
|
|
251
|
-
sku: { type: 'string' },
|
|
252
|
-
name: { type: 'string' },
|
|
253
|
-
price: { type: 'number' },
|
|
254
|
-
stock: { type: 'number' }
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const productJSON = `{
|
|
259
|
-
"sku": "PROD001",
|
|
260
|
-
"name": "Test Product",
|
|
261
|
-
"price": 29.99
|
|
262
|
-
}`;
|
|
263
|
-
|
|
264
|
-
async function validateAndParse() {
|
|
265
|
-
const jsonParser = new JSONParserService();
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
const parsed = await jsonParser.parse(productJSON, {
|
|
269
|
-
validateSchema: true,
|
|
270
|
-
schema: schema
|
|
271
|
-
});
|
|
272
|
-
console.log('Valid product:', parsed);
|
|
273
|
-
} catch (error) {
|
|
274
|
-
console.error('Validation failed:', error);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Complex Schema Validation
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
const orderSchema = {
|
|
283
|
-
type: 'object',
|
|
284
|
-
required: ['orderId', 'customer', 'items'],
|
|
285
|
-
properties: {
|
|
286
|
-
orderId: { type: 'string' },
|
|
287
|
-
customer: {
|
|
288
|
-
type: 'object',
|
|
289
|
-
required: ['email'],
|
|
290
|
-
properties: {
|
|
291
|
-
email: { type: 'string' },
|
|
292
|
-
name: { type: 'string' }
|
|
293
|
-
}
|
|
294
|
-
},
|
|
295
|
-
items: {
|
|
296
|
-
type: 'array',
|
|
297
|
-
items: {
|
|
298
|
-
type: 'object',
|
|
299
|
-
required: ['sku', 'quantity'],
|
|
300
|
-
properties: {
|
|
301
|
-
sku: { type: 'string' },
|
|
302
|
-
quantity: { type: 'number' },
|
|
303
|
-
price: { type: 'number' }
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// Validate order data
|
|
311
|
-
const orderJSON = `{
|
|
312
|
-
"orderId": "ORD001",
|
|
313
|
-
"customer": {
|
|
314
|
-
"email": "customer@example.com",
|
|
315
|
-
"name": "John Doe"
|
|
316
|
-
},
|
|
317
|
-
"items": [
|
|
318
|
-
{"sku": "SKU001", "quantity": 2, "price": 29.99},
|
|
319
|
-
{"sku": "SKU002", "quantity": 1, "price": 49.99}
|
|
320
|
-
]
|
|
321
|
-
}`;
|
|
322
|
-
|
|
323
|
-
const order = await jsonParser.parse(orderJSON, {
|
|
324
|
-
validateSchema: true,
|
|
325
|
-
schema: orderSchema
|
|
326
|
-
});
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## JSONPath Queries
|
|
330
|
-
|
|
331
|
-
Extract specific data using JSONPath-like syntax.
|
|
332
|
-
|
|
333
|
-
### Basic Queries
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
const data = {
|
|
337
|
-
store: {
|
|
338
|
-
name: "Electronics Store",
|
|
339
|
-
inventory: {
|
|
340
|
-
laptops: [
|
|
341
|
-
{ brand: "Dell", model: "XPS", price: 1200 },
|
|
342
|
-
{ brand: "Apple", model: "MacBook", price: 2000 },
|
|
343
|
-
{ brand: "Lenovo", model: "ThinkPad", price: 1500 }
|
|
344
|
-
],
|
|
345
|
-
phones: [
|
|
346
|
-
{ brand: "Apple", model: "iPhone", price: 999 },
|
|
347
|
-
{ brand: "Samsung", model: "Galaxy", price: 899 }
|
|
348
|
-
]
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const jsonParser = new JSONParserService();
|
|
354
|
-
|
|
355
|
-
// Query specific paths
|
|
356
|
-
const storeName = jsonParser.query(data, 'store.name');
|
|
357
|
-
console.log('Store:', storeName); // "Electronics Store"
|
|
358
|
-
|
|
359
|
-
const laptops = jsonParser.query(data, 'store.inventory.laptops');
|
|
360
|
-
console.log('Laptops:', laptops); // Array of laptops
|
|
361
|
-
|
|
362
|
-
const firstLaptop = jsonParser.query(data, 'store.inventory.laptops[0]');
|
|
363
|
-
console.log('First laptop:', firstLaptop); // Dell XPS
|
|
364
|
-
|
|
365
|
-
// Wildcard queries
|
|
366
|
-
const allInventory = jsonParser.query(data, 'store.inventory.*');
|
|
367
|
-
console.log('All inventory:', allInventory); // All inventory items
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
### Advanced Queries
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
// Complex nested structures
|
|
374
|
-
const orderData = {
|
|
375
|
-
orders: [
|
|
376
|
-
{
|
|
377
|
-
id: "ORD001",
|
|
378
|
-
customer: { name: "John", tier: "gold" },
|
|
379
|
-
items: [
|
|
380
|
-
{ sku: "A1", qty: 2 },
|
|
381
|
-
{ sku: "A2", qty: 1 }
|
|
382
|
-
]
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
id: "ORD002",
|
|
386
|
-
customer: { name: "Jane", tier: "silver" },
|
|
387
|
-
items: [
|
|
388
|
-
{ sku: "B1", qty: 3 }
|
|
389
|
-
]
|
|
390
|
-
}
|
|
391
|
-
]
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
// Query nested arrays
|
|
395
|
-
const firstOrderItems = jsonParser.query(orderData, 'orders[0].items');
|
|
396
|
-
const allCustomerNames = jsonParser.query(orderData, 'orders.*.customer.name');
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
## Date Parsing
|
|
400
|
-
|
|
401
|
-
### Automatic Date Parsing
|
|
402
|
-
|
|
403
|
-
```typescript
|
|
404
|
-
const jsonWithDates = `{
|
|
405
|
-
"createdAt": "2025-01-15T10:30:00Z",
|
|
406
|
-
"updatedAt": "2025-01-15T14:45:00.000Z",
|
|
407
|
-
"shipDate": "2025-01-20",
|
|
408
|
-
"customDate": "15/01/2025"
|
|
409
|
-
}`;
|
|
410
|
-
|
|
411
|
-
// Parse with automatic date detection
|
|
412
|
-
const parsed = await jsonParser.parse(jsonWithDates, {
|
|
413
|
-
parseDates: true,
|
|
414
|
-
dateFormats: ['YYYY-MM-DD', 'DD/MM/YYYY']
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
console.log('Created:', parsed.createdAt); // Date object
|
|
418
|
-
console.log('Ship date:', parsed.shipDate); // Date object
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### Custom Reviver Functions
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
// Custom reviver for special transformations
|
|
425
|
-
const customReviver = (key: string, value: unknown): unknown => {
|
|
426
|
-
// Convert price strings to numbers
|
|
427
|
-
if (key === 'price' && typeof value === 'string') {
|
|
428
|
-
return parseFloat(value.replace('$', ''));
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// Convert ISO dates to Date objects
|
|
432
|
-
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
|
|
433
|
-
return new Date(value);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Convert "null" strings to actual null
|
|
437
|
-
if (value === "null") {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
return value;
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
const jsonData = `{
|
|
445
|
-
"product": "Widget",
|
|
446
|
-
"price": "$29.99",
|
|
447
|
-
"lastUpdated": "2025-01-15T10:00:00Z",
|
|
448
|
-
"discontinued": "null"
|
|
449
|
-
}`;
|
|
450
|
-
|
|
451
|
-
const result = await jsonParser.parse(jsonData, {
|
|
452
|
-
reviver: customReviver
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
console.log(result);
|
|
456
|
-
// {
|
|
457
|
-
// product: "Widget",
|
|
458
|
-
// price: 29.99,
|
|
459
|
-
// lastUpdated: Date object,
|
|
460
|
-
// discontinued: null
|
|
461
|
-
// }
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
## Transformation Examples
|
|
465
|
-
|
|
466
|
-
### E-commerce Platform Migration
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
// Shopify to Fluent Commerce transformation
|
|
470
|
-
async function transformShopifyData() {
|
|
471
|
-
const shopifyJSON = `{
|
|
472
|
-
"products": [
|
|
473
|
-
{
|
|
474
|
-
"id": 123456,
|
|
475
|
-
"title": "Wireless Mouse",
|
|
476
|
-
"variants": [
|
|
477
|
-
{
|
|
478
|
-
"sku": "WM-001",
|
|
479
|
-
"inventory_quantity": 150,
|
|
480
|
-
"price": "29.99"
|
|
481
|
-
}
|
|
482
|
-
]
|
|
483
|
-
}
|
|
484
|
-
]
|
|
485
|
-
}`;
|
|
486
|
-
|
|
487
|
-
const jsonParser = new JSONParserService();
|
|
488
|
-
const mapper = new UniversalMapper({
|
|
489
|
-
fields: {
|
|
490
|
-
ref: { source: 'variants[0].sku', required: true },
|
|
491
|
-
name: { source: 'title', required: true },
|
|
492
|
-
qty: { source: 'variants[0].inventory_quantity', resolver: 'sdk.parseInt' },
|
|
493
|
-
price: { source: 'variants[0].price', resolver: 'sdk.parseFloat' }
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
// Parse Shopify data
|
|
498
|
-
const shopifyData = await jsonParser.parse(shopifyJSON);
|
|
499
|
-
|
|
500
|
-
// Transform to Fluent format using UniversalMapper
|
|
501
|
-
const fluentProducts = [];
|
|
502
|
-
|
|
503
|
-
for (const product of shopifyData.products) {
|
|
504
|
-
for (const variant of product.variants) {
|
|
505
|
-
const result = await mapper.map({
|
|
506
|
-
...product,
|
|
507
|
-
variants: [variant] // Map each variant individually
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
if (result.success) {
|
|
511
|
-
fluentProducts.push(result.data);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return fluentProducts;
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
### WooCommerce Integration
|
|
521
|
-
|
|
522
|
-
```typescript
|
|
523
|
-
async function processWooCommerceWebhook(webhookPayload: string) {
|
|
524
|
-
const jsonParser = new JSONParserService();
|
|
525
|
-
|
|
526
|
-
// Parse webhook payload
|
|
527
|
-
const order = await jsonParser.parse(webhookPayload, {
|
|
528
|
-
parseDates: true,
|
|
529
|
-
dataPath: 'order' // If nested
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
// Transform to Fluent format
|
|
533
|
-
const fluentOrder = {
|
|
534
|
-
ref: `WC-${order.id}`,
|
|
535
|
-
type: 'HD',
|
|
536
|
-
retailerId: '1',
|
|
537
|
-
customer: {
|
|
538
|
-
email: order.billing.email,
|
|
539
|
-
firstName: order.billing.first_name,
|
|
540
|
-
lastName: order.billing.last_name
|
|
541
|
-
},
|
|
542
|
-
items: order.line_items.map(item => ({
|
|
543
|
-
ref: item.sku,
|
|
544
|
-
quantity: item.quantity,
|
|
545
|
-
price: parseFloat(item.price)
|
|
546
|
-
}))
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
return fluentOrder;
|
|
550
|
-
}
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
## Integration with SDK Features
|
|
554
|
-
|
|
555
|
-
### With Field Mapping
|
|
556
|
-
|
|
557
|
-
```typescript
|
|
558
|
-
import { JSONParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
559
|
-
|
|
560
|
-
async function parseAndMap(jsonContent: string) {
|
|
561
|
-
const jsonParser = new JSONParserService();
|
|
562
|
-
|
|
563
|
-
// Parse JSON
|
|
564
|
-
const data = await jsonParser.parse(jsonContent, {
|
|
565
|
-
parseDates: true,
|
|
566
|
-
dataPath: 'data.products'
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
// Define mapping configuration using UniversalMapper structure
|
|
570
|
-
const mappingConfig = {
|
|
571
|
-
fields: {
|
|
572
|
-
ref: { source: 'product_id', required: true },
|
|
573
|
-
qty: { source: 'quantity_available', resolver: 'sdk.parseInt' },
|
|
574
|
-
locationRef: { source: 'warehouse_location' }
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
|
|
578
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
579
|
-
const result = await mapper.map(data);
|
|
580
|
-
|
|
581
|
-
if (!result.success) {
|
|
582
|
-
console.error('Mapping errors:', result.errors);
|
|
583
|
-
throw new Error('Mapping failed');
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return result.data;
|
|
587
|
-
}
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
### With Fluent Client
|
|
591
|
-
|
|
592
|
-
```typescript
|
|
593
|
-
async function processJSONToFluent(jsonContent: string) {
|
|
594
|
-
const jsonParser = new JSONParserService();
|
|
595
|
-
const fluentClient = await createClient({ config });
|
|
596
|
-
|
|
597
|
-
// Parse and validate
|
|
598
|
-
const products = await jsonParser.parse(jsonContent, {
|
|
599
|
-
validateSchema: true,
|
|
600
|
-
schema: productSchema
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
// Send to Fluent using GraphQL mutations (NOT Batch API for PRODUCT!)
|
|
604
|
-
// Batch API only supports INVENTORY
|
|
605
|
-
const batchSize = 100;
|
|
606
|
-
for (let i = 0; i < products.length; i += batchSize) {
|
|
607
|
-
const batch = products.slice(i, i + batchSize);
|
|
608
|
-
|
|
609
|
-
// Process each product with GraphQL mutation
|
|
610
|
-
for (const product of batch) {
|
|
611
|
-
await fluentClient.graphql({
|
|
612
|
-
query: `
|
|
613
|
-
mutation CreateProduct($input: CreateStandardProductInput!) {
|
|
614
|
-
createStandardProduct(input: $input) {
|
|
615
|
-
id
|
|
616
|
-
ref
|
|
617
|
-
status
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
`,
|
|
621
|
-
variables: {
|
|
622
|
-
input: {
|
|
623
|
-
ref: product.ref || product.sku,
|
|
624
|
-
type: 'STANDARD',
|
|
625
|
-
status: product.status || 'ACTIVE',
|
|
626
|
-
attributes: [
|
|
627
|
-
{ name: 'name', type: 'STRING', value: product.name }
|
|
628
|
-
]
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
console.log(`Processed batch ${Math.floor(i / batchSize) + 1} using GraphQL mutations`);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
## Error Handling
|
|
640
|
-
|
|
641
|
-
### Comprehensive Error Handling
|
|
642
|
-
|
|
643
|
-
```typescript
|
|
644
|
-
import { FileParsingError } from '@fluentcommerce/fc-connect-sdk';
|
|
645
|
-
|
|
646
|
-
async function robustJSONParsing(jsonContent: string) {
|
|
647
|
-
const jsonParser = new JSONParserService();
|
|
648
|
-
|
|
649
|
-
try {
|
|
650
|
-
// Validate first
|
|
651
|
-
const validation = jsonParser.validate(jsonContent);
|
|
652
|
-
|
|
653
|
-
if (!validation.valid) {
|
|
654
|
-
console.error('Validation errors:', validation.errors);
|
|
655
|
-
|
|
656
|
-
if (validation.warnings) {
|
|
657
|
-
console.warn('Warnings:', validation.warnings);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// Decide whether to proceed
|
|
661
|
-
if (validation.errors.some(e => e.includes('syntax error'))) {
|
|
662
|
-
throw new Error('Cannot parse invalid JSON');
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Parse with error recovery
|
|
667
|
-
const parsed = await jsonParser.parse(jsonContent, {
|
|
668
|
-
allowComments: true, // Allow // and /* */ comments
|
|
669
|
-
allowTrailingCommas: true, // Allow trailing commas
|
|
670
|
-
parseDates: true
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
return parsed;
|
|
674
|
-
|
|
675
|
-
} catch (error) {
|
|
676
|
-
if (error instanceof FileParsingError) {
|
|
677
|
-
console.error('Parsing error:', error.message);
|
|
678
|
-
console.error('Context:', error.context);
|
|
679
|
-
|
|
680
|
-
// Try to extract line/column info
|
|
681
|
-
const match = error.message.match(/line (\d+), column (\d+)/);
|
|
682
|
-
if (match) {
|
|
683
|
-
const [, line, column] = match;
|
|
684
|
-
console.error(`Error at line ${line}, column ${column}`);
|
|
685
|
-
|
|
686
|
-
// Show the problematic line
|
|
687
|
-
const lines = jsonContent.split('\n');
|
|
688
|
-
if (lines[parseInt(line) - 1]) {
|
|
689
|
-
console.error('Problematic line:', lines[parseInt(line) - 1]);
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
throw error;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
## Performance Tips
|
|
700
|
-
|
|
701
|
-
### 1. Use Streaming for Large Files
|
|
702
|
-
|
|
703
|
-
```typescript
|
|
704
|
-
// ❌ BAD: Load everything at once
|
|
705
|
-
const allData = await jsonParser.parse(jsonContent); // May cause memory issues
|
|
706
|
-
|
|
707
|
-
// ✅ GOOD: Stream and process
|
|
708
|
-
for await (const batch of jsonParser.parseStreaming(jsonContent, {
|
|
709
|
-
batchSize: 100
|
|
710
|
-
})) {
|
|
711
|
-
await processBatch(batch);
|
|
712
|
-
}
|
|
713
|
-
```
|
|
714
|
-
|
|
715
|
-
### 2. Optimize Parsing Options
|
|
716
|
-
|
|
717
|
-
```typescript
|
|
718
|
-
// Disable unnecessary features for better performance
|
|
719
|
-
const optimizedOptions = {
|
|
720
|
-
parseDates: false, // Skip if not needed
|
|
721
|
-
validateSchema: false, // Skip validation if data is trusted
|
|
722
|
-
maxDepth: 10 // Limit nesting depth
|
|
723
|
-
};
|
|
724
|
-
|
|
725
|
-
const parsed = await jsonParser.parse(jsonContent, optimizedOptions);
|
|
726
|
-
```
|
|
727
|
-
|
|
728
|
-
### 3. Parallel Processing
|
|
729
|
-
|
|
730
|
-
```typescript
|
|
731
|
-
async function parallelProcessing(jsonArrays: string[]) {
|
|
732
|
-
const jsonParser = new JSONParserService();
|
|
733
|
-
|
|
734
|
-
// Process multiple JSON files in parallel
|
|
735
|
-
const promises = jsonArrays.map(async (json) => {
|
|
736
|
-
return await jsonParser.parse(json);
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
const results = await Promise.all(promises);
|
|
740
|
-
return results;
|
|
741
|
-
}
|
|
742
|
-
```
|
|
743
|
-
|
|
744
|
-
## Key Takeaways
|
|
745
|
-
|
|
746
|
-
- 🎯 JSON Parser handles modern API responses and nested structures
|
|
747
|
-
- 🎯 Use JSONL format for streaming large datasets line-by-line
|
|
748
|
-
- 🎯 Extract nested data with `dataPath` option
|
|
749
|
-
- 🎯 Validate structure with schema validation
|
|
750
|
-
- 🎯 Parse dates automatically with `parseDates` option
|
|
751
|
-
- 🎯 Stream large files with `parseStreaming()` for memory efficiency
|
|
752
|
-
- 🎯 Combine with UniversalMapper for transformations
|
|
753
|
-
|
|
754
|
-
## Practice Exercise
|
|
755
|
-
|
|
756
|
-
**Challenge:** Parse this Shopify webhook and transform it for Fluent:
|
|
757
|
-
|
|
758
|
-
```json
|
|
759
|
-
{
|
|
760
|
-
"order": {
|
|
761
|
-
"id": 12345,
|
|
762
|
-
"email": "customer@example.com",
|
|
763
|
-
"created_at": "2025-01-15T10:30:00Z",
|
|
764
|
-
"line_items": [
|
|
765
|
-
{
|
|
766
|
-
"sku": "SKU001",
|
|
767
|
-
"quantity": 2,
|
|
768
|
-
"price": "29.99"
|
|
769
|
-
}
|
|
770
|
-
]
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
```
|
|
774
|
-
|
|
775
|
-
**Requirements:**
|
|
776
|
-
1. Parse the JSON
|
|
777
|
-
2. Extract the order object
|
|
778
|
-
3. Transform to: `{ ref, customer: { email }, items: [{ ref, quantity, price }] }`
|
|
779
|
-
4. Parse the date and convert price to number
|
|
780
|
-
|
|
781
|
-
**Solution:** See [JSON Examples](../examples/json-parser-examples.ts)
|
|
782
|
-
|
|
783
|
-
## Next Steps
|
|
784
|
-
|
|
785
|
-
Continue to [Module 4: XML Parser →](./02-core-guides-parsers-04-xml-parser.md) to learn XML parsing and generation.
|
|
786
|
-
|
|
787
|
-
---
|
|
788
|
-
|
|
789
|
-
**Module 3 Complete!** ✅
|
|
1
|
+
# Module 3: JSON Parser
|
|
2
|
+
|
|
3
|
+
**Level:** Beginner
|
|
4
|
+
**Estimated Time:** 25 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module covers the JSON Parser (`JSONParserService`), essential for processing API responses, webhooks, and modern data formats. You'll learn how to parse JSON and JSONL, extract nested data, handle large files with streaming, and validate data structures.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Parse JSON and JSONL (JSON Lines) formats
|
|
14
|
+
- ✅ Extract nested data with path queries
|
|
15
|
+
- ✅ Stream large JSON files efficiently
|
|
16
|
+
- ✅ Validate JSON against schemas
|
|
17
|
+
- ✅ Parse and transform dates automatically
|
|
18
|
+
- ✅ Integrate with SDK transformation services
|
|
19
|
+
|
|
20
|
+
## What is JSON?
|
|
21
|
+
|
|
22
|
+
**JSON (JavaScript Object Notation)** is a lightweight data format that:
|
|
23
|
+
- Supports nested objects and arrays
|
|
24
|
+
- Uses key-value pairs
|
|
25
|
+
- Includes native types: string, number, boolean, null
|
|
26
|
+
- Is the standard format for modern APIs
|
|
27
|
+
|
|
28
|
+
**Example:**
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"products": [
|
|
32
|
+
{
|
|
33
|
+
"sku": "SKU001",
|
|
34
|
+
"name": "Wireless Mouse",
|
|
35
|
+
"price": 29.99,
|
|
36
|
+
"stock": {
|
|
37
|
+
"qty": 150,
|
|
38
|
+
"locations": ["WH-01", "WH-02"]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Basic JSON Parsing
|
|
46
|
+
|
|
47
|
+
### Simple Parsing
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
51
|
+
|
|
52
|
+
const jsonParser = new JSONParserService();
|
|
53
|
+
|
|
54
|
+
// Sample JSON data
|
|
55
|
+
const jsonContent = `{
|
|
56
|
+
"products": [
|
|
57
|
+
{
|
|
58
|
+
"sku": "SKU001",
|
|
59
|
+
"name": "Wireless Mouse",
|
|
60
|
+
"price": 29.99,
|
|
61
|
+
"stock": 150
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"sku": "SKU002",
|
|
65
|
+
"name": "Keyboard",
|
|
66
|
+
"price": 79.99,
|
|
67
|
+
"stock": 75
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}`;
|
|
71
|
+
|
|
72
|
+
// Parse JSON
|
|
73
|
+
const parsed = await jsonParser.parse(jsonContent);
|
|
74
|
+
|
|
75
|
+
console.log('Parsed data:', parsed);
|
|
76
|
+
console.log(`Found ${parsed.products.length} products`);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Type Safety with TypeScript
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Define your data structure
|
|
83
|
+
interface Product {
|
|
84
|
+
sku: string;
|
|
85
|
+
name: string;
|
|
86
|
+
price: number;
|
|
87
|
+
stock: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface ProductCatalog {
|
|
91
|
+
products: Product[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Parse with type assertion
|
|
95
|
+
const catalog = await jsonParser.parse<ProductCatalog>(jsonContent);
|
|
96
|
+
|
|
97
|
+
// Now you have full type safety
|
|
98
|
+
catalog.products.forEach(product => {
|
|
99
|
+
console.log(`${product.sku}: ${product.name} - $${product.price}`);
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Nested Data Extraction
|
|
104
|
+
|
|
105
|
+
Extract specific parts of nested JSON using `dataPath`:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const nestedJSON = `{
|
|
109
|
+
"response": {
|
|
110
|
+
"status": "success",
|
|
111
|
+
"data": {
|
|
112
|
+
"inventory": {
|
|
113
|
+
"items": [
|
|
114
|
+
{"sku": "A001", "qty": 100},
|
|
115
|
+
{"sku": "A002", "qty": 50}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}`;
|
|
121
|
+
|
|
122
|
+
// Extract nested data using dataPath
|
|
123
|
+
const items = await jsonParser.parse(nestedJSON, {
|
|
124
|
+
dataPath: 'response.data.inventory.items'
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
console.log('Extracted items:', items);
|
|
128
|
+
// Output: [{"sku": "A001", "qty": 100}, {"sku": "A002", "qty": 50}]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## JSONL Format Support
|
|
132
|
+
|
|
133
|
+
**JSONL (JSON Lines)** is perfect for streaming large datasets where each line is a valid JSON object.
|
|
134
|
+
|
|
135
|
+
### Basic JSONL Parsing
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const jsonlContent = `{"id": 1, "name": "Product 1", "price": 10.99}
|
|
139
|
+
{"id": 2, "name": "Product 2", "price": 20.99}
|
|
140
|
+
{"id": 3, "name": "Product 3", "price": 30.99}
|
|
141
|
+
{"id": 4, "name": "Product 4", "price": 40.99}`;
|
|
142
|
+
|
|
143
|
+
// Process each line individually
|
|
144
|
+
for await (const item of jsonParser.parseStreaming(jsonlContent, {
|
|
145
|
+
jsonLines: true,
|
|
146
|
+
batchSize: 1
|
|
147
|
+
})) {
|
|
148
|
+
console.log('Processing item:', item);
|
|
149
|
+
// Process each item as it's parsed
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Batch Processing JSONL
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
async function processBatchedJSONL(jsonlContent: string) {
|
|
157
|
+
const jsonParser = new JSONParserService();
|
|
158
|
+
|
|
159
|
+
// Process in batches of 100
|
|
160
|
+
for await (const batch of jsonParser.parseStreaming(jsonlContent, {
|
|
161
|
+
jsonLines: true,
|
|
162
|
+
batchSize: 100
|
|
163
|
+
})) {
|
|
164
|
+
console.log(`Processing batch of ${batch.length} items`);
|
|
165
|
+
await processBatch(batch);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function processBatch(items: unknown[]) {
|
|
170
|
+
// Send batch to Fluent Commerce
|
|
171
|
+
console.log(`Sending ${items.length} items to Fluent`);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Streaming for Large Files
|
|
176
|
+
|
|
177
|
+
Handle large JSON files without loading everything into memory.
|
|
178
|
+
|
|
179
|
+
### Memory-Efficient Streaming
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { Readable } from 'stream';
|
|
183
|
+
import { JSONParserService } from '@fluentcommerce/fc-connect-sdk';
|
|
184
|
+
|
|
185
|
+
async function streamLargeFile(fileStream: Readable) {
|
|
186
|
+
const jsonParser = new JSONParserService();
|
|
187
|
+
|
|
188
|
+
// Configure streaming options
|
|
189
|
+
const streamOptions = {
|
|
190
|
+
batchSize: 50,
|
|
191
|
+
memoryLimit: 10 * 1024 * 1024, // 10MB limit
|
|
192
|
+
parseDates: true
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
let totalProcessed = 0;
|
|
196
|
+
|
|
197
|
+
for await (const batch of jsonParser.parseStreaming(fileStream, streamOptions)) {
|
|
198
|
+
// Process each batch
|
|
199
|
+
await processInventoryBatch(batch);
|
|
200
|
+
|
|
201
|
+
totalProcessed += Array.isArray(batch) ? batch.length : 1;
|
|
202
|
+
console.log(`Processed ${totalProcessed} items`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function processInventoryBatch(items: unknown) {
|
|
207
|
+
// Transform and send to Fluent
|
|
208
|
+
console.log('Processing batch...');
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Streaming with Progress Tracking
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
async function streamWithProgress(jsonContent: string) {
|
|
216
|
+
const jsonParser = new JSONParserService();
|
|
217
|
+
const startTime = Date.now();
|
|
218
|
+
let itemCount = 0;
|
|
219
|
+
|
|
220
|
+
for await (const item of jsonParser.parseStreaming(jsonContent, {
|
|
221
|
+
batchSize: 1
|
|
222
|
+
})) {
|
|
223
|
+
itemCount++;
|
|
224
|
+
|
|
225
|
+
// Process item
|
|
226
|
+
await processItem(item);
|
|
227
|
+
|
|
228
|
+
// Report progress every 100 items
|
|
229
|
+
if (itemCount % 100 === 0) {
|
|
230
|
+
const elapsed = (Date.now() - startTime) / 1000;
|
|
231
|
+
const rate = itemCount / elapsed;
|
|
232
|
+
console.log(`Processed ${itemCount} items (${rate.toFixed(2)} items/sec)`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
console.log(`Completed: ${itemCount} total items`);
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Schema Validation
|
|
241
|
+
|
|
242
|
+
Validate JSON against a schema to ensure data integrity.
|
|
243
|
+
|
|
244
|
+
### Basic Schema Validation
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const schema = {
|
|
248
|
+
type: 'object',
|
|
249
|
+
required: ['sku', 'name', 'price'],
|
|
250
|
+
properties: {
|
|
251
|
+
sku: { type: 'string' },
|
|
252
|
+
name: { type: 'string' },
|
|
253
|
+
price: { type: 'number' },
|
|
254
|
+
stock: { type: 'number' }
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const productJSON = `{
|
|
259
|
+
"sku": "PROD001",
|
|
260
|
+
"name": "Test Product",
|
|
261
|
+
"price": 29.99
|
|
262
|
+
}`;
|
|
263
|
+
|
|
264
|
+
async function validateAndParse() {
|
|
265
|
+
const jsonParser = new JSONParserService();
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const parsed = await jsonParser.parse(productJSON, {
|
|
269
|
+
validateSchema: true,
|
|
270
|
+
schema: schema
|
|
271
|
+
});
|
|
272
|
+
console.log('Valid product:', parsed);
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.error('Validation failed:', error);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Complex Schema Validation
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
const orderSchema = {
|
|
283
|
+
type: 'object',
|
|
284
|
+
required: ['orderId', 'customer', 'items'],
|
|
285
|
+
properties: {
|
|
286
|
+
orderId: { type: 'string' },
|
|
287
|
+
customer: {
|
|
288
|
+
type: 'object',
|
|
289
|
+
required: ['email'],
|
|
290
|
+
properties: {
|
|
291
|
+
email: { type: 'string' },
|
|
292
|
+
name: { type: 'string' }
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
items: {
|
|
296
|
+
type: 'array',
|
|
297
|
+
items: {
|
|
298
|
+
type: 'object',
|
|
299
|
+
required: ['sku', 'quantity'],
|
|
300
|
+
properties: {
|
|
301
|
+
sku: { type: 'string' },
|
|
302
|
+
quantity: { type: 'number' },
|
|
303
|
+
price: { type: 'number' }
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// Validate order data
|
|
311
|
+
const orderJSON = `{
|
|
312
|
+
"orderId": "ORD001",
|
|
313
|
+
"customer": {
|
|
314
|
+
"email": "customer@example.com",
|
|
315
|
+
"name": "John Doe"
|
|
316
|
+
},
|
|
317
|
+
"items": [
|
|
318
|
+
{"sku": "SKU001", "quantity": 2, "price": 29.99},
|
|
319
|
+
{"sku": "SKU002", "quantity": 1, "price": 49.99}
|
|
320
|
+
]
|
|
321
|
+
}`;
|
|
322
|
+
|
|
323
|
+
const order = await jsonParser.parse(orderJSON, {
|
|
324
|
+
validateSchema: true,
|
|
325
|
+
schema: orderSchema
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## JSONPath Queries
|
|
330
|
+
|
|
331
|
+
Extract specific data using JSONPath-like syntax.
|
|
332
|
+
|
|
333
|
+
### Basic Queries
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
const data = {
|
|
337
|
+
store: {
|
|
338
|
+
name: "Electronics Store",
|
|
339
|
+
inventory: {
|
|
340
|
+
laptops: [
|
|
341
|
+
{ brand: "Dell", model: "XPS", price: 1200 },
|
|
342
|
+
{ brand: "Apple", model: "MacBook", price: 2000 },
|
|
343
|
+
{ brand: "Lenovo", model: "ThinkPad", price: 1500 }
|
|
344
|
+
],
|
|
345
|
+
phones: [
|
|
346
|
+
{ brand: "Apple", model: "iPhone", price: 999 },
|
|
347
|
+
{ brand: "Samsung", model: "Galaxy", price: 899 }
|
|
348
|
+
]
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const jsonParser = new JSONParserService();
|
|
354
|
+
|
|
355
|
+
// Query specific paths
|
|
356
|
+
const storeName = jsonParser.query(data, 'store.name');
|
|
357
|
+
console.log('Store:', storeName); // "Electronics Store"
|
|
358
|
+
|
|
359
|
+
const laptops = jsonParser.query(data, 'store.inventory.laptops');
|
|
360
|
+
console.log('Laptops:', laptops); // Array of laptops
|
|
361
|
+
|
|
362
|
+
const firstLaptop = jsonParser.query(data, 'store.inventory.laptops[0]');
|
|
363
|
+
console.log('First laptop:', firstLaptop); // Dell XPS
|
|
364
|
+
|
|
365
|
+
// Wildcard queries
|
|
366
|
+
const allInventory = jsonParser.query(data, 'store.inventory.*');
|
|
367
|
+
console.log('All inventory:', allInventory); // All inventory items
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Advanced Queries
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
// Complex nested structures
|
|
374
|
+
const orderData = {
|
|
375
|
+
orders: [
|
|
376
|
+
{
|
|
377
|
+
id: "ORD001",
|
|
378
|
+
customer: { name: "John", tier: "gold" },
|
|
379
|
+
items: [
|
|
380
|
+
{ sku: "A1", qty: 2 },
|
|
381
|
+
{ sku: "A2", qty: 1 }
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
id: "ORD002",
|
|
386
|
+
customer: { name: "Jane", tier: "silver" },
|
|
387
|
+
items: [
|
|
388
|
+
{ sku: "B1", qty: 3 }
|
|
389
|
+
]
|
|
390
|
+
}
|
|
391
|
+
]
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
// Query nested arrays
|
|
395
|
+
const firstOrderItems = jsonParser.query(orderData, 'orders[0].items');
|
|
396
|
+
const allCustomerNames = jsonParser.query(orderData, 'orders.*.customer.name');
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Date Parsing
|
|
400
|
+
|
|
401
|
+
### Automatic Date Parsing
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
const jsonWithDates = `{
|
|
405
|
+
"createdAt": "2025-01-15T10:30:00Z",
|
|
406
|
+
"updatedAt": "2025-01-15T14:45:00.000Z",
|
|
407
|
+
"shipDate": "2025-01-20",
|
|
408
|
+
"customDate": "15/01/2025"
|
|
409
|
+
}`;
|
|
410
|
+
|
|
411
|
+
// Parse with automatic date detection
|
|
412
|
+
const parsed = await jsonParser.parse(jsonWithDates, {
|
|
413
|
+
parseDates: true,
|
|
414
|
+
dateFormats: ['YYYY-MM-DD', 'DD/MM/YYYY']
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
console.log('Created:', parsed.createdAt); // Date object
|
|
418
|
+
console.log('Ship date:', parsed.shipDate); // Date object
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Custom Reviver Functions
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
// Custom reviver for special transformations
|
|
425
|
+
const customReviver = (key: string, value: unknown): unknown => {
|
|
426
|
+
// Convert price strings to numbers
|
|
427
|
+
if (key === 'price' && typeof value === 'string') {
|
|
428
|
+
return parseFloat(value.replace('$', ''));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Convert ISO dates to Date objects
|
|
432
|
+
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
|
|
433
|
+
return new Date(value);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Convert "null" strings to actual null
|
|
437
|
+
if (value === "null") {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return value;
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
const jsonData = `{
|
|
445
|
+
"product": "Widget",
|
|
446
|
+
"price": "$29.99",
|
|
447
|
+
"lastUpdated": "2025-01-15T10:00:00Z",
|
|
448
|
+
"discontinued": "null"
|
|
449
|
+
}`;
|
|
450
|
+
|
|
451
|
+
const result = await jsonParser.parse(jsonData, {
|
|
452
|
+
reviver: customReviver
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
console.log(result);
|
|
456
|
+
// {
|
|
457
|
+
// product: "Widget",
|
|
458
|
+
// price: 29.99,
|
|
459
|
+
// lastUpdated: Date object,
|
|
460
|
+
// discontinued: null
|
|
461
|
+
// }
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
## Transformation Examples
|
|
465
|
+
|
|
466
|
+
### E-commerce Platform Migration
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Shopify to Fluent Commerce transformation
|
|
470
|
+
async function transformShopifyData() {
|
|
471
|
+
const shopifyJSON = `{
|
|
472
|
+
"products": [
|
|
473
|
+
{
|
|
474
|
+
"id": 123456,
|
|
475
|
+
"title": "Wireless Mouse",
|
|
476
|
+
"variants": [
|
|
477
|
+
{
|
|
478
|
+
"sku": "WM-001",
|
|
479
|
+
"inventory_quantity": 150,
|
|
480
|
+
"price": "29.99"
|
|
481
|
+
}
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
]
|
|
485
|
+
}`;
|
|
486
|
+
|
|
487
|
+
const jsonParser = new JSONParserService();
|
|
488
|
+
const mapper = new UniversalMapper({
|
|
489
|
+
fields: {
|
|
490
|
+
ref: { source: 'variants[0].sku', required: true },
|
|
491
|
+
name: { source: 'title', required: true },
|
|
492
|
+
qty: { source: 'variants[0].inventory_quantity', resolver: 'sdk.parseInt' },
|
|
493
|
+
price: { source: 'variants[0].price', resolver: 'sdk.parseFloat' }
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Parse Shopify data
|
|
498
|
+
const shopifyData = await jsonParser.parse(shopifyJSON);
|
|
499
|
+
|
|
500
|
+
// Transform to Fluent format using UniversalMapper
|
|
501
|
+
const fluentProducts = [];
|
|
502
|
+
|
|
503
|
+
for (const product of shopifyData.products) {
|
|
504
|
+
for (const variant of product.variants) {
|
|
505
|
+
const result = await mapper.map({
|
|
506
|
+
...product,
|
|
507
|
+
variants: [variant] // Map each variant individually
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
if (result.success) {
|
|
511
|
+
fluentProducts.push(result.data);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return fluentProducts;
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### WooCommerce Integration
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
async function processWooCommerceWebhook(webhookPayload: string) {
|
|
524
|
+
const jsonParser = new JSONParserService();
|
|
525
|
+
|
|
526
|
+
// Parse webhook payload
|
|
527
|
+
const order = await jsonParser.parse(webhookPayload, {
|
|
528
|
+
parseDates: true,
|
|
529
|
+
dataPath: 'order' // If nested
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
// Transform to Fluent format
|
|
533
|
+
const fluentOrder = {
|
|
534
|
+
ref: `WC-${order.id}`,
|
|
535
|
+
type: 'HD',
|
|
536
|
+
retailerId: '1',
|
|
537
|
+
customer: {
|
|
538
|
+
email: order.billing.email,
|
|
539
|
+
firstName: order.billing.first_name,
|
|
540
|
+
lastName: order.billing.last_name
|
|
541
|
+
},
|
|
542
|
+
items: order.line_items.map(item => ({
|
|
543
|
+
ref: item.sku,
|
|
544
|
+
quantity: item.quantity,
|
|
545
|
+
price: parseFloat(item.price)
|
|
546
|
+
}))
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
return fluentOrder;
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
## Integration with SDK Features
|
|
554
|
+
|
|
555
|
+
### With Field Mapping
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
import { JSONParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
559
|
+
|
|
560
|
+
async function parseAndMap(jsonContent: string) {
|
|
561
|
+
const jsonParser = new JSONParserService();
|
|
562
|
+
|
|
563
|
+
// Parse JSON
|
|
564
|
+
const data = await jsonParser.parse(jsonContent, {
|
|
565
|
+
parseDates: true,
|
|
566
|
+
dataPath: 'data.products'
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// Define mapping configuration using UniversalMapper structure
|
|
570
|
+
const mappingConfig = {
|
|
571
|
+
fields: {
|
|
572
|
+
ref: { source: 'product_id', required: true },
|
|
573
|
+
qty: { source: 'quantity_available', resolver: 'sdk.parseInt' },
|
|
574
|
+
locationRef: { source: 'warehouse_location' }
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
579
|
+
const result = await mapper.map(data);
|
|
580
|
+
|
|
581
|
+
if (!result.success) {
|
|
582
|
+
console.error('Mapping errors:', result.errors);
|
|
583
|
+
throw new Error('Mapping failed');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return result.data;
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### With Fluent Client
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
async function processJSONToFluent(jsonContent: string) {
|
|
594
|
+
const jsonParser = new JSONParserService();
|
|
595
|
+
const fluentClient = await createClient({ config });
|
|
596
|
+
|
|
597
|
+
// Parse and validate
|
|
598
|
+
const products = await jsonParser.parse(jsonContent, {
|
|
599
|
+
validateSchema: true,
|
|
600
|
+
schema: productSchema
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
// Send to Fluent using GraphQL mutations (NOT Batch API for PRODUCT!)
|
|
604
|
+
// Batch API only supports INVENTORY
|
|
605
|
+
const batchSize = 100;
|
|
606
|
+
for (let i = 0; i < products.length; i += batchSize) {
|
|
607
|
+
const batch = products.slice(i, i + batchSize);
|
|
608
|
+
|
|
609
|
+
// Process each product with GraphQL mutation
|
|
610
|
+
for (const product of batch) {
|
|
611
|
+
await fluentClient.graphql({
|
|
612
|
+
query: `
|
|
613
|
+
mutation CreateProduct($input: CreateStandardProductInput!) {
|
|
614
|
+
createStandardProduct(input: $input) {
|
|
615
|
+
id
|
|
616
|
+
ref
|
|
617
|
+
status
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
`,
|
|
621
|
+
variables: {
|
|
622
|
+
input: {
|
|
623
|
+
ref: product.ref || product.sku,
|
|
624
|
+
type: 'STANDARD',
|
|
625
|
+
status: product.status || 'ACTIVE',
|
|
626
|
+
attributes: [
|
|
627
|
+
{ name: 'name', type: 'STRING', value: product.name }
|
|
628
|
+
]
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
console.log(`Processed batch ${Math.floor(i / batchSize) + 1} using GraphQL mutations`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
## Error Handling
|
|
640
|
+
|
|
641
|
+
### Comprehensive Error Handling
|
|
642
|
+
|
|
643
|
+
```typescript
|
|
644
|
+
import { FileParsingError } from '@fluentcommerce/fc-connect-sdk';
|
|
645
|
+
|
|
646
|
+
async function robustJSONParsing(jsonContent: string) {
|
|
647
|
+
const jsonParser = new JSONParserService();
|
|
648
|
+
|
|
649
|
+
try {
|
|
650
|
+
// Validate first
|
|
651
|
+
const validation = jsonParser.validate(jsonContent);
|
|
652
|
+
|
|
653
|
+
if (!validation.valid) {
|
|
654
|
+
console.error('Validation errors:', validation.errors);
|
|
655
|
+
|
|
656
|
+
if (validation.warnings) {
|
|
657
|
+
console.warn('Warnings:', validation.warnings);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Decide whether to proceed
|
|
661
|
+
if (validation.errors.some(e => e.includes('syntax error'))) {
|
|
662
|
+
throw new Error('Cannot parse invalid JSON');
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// Parse with error recovery
|
|
667
|
+
const parsed = await jsonParser.parse(jsonContent, {
|
|
668
|
+
allowComments: true, // Allow // and /* */ comments
|
|
669
|
+
allowTrailingCommas: true, // Allow trailing commas
|
|
670
|
+
parseDates: true
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
return parsed;
|
|
674
|
+
|
|
675
|
+
} catch (error) {
|
|
676
|
+
if (error instanceof FileParsingError) {
|
|
677
|
+
console.error('Parsing error:', error.message);
|
|
678
|
+
console.error('Context:', error.context);
|
|
679
|
+
|
|
680
|
+
// Try to extract line/column info
|
|
681
|
+
const match = error.message.match(/line (\d+), column (\d+)/);
|
|
682
|
+
if (match) {
|
|
683
|
+
const [, line, column] = match;
|
|
684
|
+
console.error(`Error at line ${line}, column ${column}`);
|
|
685
|
+
|
|
686
|
+
// Show the problematic line
|
|
687
|
+
const lines = jsonContent.split('\n');
|
|
688
|
+
if (lines[parseInt(line) - 1]) {
|
|
689
|
+
console.error('Problematic line:', lines[parseInt(line) - 1]);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
throw error;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
## Performance Tips
|
|
700
|
+
|
|
701
|
+
### 1. Use Streaming for Large Files
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
// ❌ BAD: Load everything at once
|
|
705
|
+
const allData = await jsonParser.parse(jsonContent); // May cause memory issues
|
|
706
|
+
|
|
707
|
+
// ✅ GOOD: Stream and process
|
|
708
|
+
for await (const batch of jsonParser.parseStreaming(jsonContent, {
|
|
709
|
+
batchSize: 100
|
|
710
|
+
})) {
|
|
711
|
+
await processBatch(batch);
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### 2. Optimize Parsing Options
|
|
716
|
+
|
|
717
|
+
```typescript
|
|
718
|
+
// Disable unnecessary features for better performance
|
|
719
|
+
const optimizedOptions = {
|
|
720
|
+
parseDates: false, // Skip if not needed
|
|
721
|
+
validateSchema: false, // Skip validation if data is trusted
|
|
722
|
+
maxDepth: 10 // Limit nesting depth
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
const parsed = await jsonParser.parse(jsonContent, optimizedOptions);
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### 3. Parallel Processing
|
|
729
|
+
|
|
730
|
+
```typescript
|
|
731
|
+
async function parallelProcessing(jsonArrays: string[]) {
|
|
732
|
+
const jsonParser = new JSONParserService();
|
|
733
|
+
|
|
734
|
+
// Process multiple JSON files in parallel
|
|
735
|
+
const promises = jsonArrays.map(async (json) => {
|
|
736
|
+
return await jsonParser.parse(json);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
const results = await Promise.all(promises);
|
|
740
|
+
return results;
|
|
741
|
+
}
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
## Key Takeaways
|
|
745
|
+
|
|
746
|
+
- 🎯 JSON Parser handles modern API responses and nested structures
|
|
747
|
+
- 🎯 Use JSONL format for streaming large datasets line-by-line
|
|
748
|
+
- 🎯 Extract nested data with `dataPath` option
|
|
749
|
+
- 🎯 Validate structure with schema validation
|
|
750
|
+
- 🎯 Parse dates automatically with `parseDates` option
|
|
751
|
+
- 🎯 Stream large files with `parseStreaming()` for memory efficiency
|
|
752
|
+
- 🎯 Combine with UniversalMapper for transformations
|
|
753
|
+
|
|
754
|
+
## Practice Exercise
|
|
755
|
+
|
|
756
|
+
**Challenge:** Parse this Shopify webhook and transform it for Fluent:
|
|
757
|
+
|
|
758
|
+
```json
|
|
759
|
+
{
|
|
760
|
+
"order": {
|
|
761
|
+
"id": 12345,
|
|
762
|
+
"email": "customer@example.com",
|
|
763
|
+
"created_at": "2025-01-15T10:30:00Z",
|
|
764
|
+
"line_items": [
|
|
765
|
+
{
|
|
766
|
+
"sku": "SKU001",
|
|
767
|
+
"quantity": 2,
|
|
768
|
+
"price": "29.99"
|
|
769
|
+
}
|
|
770
|
+
]
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**Requirements:**
|
|
776
|
+
1. Parse the JSON
|
|
777
|
+
2. Extract the order object
|
|
778
|
+
3. Transform to: `{ ref, customer: { email }, items: [{ ref, quantity, price }] }`
|
|
779
|
+
4. Parse the date and convert price to number
|
|
780
|
+
|
|
781
|
+
**Solution:** See [JSON Examples](../examples/json-parser-examples.ts)
|
|
782
|
+
|
|
783
|
+
## Next Steps
|
|
784
|
+
|
|
785
|
+
Continue to [Module 4: XML Parser →](./02-core-guides-parsers-04-xml-parser.md) to learn XML parsing and generation.
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
**Module 3 Complete!** ✅
|