@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.56
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/README.md +11 -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,1055 +1,1055 @@
|
|
|
1
|
-
# Module 8: API Reference
|
|
2
|
-
|
|
3
|
-
**Level:** Reference
|
|
4
|
-
**Estimated Time:** Reference material
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
Complete API reference for all file operation methods in S3DataSource and SftpDataSource.
|
|
9
|
-
|
|
10
|
-
## S3DataSource API
|
|
11
|
-
|
|
12
|
-
### Constructor
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
constructor(
|
|
16
|
-
config: {
|
|
17
|
-
s3Config: S3ClientConfig;
|
|
18
|
-
bucketName: string;
|
|
19
|
-
},
|
|
20
|
-
logger: Logger
|
|
21
|
-
)
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Parameters:**
|
|
25
|
-
|
|
26
|
-
- `s3Config`: AWS S3 client configuration
|
|
27
|
-
- `region`: AWS region (e.g., 'us-east-1')
|
|
28
|
-
- `credentials`: AWS credentials object
|
|
29
|
-
- `accessKeyId`: AWS access key ID
|
|
30
|
-
- `secretAccessKey`: AWS secret access key
|
|
31
|
-
- `bucketName`: S3 bucket name
|
|
32
|
-
- `logger`: Logger instance for logging
|
|
33
|
-
|
|
34
|
-
**Example:**
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
const s3 = new S3DataSource(
|
|
38
|
-
{
|
|
39
|
-
type: 'S3_CSV',
|
|
40
|
-
connectionId: 's3-api',
|
|
41
|
-
name: 'S3 API Example',
|
|
42
|
-
s3Config: {
|
|
43
|
-
region: 'us-east-1',
|
|
44
|
-
bucket: 'my-bucket',
|
|
45
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
46
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
logger
|
|
50
|
-
);
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### listFiles()
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
listFiles(params?: {
|
|
57
|
-
prefix?: string;
|
|
58
|
-
delimiter?: string;
|
|
59
|
-
maxKeys?: number;
|
|
60
|
-
continuationToken?: string;
|
|
61
|
-
}): Promise<FileMetadata[]>
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Parameters:**
|
|
65
|
-
|
|
66
|
-
- `params.prefix`: Filter files by key prefix (optional)
|
|
67
|
-
- `params.delimiter`: Delimiter for grouping keys (optional, e.g., '/' for folder structure)
|
|
68
|
-
- `params.maxKeys`: Maximum number of keys to return (optional, default: 1000)
|
|
69
|
-
- `params.continuationToken`: Token for pagination (optional, from previous response)
|
|
70
|
-
|
|
71
|
-
**Returns:** Array of FileMetadata objects (see [FileMetadata interface](#filemetadata))
|
|
72
|
-
|
|
73
|
-
**Example:**
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
// List all files
|
|
77
|
-
const allFiles = await s3.listFiles();
|
|
78
|
-
|
|
79
|
-
// List with prefix
|
|
80
|
-
const csvFiles = await s3.listFiles({ prefix: 'incoming/', maxKeys: 100 });
|
|
81
|
-
|
|
82
|
-
// List with pagination
|
|
83
|
-
const firstPage = await s3.listFiles({ prefix: 'data/', maxKeys: 100 });
|
|
84
|
-
// Use continuationToken from response metadata for next page
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### downloadFile()
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
downloadFile(
|
|
91
|
-
key: string,
|
|
92
|
-
options?: {
|
|
93
|
-
encoding?: 'utf8' | 'binary';
|
|
94
|
-
responseHeaders?: Record<string, string>;
|
|
95
|
-
}
|
|
96
|
-
): Promise<string | Buffer>
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**Parameters:**
|
|
100
|
-
|
|
101
|
-
- `key`: S3 object key (no leading slash)
|
|
102
|
-
- `options.encoding`: Return encoding ('utf8' for string, 'binary' for Buffer) (optional)
|
|
103
|
-
- `options.responseHeaders`: Custom response headers (optional)
|
|
104
|
-
|
|
105
|
-
**Returns:** File content as string (default) or Buffer (if encoding: 'binary')
|
|
106
|
-
|
|
107
|
-
**Throws:**
|
|
108
|
-
|
|
109
|
-
- `NoSuchKey`: If file doesn't exist
|
|
110
|
-
- `AccessDenied`: If no read permission
|
|
111
|
-
|
|
112
|
-
**Example:**
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
const content = await s3.downloadFile('data/orders.csv');
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### uploadFile()
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
uploadFile(
|
|
122
|
-
key: string,
|
|
123
|
-
content: string | Buffer,
|
|
124
|
-
options?: {
|
|
125
|
-
contentType?: string;
|
|
126
|
-
metadata?: Record<string, string>;
|
|
127
|
-
}
|
|
128
|
-
): Promise<void>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Parameters:**
|
|
132
|
-
|
|
133
|
-
- `key`: S3 object key (no leading slash)
|
|
134
|
-
- `content`: Content to upload (string or Buffer)
|
|
135
|
-
- `options.contentType`: MIME type of the content (optional, auto-detected if not provided)
|
|
136
|
-
- `options.metadata`: Custom metadata key-value pairs (optional)
|
|
137
|
-
|
|
138
|
-
**Returns:** Promise<void>
|
|
139
|
-
|
|
140
|
-
**Throws:**
|
|
141
|
-
|
|
142
|
-
- `AccessDenied`: If no write permission
|
|
143
|
-
|
|
144
|
-
**Example:**
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
await s3.uploadFile('output/results.json', JSON.stringify(data));
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### moveFile()
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
moveFile(
|
|
154
|
-
sourcePath: string,
|
|
155
|
-
destPath: string,
|
|
156
|
-
deleteSource: boolean = true
|
|
157
|
-
): Promise<void>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
**Parameters:**
|
|
161
|
-
|
|
162
|
-
- `sourcePath`: Source S3 key (no leading slash)
|
|
163
|
-
- `destPath`: Destination S3 key (no leading slash)
|
|
164
|
-
- `deleteSource`: Delete source file after copy (default: **true**)
|
|
165
|
-
|
|
166
|
-
**Returns:** Promise<void>
|
|
167
|
-
|
|
168
|
-
**Implementation:** Copies file to destination, then optionally deletes source (2 operations if deleteSource=true, 1 if false)
|
|
169
|
-
|
|
170
|
-
⚠️ **IMPORTANT:** `deleteSource` defaults to `true` - the source file WILL BE DELETED unless you explicitly pass `false`
|
|
171
|
-
|
|
172
|
-
**Throws:**
|
|
173
|
-
|
|
174
|
-
- `NoSuchKey`: If source file doesn't exist
|
|
175
|
-
- `AccessDenied`: If no copy or delete permission
|
|
176
|
-
|
|
177
|
-
**Example:**
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
// Move (copy + delete source) - DEFAULT BEHAVIOR
|
|
181
|
-
await s3.moveFile('incoming/data.csv', 'archive/data.csv');
|
|
182
|
-
|
|
183
|
-
// Copy without deleting source
|
|
184
|
-
await s3.moveFile('incoming/data.csv', 'archive/data.csv', false);
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### copyFile()
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
copyFile(
|
|
191
|
-
sourceKey: string,
|
|
192
|
-
destKey: string,
|
|
193
|
-
options?: {
|
|
194
|
-
sourceBucket?: string;
|
|
195
|
-
metadata?: Record<string, string>;
|
|
196
|
-
}
|
|
197
|
-
): Promise<void>
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Parameters:**
|
|
201
|
-
|
|
202
|
-
- `sourceKey`: Source S3 key (no leading slash)
|
|
203
|
-
- `destKey`: Destination S3 key (no leading slash)
|
|
204
|
-
- `options.sourceBucket`: Source bucket name (optional, defaults to same bucket)
|
|
205
|
-
- `options.metadata`: Custom metadata to apply to destination (optional)
|
|
206
|
-
|
|
207
|
-
**Returns:** Promise<void>
|
|
208
|
-
|
|
209
|
-
**Throws:**
|
|
210
|
-
|
|
211
|
-
- `NoSuchKey`: If source file doesn't exist
|
|
212
|
-
- `AccessDenied`: If no copy permission
|
|
213
|
-
|
|
214
|
-
**Example:**
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
// Copy within same bucket
|
|
218
|
-
await s3.copyFile('important/data.csv', 'backup/data.csv');
|
|
219
|
-
|
|
220
|
-
// Copy with metadata
|
|
221
|
-
await s3.copyFile('source/file.txt', 'dest/file.txt', {
|
|
222
|
-
metadata: { processedBy: 'sdk' }
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// Copy from different bucket
|
|
226
|
-
await s3.copyFile('source/file.txt', 'dest/file.txt', {
|
|
227
|
-
sourceBucket: 'other-bucket'
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### deleteFile()
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
deleteFile(key: string): Promise<void>
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
**Parameters:**
|
|
238
|
-
|
|
239
|
-
- `key`: S3 object key to delete
|
|
240
|
-
|
|
241
|
-
**Returns:** Promise<void>
|
|
242
|
-
|
|
243
|
-
**Throws:**
|
|
244
|
-
|
|
245
|
-
- `AccessDenied`: If no delete permission
|
|
246
|
-
|
|
247
|
-
**Note:** Does not throw if file doesn't exist (idempotent)
|
|
248
|
-
|
|
249
|
-
**Example:**
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
await s3.deleteFile('temp/old-file.csv');
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### fileExists()
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
fileExists(key: string): Promise<boolean>
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Parameters:**
|
|
262
|
-
|
|
263
|
-
- `key`: S3 object key to check
|
|
264
|
-
|
|
265
|
-
**Returns:** true if file exists, false otherwise
|
|
266
|
-
|
|
267
|
-
**Example:**
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
if (await s3.fileExists('config/settings.json')) {
|
|
271
|
-
const config = await s3.downloadFile('config/settings.json');
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### writeParquetContent()
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
writeParquetContent(
|
|
279
|
-
records: ParquetDataRecord[],
|
|
280
|
-
options?: {
|
|
281
|
-
compression?: 'UNCOMPRESSED' | 'GZIP' | 'SNAPPY' | 'LZO' | 'BROTLI';
|
|
282
|
-
schema?: Record<string, any>;
|
|
283
|
-
rowGroupSize?: number;
|
|
284
|
-
}
|
|
285
|
-
): Promise<Buffer>
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
**Parameters:**
|
|
289
|
-
|
|
290
|
-
- `records`: Array of data records
|
|
291
|
-
- `options`: Optional Parquet generation options
|
|
292
|
-
- `compression`: Compression algorithm (default: `'UNCOMPRESSED'`)
|
|
293
|
-
- `schema`: Explicit schema definition (default: auto-detected)
|
|
294
|
-
- `rowGroupSize`: Number of rows per row group (default: 5000)
|
|
295
|
-
|
|
296
|
-
**Returns:** Promise<Buffer> - Parquet file content as Buffer
|
|
297
|
-
|
|
298
|
-
**Example:**
|
|
299
|
-
|
|
300
|
-
```typescript
|
|
301
|
-
const records = [
|
|
302
|
-
{ sku: 'SKU-001', quantity: 10, price: 99.99 }
|
|
303
|
-
];
|
|
304
|
-
const parquetBuffer = await s3.writeParquetContent(records, {
|
|
305
|
-
compression: 'GZIP',
|
|
306
|
-
rowGroupSize: 5000
|
|
307
|
-
});
|
|
308
|
-
await s3.uploadFile('data/inventory.parquet', parquetBuffer);
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Handling Large Files
|
|
312
|
-
|
|
313
|
-
For large files (>100MB), use `downloadFile()` with `encoding: 'binary'` and process in chunks:
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
import { Buffer } from 'node:buffer';
|
|
317
|
-
|
|
318
|
-
// Download as Buffer (use encoding: 'binary' for S3)
|
|
319
|
-
const buffer = await s3.downloadFile('large-file.csv', { encoding: 'binary' });
|
|
320
|
-
|
|
321
|
-
// Process in chunks
|
|
322
|
-
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
323
|
-
for (let offset = 0; offset < buffer.length; offset += chunkSize) {
|
|
324
|
-
const chunk = buffer.slice(offset, offset + chunkSize);
|
|
325
|
-
processChunk(chunk.toString('utf8'));
|
|
326
|
-
}
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
**Note:** The SDK does not provide built-in streaming. See [Module 5: Streaming & Performance](./file-operations-05-streaming-performance.md) for advanced patterns.
|
|
330
|
-
|
|
331
|
-
## SftpDataSource API
|
|
332
|
-
|
|
333
|
-
### Constructor
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
constructor(
|
|
337
|
-
config: {
|
|
338
|
-
settings: SftpSettings;
|
|
339
|
-
},
|
|
340
|
-
logger: Logger
|
|
341
|
-
)
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
**Parameters:**
|
|
345
|
-
|
|
346
|
-
- `settings`: SFTP connection settings
|
|
347
|
-
- `host`: SFTP server hostname
|
|
348
|
-
- `port`: SFTP port (default: 22)
|
|
349
|
-
- `username`: SFTP username
|
|
350
|
-
- `password`: SFTP password (if password auth)
|
|
351
|
-
- `privateKey`: SSH private key (if key auth)
|
|
352
|
-
- `passphrase`: Private key passphrase (optional)
|
|
353
|
-
- `remotePath`: Base remote path
|
|
354
|
-
- `filePattern`: File pattern to match (e.g., '\*.csv')
|
|
355
|
-
- `connectTimeout`: Connection timeout in ms (optional)
|
|
356
|
-
- `logger`: Logger instance
|
|
357
|
-
|
|
358
|
-
**Example:**
|
|
359
|
-
|
|
360
|
-
```typescript
|
|
361
|
-
const sftp = new SftpDataSource(
|
|
362
|
-
{
|
|
363
|
-
type: 'SFTP_CSV',
|
|
364
|
-
connectionId: 'sftp-api',
|
|
365
|
-
name: 'SFTP API Example',
|
|
366
|
-
settings: {
|
|
367
|
-
host: 'sftp.example.com',
|
|
368
|
-
port: 22,
|
|
369
|
-
username: 'myuser',
|
|
370
|
-
password: process.env.SFTP_PASSWORD!,
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
logger
|
|
374
|
-
);
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
### listFiles()
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
listFiles(params?: {
|
|
381
|
-
lastProcessedTimestamp?: string;
|
|
382
|
-
fileName?: string;
|
|
383
|
-
remotePath?: string;
|
|
384
|
-
filePattern?: string;
|
|
385
|
-
}): Promise<FileMetadata[]>
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
**Parameters:**
|
|
389
|
-
|
|
390
|
-
- `params.lastProcessedTimestamp`: Filter files modified after this timestamp (optional)
|
|
391
|
-
- `params.fileName`: Filter by specific file name (optional)
|
|
392
|
-
- `params.remotePath`: Remote path to list (optional, uses constructor config if not provided)
|
|
393
|
-
- `params.filePattern`: File pattern to match (optional, uses constructor config if not provided)
|
|
394
|
-
|
|
395
|
-
**Returns:** Array of FileMetadata objects (see [FileMetadata interface](#filemetadata))
|
|
396
|
-
|
|
397
|
-
**Example:**
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
// List all files (uses constructor config)
|
|
401
|
-
const files = await sftp.listFiles();
|
|
402
|
-
|
|
403
|
-
// List files with custom path and pattern
|
|
404
|
-
const csvFiles = await sftp.listFiles({
|
|
405
|
-
remotePath: '/data/incoming',
|
|
406
|
-
filePattern: '*.csv'
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
// List files modified after specific timestamp
|
|
410
|
-
const recentFiles = await sftp.listFiles({
|
|
411
|
-
lastProcessedTimestamp: '2025-01-15T00:00:00Z'
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
files.forEach(f => console.log(f.path, f.source)); // path and source ('SFTP')
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
### downloadFile()
|
|
418
|
-
|
|
419
|
-
```typescript
|
|
420
|
-
downloadFile(path: string, options?: {
|
|
421
|
-
encoding?: string;
|
|
422
|
-
asBuffer?: boolean;
|
|
423
|
-
maxSize?: number;
|
|
424
|
-
}): Promise<string | Buffer>
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**Parameters:**
|
|
428
|
-
|
|
429
|
-
- `path`: Absolute remote path (with leading slash)
|
|
430
|
-
- `options.encoding`: Character encoding (default: 'utf8'). Supported: 'utf8', 'ascii', 'base64', 'hex', 'utf16le', 'latin1'
|
|
431
|
-
- `options.asBuffer`: Return as Buffer instead of string (default: false)
|
|
432
|
-
- `options.maxSize`: Maximum file size in bytes (optional, throws error if exceeded)
|
|
433
|
-
|
|
434
|
-
**Returns:** File content as string (default) or Buffer (if `asBuffer: true`)
|
|
435
|
-
|
|
436
|
-
**Throws:**
|
|
437
|
-
|
|
438
|
-
- Error with "No such file" if file doesn't exist
|
|
439
|
-
- Error with "Permission denied" if no read permission
|
|
440
|
-
- Error if file size exceeds `maxSize`
|
|
441
|
-
|
|
442
|
-
**Example:**
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
// Download as string (default)
|
|
446
|
-
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
447
|
-
|
|
448
|
-
// Download as Buffer
|
|
449
|
-
const buffer = await sftp.downloadFile('/data/incoming/orders.csv', { asBuffer: true });
|
|
450
|
-
|
|
451
|
-
// Download with size limit
|
|
452
|
-
const smallFile = await sftp.downloadFile('/config/settings.json', {
|
|
453
|
-
maxSize: 1024 * 1024 // 1MB max
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
// Download with specific encoding
|
|
457
|
-
const latin1Content = await sftp.downloadFile('/data/older-system.txt', {
|
|
458
|
-
encoding: 'latin1'
|
|
459
|
-
});
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### uploadFile()
|
|
463
|
-
|
|
464
|
-
```typescript
|
|
465
|
-
uploadFile(
|
|
466
|
-
remotePath: string,
|
|
467
|
-
content: string | Buffer,
|
|
468
|
-
options?: {
|
|
469
|
-
overwrite?: boolean;
|
|
470
|
-
createDirectories?: boolean;
|
|
471
|
-
permissions?: string;
|
|
472
|
-
encoding?: string;
|
|
473
|
-
}
|
|
474
|
-
): Promise<void>
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
**Parameters:**
|
|
478
|
-
|
|
479
|
-
- `remotePath`: Absolute remote path (with leading slash)
|
|
480
|
-
- `content`: Content to upload (string or Buffer)
|
|
481
|
-
- `options`: Optional upload parameters (default: all false/undefined)
|
|
482
|
-
- `overwrite`: Overwrite existing file (default: `false`)
|
|
483
|
-
- `false`: Throws `DataSourceError` if file already exists
|
|
484
|
-
- `true`: Replaces existing file without error
|
|
485
|
-
- `createDirectories`: Create parent directories if needed (default: `false`)
|
|
486
|
-
- `false`: Throws error if parent directory doesn't exist
|
|
487
|
-
- `true`: Creates all parent directories recursively
|
|
488
|
-
- `permissions`: File permissions in Unix octal notation (default: server default)
|
|
489
|
-
- Common values: `'0644'` (rw-r--r--), `'0755'` (rwxr-xr-x), `'0600'` (rw-------)
|
|
490
|
-
- `encoding`: Content encoding when `content` is string (default: `'utf8'`)
|
|
491
|
-
- Supported: `'utf8'`, `'ascii'`, `'base64'`, `'hex'`, `'utf16le'`, `'latin1'`
|
|
492
|
-
- Ignored when `content` is a Buffer
|
|
493
|
-
|
|
494
|
-
**Returns:** Promise<void>
|
|
495
|
-
|
|
496
|
-
**Throws:**
|
|
497
|
-
|
|
498
|
-
- `DataSourceError`: "Remote file already exists" when `overwrite: false` and file exists
|
|
499
|
-
- `DataSourceError`: "Permission denied" if no write permission
|
|
500
|
-
- `DataSourceError`: "No such file" if parent directory missing and `createDirectories: false`
|
|
501
|
-
- `DataSourceError`: Network/connection failures (auto-retried per retry config)
|
|
502
|
-
|
|
503
|
-
**Example:**
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
// Simple upload
|
|
507
|
-
await sftp.uploadFile('/data/outgoing/results.json', JSON.stringify(data));
|
|
508
|
-
|
|
509
|
-
// With options
|
|
510
|
-
await sftp.uploadFile('/data/outgoing/results.json', JSON.stringify(data), {
|
|
511
|
-
overwrite: true,
|
|
512
|
-
createDirectories: true,
|
|
513
|
-
permissions: '0644'
|
|
514
|
-
});
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
### moveFile()
|
|
518
|
-
|
|
519
|
-
```typescript
|
|
520
|
-
moveFile(
|
|
521
|
-
oldPath: string,
|
|
522
|
-
newPath: string,
|
|
523
|
-
overwrite: boolean = false
|
|
524
|
-
): Promise<void>
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
**Parameters:**
|
|
528
|
-
|
|
529
|
-
- `oldPath`: Absolute source path (with leading slash)
|
|
530
|
-
- `newPath`: Absolute destination path (with leading slash)
|
|
531
|
-
- `overwrite`: Overwrite destination if it exists (default: false)
|
|
532
|
-
|
|
533
|
-
**Returns:** Promise<void>
|
|
534
|
-
|
|
535
|
-
**Implementation:** Native SFTP rename operation (1 operation)
|
|
536
|
-
|
|
537
|
-
**Throws:**
|
|
538
|
-
|
|
539
|
-
- Error with "No such file" if source doesn't exist
|
|
540
|
-
- Error with "Permission denied" if no rename permission
|
|
541
|
-
- Error if destination exists and `overwrite: false`
|
|
542
|
-
|
|
543
|
-
**Example:**
|
|
544
|
-
|
|
545
|
-
```typescript
|
|
546
|
-
// Simple move
|
|
547
|
-
await sftp.moveFile('/data/incoming/orders.csv', '/data/processed/orders.csv');
|
|
548
|
-
|
|
549
|
-
// Move with overwrite
|
|
550
|
-
await sftp.moveFile(
|
|
551
|
-
'/data/incoming/orders.csv',
|
|
552
|
-
'/archive/orders.csv',
|
|
553
|
-
true // Overwrite if exists
|
|
554
|
-
);
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
### copyFile()
|
|
558
|
-
|
|
559
|
-
```typescript
|
|
560
|
-
copyFile(
|
|
561
|
-
sourcePath: string,
|
|
562
|
-
destPath: string,
|
|
563
|
-
overwrite: boolean = false
|
|
564
|
-
): Promise<void>
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
**Parameters:**
|
|
568
|
-
|
|
569
|
-
- `sourcePath`: Absolute source path (with leading slash)
|
|
570
|
-
- `destPath`: Absolute destination path (with leading slash)
|
|
571
|
-
- `overwrite`: Overwrite destination if it exists (default: false)
|
|
572
|
-
|
|
573
|
-
**Returns:** Promise<void>
|
|
574
|
-
|
|
575
|
-
**Throws:**
|
|
576
|
-
|
|
577
|
-
- Error with "No such file" if source doesn't exist
|
|
578
|
-
- Error with "Permission denied" if no read/write permission
|
|
579
|
-
- Error if destination exists and `overwrite: false`
|
|
580
|
-
|
|
581
|
-
**Example:**
|
|
582
|
-
|
|
583
|
-
```typescript
|
|
584
|
-
// Simple copy
|
|
585
|
-
await sftp.copyFile('/data/important/config.json', '/backup/config.json');
|
|
586
|
-
|
|
587
|
-
// Copy with overwrite
|
|
588
|
-
await sftp.copyFile(
|
|
589
|
-
'/data/important/config.json',
|
|
590
|
-
'/backup/config.json',
|
|
591
|
-
true // Overwrite if exists
|
|
592
|
-
);
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
### deleteFile()
|
|
596
|
-
|
|
597
|
-
```typescript
|
|
598
|
-
deleteFile(remotePath: string): Promise<void>
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
**Parameters:**
|
|
602
|
-
|
|
603
|
-
- `remotePath`: Absolute remote path (with leading slash)
|
|
604
|
-
|
|
605
|
-
**Returns:** Promise<void>
|
|
606
|
-
|
|
607
|
-
**Throws:**
|
|
608
|
-
|
|
609
|
-
- Error with "No such file" if file doesn't exist
|
|
610
|
-
- Error with "Permission denied" if no delete permission
|
|
611
|
-
|
|
612
|
-
**Example:**
|
|
613
|
-
|
|
614
|
-
```typescript
|
|
615
|
-
await sftp.deleteFile('/data/temp/old-file.csv');
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
### fileExists()
|
|
619
|
-
|
|
620
|
-
```typescript
|
|
621
|
-
fileExists(remotePath: string): Promise<boolean>
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
**Parameters:**
|
|
625
|
-
|
|
626
|
-
- `remotePath`: Absolute remote path (with leading slash)
|
|
627
|
-
|
|
628
|
-
**Returns:** true if file exists, false otherwise
|
|
629
|
-
|
|
630
|
-
**Example:**
|
|
631
|
-
|
|
632
|
-
```typescript
|
|
633
|
-
if (await sftp.fileExists('/data/incoming/orders.csv')) {
|
|
634
|
-
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
635
|
-
}
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### createDirectory()
|
|
639
|
-
|
|
640
|
-
```typescript
|
|
641
|
-
createDirectory(
|
|
642
|
-
remotePath: string,
|
|
643
|
-
recursive: boolean = false,
|
|
644
|
-
permissions?: string
|
|
645
|
-
): Promise<void>
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
**Parameters:**
|
|
649
|
-
|
|
650
|
-
- `remotePath`: Absolute remote directory path (with leading slash)
|
|
651
|
-
- `recursive`: Create parent directories if they don't exist (default: `false`)
|
|
652
|
-
- `permissions`: Optional directory permissions in Unix octal notation (e.g., `'0755'`)
|
|
653
|
-
|
|
654
|
-
**Returns:** Promise<void>
|
|
655
|
-
|
|
656
|
-
**Throws:**
|
|
657
|
-
|
|
658
|
-
- `DataSourceError`: "Permission denied" if no write permission
|
|
659
|
-
- `DataSourceError`: "No such file" if parent directory missing and `recursive: false`
|
|
660
|
-
|
|
661
|
-
**Example:**
|
|
662
|
-
|
|
663
|
-
```typescript
|
|
664
|
-
// Create single directory
|
|
665
|
-
await sftp.createDirectory('/data/incoming');
|
|
666
|
-
|
|
667
|
-
// Create recursively
|
|
668
|
-
await sftp.createDirectory('/data/archive/2025/01/15', true);
|
|
669
|
-
|
|
670
|
-
// Create with permissions
|
|
671
|
-
await sftp.createDirectory('/data/public', true, '0755');
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
### directoryExists()
|
|
675
|
-
|
|
676
|
-
```typescript
|
|
677
|
-
directoryExists(remotePath: string): Promise<boolean>
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
**Parameters:**
|
|
681
|
-
|
|
682
|
-
- `remotePath`: Absolute remote directory path (with leading slash)
|
|
683
|
-
|
|
684
|
-
**Returns:** true if directory exists, false otherwise
|
|
685
|
-
|
|
686
|
-
**Example:**
|
|
687
|
-
|
|
688
|
-
```typescript
|
|
689
|
-
if (!(await sftp.directoryExists('/data/incoming'))) {
|
|
690
|
-
await sftp.createDirectory('/data/incoming', true);
|
|
691
|
-
}
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
### parseCsvContent()
|
|
695
|
-
|
|
696
|
-
```typescript
|
|
697
|
-
parseCsvContent(
|
|
698
|
-
csvContent: string,
|
|
699
|
-
fileMetadata: FileMetadata
|
|
700
|
-
): CsvRecord[]
|
|
701
|
-
```
|
|
702
|
-
|
|
703
|
-
**Parameters:**
|
|
704
|
-
|
|
705
|
-
- `csvContent`: CSV content as string
|
|
706
|
-
- `fileMetadata`: File metadata for context (includes path, name, size, source)
|
|
707
|
-
|
|
708
|
-
**Returns:** Array of parsed CSV records (objects with column names as keys)
|
|
709
|
-
|
|
710
|
-
**Example:**
|
|
711
|
-
|
|
712
|
-
```typescript
|
|
713
|
-
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
714
|
-
const records = sftp.parseCsvContent(content as string, {
|
|
715
|
-
path: '/data/incoming/orders.csv',
|
|
716
|
-
name: 'orders.csv',
|
|
717
|
-
size: content.length,
|
|
718
|
-
source: 'SFTP'
|
|
719
|
-
});
|
|
720
|
-
```
|
|
721
|
-
|
|
722
|
-
### parseJsonContent()
|
|
723
|
-
|
|
724
|
-
```typescript
|
|
725
|
-
parseJsonContent(
|
|
726
|
-
jsonContent: string,
|
|
727
|
-
fileMetadata: FileMetadata,
|
|
728
|
-
options?: {
|
|
729
|
-
format?: 'json' | 'jsonl';
|
|
730
|
-
validate?: boolean;
|
|
731
|
-
maxDepth?: number;
|
|
732
|
-
}
|
|
733
|
-
): Record<string, unknown>[]
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
**Parameters:**
|
|
737
|
-
|
|
738
|
-
- `jsonContent`: JSON content as string
|
|
739
|
-
- `fileMetadata`: File metadata for context
|
|
740
|
-
- `options`: Optional parsing options
|
|
741
|
-
- `format`: `'json'` for JSON array or `'jsonl'` for JSON Lines (default: auto-detect)
|
|
742
|
-
- `validate`: Throw error on invalid JSON (default: `false`)
|
|
743
|
-
- `maxDepth`: Limit nesting depth (default: unlimited)
|
|
744
|
-
|
|
745
|
-
**Returns:** Array of parsed JSON objects
|
|
746
|
-
|
|
747
|
-
**Example:**
|
|
748
|
-
|
|
749
|
-
```typescript
|
|
750
|
-
const content = await sftp.downloadFile('/data/incoming/orders.json');
|
|
751
|
-
const records = sftp.parseJsonContent(content as string, {
|
|
752
|
-
path: '/data/incoming/orders.json',
|
|
753
|
-
name: 'orders.json',
|
|
754
|
-
size: content.length,
|
|
755
|
-
source: 'SFTP'
|
|
756
|
-
}, {
|
|
757
|
-
format: 'json',
|
|
758
|
-
validate: true,
|
|
759
|
-
maxDepth: 10
|
|
760
|
-
});
|
|
761
|
-
```
|
|
762
|
-
|
|
763
|
-
### writeCsvContent()
|
|
764
|
-
|
|
765
|
-
```typescript
|
|
766
|
-
writeCsvContent(
|
|
767
|
-
records: Record<string, any>[],
|
|
768
|
-
options?: {
|
|
769
|
-
headers?: string[];
|
|
770
|
-
delimiter?: string;
|
|
771
|
-
includeHeaders?: boolean;
|
|
772
|
-
}
|
|
773
|
-
): string
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
**Parameters:**
|
|
777
|
-
|
|
778
|
-
- `records`: Array of objects to convert to CSV
|
|
779
|
-
- `options`: Optional CSV generation options
|
|
780
|
-
- `headers`: Column names (default: inferred from first record)
|
|
781
|
-
- `delimiter`: Field delimiter (default: `','`)
|
|
782
|
-
- `includeHeaders`: Include header row (default: `true`)
|
|
783
|
-
|
|
784
|
-
**Returns:** CSV content as string
|
|
785
|
-
|
|
786
|
-
**Example:**
|
|
787
|
-
|
|
788
|
-
```typescript
|
|
789
|
-
const records = [
|
|
790
|
-
{ sku: 'SKU-001', quantity: 10 },
|
|
791
|
-
{ sku: 'SKU-002', quantity: 25 }
|
|
792
|
-
];
|
|
793
|
-
const csv = sftp.writeCsvContent(records, {
|
|
794
|
-
headers: ['sku', 'quantity'],
|
|
795
|
-
delimiter: ',',
|
|
796
|
-
includeHeaders: true
|
|
797
|
-
});
|
|
798
|
-
await sftp.uploadFile('/data/outgoing/inventory.csv', csv);
|
|
799
|
-
```
|
|
800
|
-
|
|
801
|
-
### writeJsonContent()
|
|
802
|
-
|
|
803
|
-
```typescript
|
|
804
|
-
writeJsonContent(
|
|
805
|
-
records: Record<string, any>[],
|
|
806
|
-
options?: {
|
|
807
|
-
format?: 'json' | 'jsonl';
|
|
808
|
-
pretty?: boolean;
|
|
809
|
-
}
|
|
810
|
-
): string
|
|
811
|
-
```
|
|
812
|
-
|
|
813
|
-
**Parameters:**
|
|
814
|
-
|
|
815
|
-
- `records`: Array of objects to convert to JSON
|
|
816
|
-
- `options`: Optional JSON generation options
|
|
817
|
-
- `format`: `'json'` for JSON array or `'jsonl'` for JSON Lines (default: `'json'`)
|
|
818
|
-
- `pretty`: Pretty-print JSON (default: `false`)
|
|
819
|
-
|
|
820
|
-
**Returns:** JSON content as string
|
|
821
|
-
|
|
822
|
-
**Example:**
|
|
823
|
-
|
|
824
|
-
```typescript
|
|
825
|
-
const orders = [{ id: 'ORD-001', total: 99.99 }];
|
|
826
|
-
const json = sftp.writeJsonContent(orders, {
|
|
827
|
-
format: 'json',
|
|
828
|
-
pretty: true
|
|
829
|
-
});
|
|
830
|
-
await sftp.uploadFile('/data/outgoing/orders.json', json);
|
|
831
|
-
```
|
|
832
|
-
|
|
833
|
-
### writeParquetContent()
|
|
834
|
-
|
|
835
|
-
```typescript
|
|
836
|
-
writeParquetContent(
|
|
837
|
-
records: ParquetDataRecord[],
|
|
838
|
-
options?: {
|
|
839
|
-
compression?: 'UNCOMPRESSED' | 'GZIP' | 'SNAPPY' | 'LZO' | 'BROTLI';
|
|
840
|
-
schema?: Record<string, any>;
|
|
841
|
-
rowGroupSize?: number;
|
|
842
|
-
}
|
|
843
|
-
): Promise<Buffer>
|
|
844
|
-
```
|
|
845
|
-
|
|
846
|
-
**Parameters:**
|
|
847
|
-
|
|
848
|
-
- `records`: Array of data records
|
|
849
|
-
- `options`: Optional Parquet generation options
|
|
850
|
-
- `compression`: Compression algorithm (default: `'UNCOMPRESSED'`)
|
|
851
|
-
- `schema`: Explicit schema definition (default: auto-detected)
|
|
852
|
-
- `rowGroupSize`: Number of rows per row group (default: 5000)
|
|
853
|
-
|
|
854
|
-
**Returns:** Promise<Buffer> - Parquet file content as Buffer
|
|
855
|
-
|
|
856
|
-
**Example:**
|
|
857
|
-
|
|
858
|
-
```typescript
|
|
859
|
-
const records = [
|
|
860
|
-
{ sku: 'SKU-001', quantity: 10, price: 99.99 }
|
|
861
|
-
];
|
|
862
|
-
const parquetBuffer = await sftp.writeParquetContent(records, {
|
|
863
|
-
compression: 'GZIP',
|
|
864
|
-
rowGroupSize: 5000
|
|
865
|
-
});
|
|
866
|
-
await sftp.uploadFile('/data/outgoing/inventory.parquet', parquetBuffer);
|
|
867
|
-
```
|
|
868
|
-
|
|
869
|
-
### Handling Large Files
|
|
870
|
-
|
|
871
|
-
For large files (>100MB), use `downloadFile()` with `asBuffer: true` and `maxSize` option:
|
|
872
|
-
|
|
873
|
-
```typescript
|
|
874
|
-
import { Buffer } from 'node:buffer';
|
|
875
|
-
|
|
876
|
-
// Download as Buffer with size limit
|
|
877
|
-
const buffer = await sftp.downloadFile('/data/large-file.csv', {
|
|
878
|
-
asBuffer: true,
|
|
879
|
-
maxSize: 100 * 1024 * 1024 // 100 MB limit
|
|
880
|
-
});
|
|
881
|
-
|
|
882
|
-
// Process in chunks
|
|
883
|
-
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
884
|
-
for (let offset = 0; offset < buffer.length; offset += chunkSize) {
|
|
885
|
-
const chunk = buffer.slice(offset, offset + chunkSize);
|
|
886
|
-
processChunk(chunk.toString('utf8'));
|
|
887
|
-
}
|
|
888
|
-
```
|
|
889
|
-
|
|
890
|
-
**Note:** The SDK does not provide built-in streaming. See [Module 5: Streaming & Performance](./file-operations-05-streaming-performance.md) for advanced patterns.
|
|
891
|
-
|
|
892
|
-
### dispose()
|
|
893
|
-
|
|
894
|
-
```typescript
|
|
895
|
-
dispose(): Promise<void>
|
|
896
|
-
```
|
|
897
|
-
|
|
898
|
-
**Parameters:** None
|
|
899
|
-
|
|
900
|
-
**Returns:** Promise<void>
|
|
901
|
-
|
|
902
|
-
**Purpose:** Close SFTP connection and free resources
|
|
903
|
-
|
|
904
|
-
**CRITICAL:** Always call in `finally` block
|
|
905
|
-
|
|
906
|
-
**Example:**
|
|
907
|
-
|
|
908
|
-
```typescript
|
|
909
|
-
const sftp = new SftpDataSource(config, logger);
|
|
910
|
-
try {
|
|
911
|
-
await sftp.listFiles();
|
|
912
|
-
} finally {
|
|
913
|
-
await sftp.dispose(); // REQUIRED!
|
|
914
|
-
}
|
|
915
|
-
```
|
|
916
|
-
|
|
917
|
-
## Common Types
|
|
918
|
-
|
|
919
|
-
### FileMetadata
|
|
920
|
-
|
|
921
|
-
```typescript
|
|
922
|
-
interface FileMetadata {
|
|
923
|
-
path: string; // REQUIRED: Full file path/key
|
|
924
|
-
name: string; // REQUIRED: File name
|
|
925
|
-
size?: number; // File size in bytes (optional)
|
|
926
|
-
lastModified?: string; // ISO 8601 timestamp string (NOT Date object!)
|
|
927
|
-
contentType?: string; // MIME type (optional, S3 only)
|
|
928
|
-
source: string; // REQUIRED: Data source type ('S3' or 'SFTP')
|
|
929
|
-
etag?: string; // S3 ETag (optional, S3 only)
|
|
930
|
-
bucket?: string; // S3 bucket name (optional, S3 only)
|
|
931
|
-
region?: string; // S3 region (optional, S3 only)
|
|
932
|
-
}
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
**Key Points:**
|
|
936
|
-
|
|
937
|
-
- ✅ `path` is REQUIRED (not optional!)
|
|
938
|
-
- ✅ `lastModified` is an ISO string, NOT a Date object
|
|
939
|
-
- ✅ `source` indicates the data source type ('S3' or 'SFTP')
|
|
940
|
-
- ✅ S3-specific fields: `contentType`, `etag`, `bucket`, `region`
|
|
941
|
-
|
|
942
|
-
**Example Usage:**
|
|
943
|
-
|
|
944
|
-
```typescript
|
|
945
|
-
const files: FileMetadata[] = await dataSource.listFiles();
|
|
946
|
-
|
|
947
|
-
files.forEach(file => {
|
|
948
|
-
console.log(`File: ${file.name}`);
|
|
949
|
-
console.log(`Path: ${file.path}`);
|
|
950
|
-
console.log(`Source: ${file.source}`); // 'S3' or 'SFTP'
|
|
951
|
-
console.log(`Modified: ${file.lastModified}`); // ISO string
|
|
952
|
-
if (file.contentType) {
|
|
953
|
-
console.log(`Type: ${file.contentType}`); // S3 only
|
|
954
|
-
}
|
|
955
|
-
});
|
|
956
|
-
```
|
|
957
|
-
|
|
958
|
-
### Logger
|
|
959
|
-
|
|
960
|
-
```typescript
|
|
961
|
-
interface Logger {
|
|
962
|
-
debug(message: string, meta?: any): void;
|
|
963
|
-
info(message: string, meta?: any): void;
|
|
964
|
-
warn(message: string, meta?: any): void;
|
|
965
|
-
error(message: string, error?: Error, meta?: any): void;
|
|
966
|
-
}
|
|
967
|
-
```
|
|
968
|
-
|
|
969
|
-
**Note:** Use `createConsoleLogger()` or `toStructuredLogger()` from the SDK to create Logger instances. See [Logging Guide](../../../02-CORE-GUIDES/logging-guide.md) for details.
|
|
970
|
-
|
|
971
|
-
## Key Differences: S3 vs SFTP
|
|
972
|
-
|
|
973
|
-
| Feature | S3DataSource | SftpDataSource |
|
|
974
|
-
| ----------------------- | ------------------------------------- | ----------------------------------------------- |
|
|
975
|
-
| **Path Format** | No leading slash: `folder/file.csv` | Leading slash: `/folder/file.csv` |
|
|
976
|
-
| **List Method** | `listFiles({ prefix?, delimiter?, maxKeys?, continuationToken? })` | `listFiles({ lastProcessedTimestamp?, fileName?, remotePath?, filePattern? })` |
|
|
977
|
-
| **Upload Signature** | `uploadFile(key, content, options?)` | `uploadFile(remotePath, content, options?)` |
|
|
978
|
-
| **Move Signature** | `moveFile(sourcePath, destPath, deleteSource?)` | `moveFile(oldPath, newPath, overwrite?)` |
|
|
979
|
-
| **Move Implementation** | Copy + Delete (2 ops) | Native rename (1 op) |
|
|
980
|
-
| **Directory Creation** | Automatic | Optional (`createDirectories` flag) |
|
|
981
|
-
| **Connection** | Stateless (per-request) | Stateful (must dispose) |
|
|
982
|
-
| **Cleanup** | Not needed | **Required** (`dispose()`) |
|
|
983
|
-
|
|
984
|
-
## Best Practices
|
|
985
|
-
|
|
986
|
-
### S3 Best Practices
|
|
987
|
-
|
|
988
|
-
```typescript
|
|
989
|
-
// ✅ Use meaningful prefixes
|
|
990
|
-
await s3.listFiles({ prefix: 'incoming/orders/' });
|
|
991
|
-
|
|
992
|
-
// ✅ Use maxKeys for pagination control
|
|
993
|
-
await s3.listFiles({ prefix: 'data/', maxKeys: 100 });
|
|
994
|
-
|
|
995
|
-
// ✅ Check existence before operations
|
|
996
|
-
if (await s3.fileExists('file.csv')) {
|
|
997
|
-
await s3.downloadFile('file.csv');
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// ✅ Use chunked processing for large files
|
|
1001
|
-
if (fileSize > 100 * 1024 * 1024) {
|
|
1002
|
-
// >100MB: Download as Buffer and process in chunks
|
|
1003
|
-
import { Buffer } from 'node:buffer';
|
|
1004
|
-
const buffer = await s3.downloadFile('large-file.csv', { encoding: 'binary' });
|
|
1005
|
-
// Process buffer in chunks (see Module 5 for patterns)
|
|
1006
|
-
}
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
### SFTP Best Practices
|
|
1010
|
-
|
|
1011
|
-
```typescript
|
|
1012
|
-
// ✅ Always use try/finally with dispose
|
|
1013
|
-
try {
|
|
1014
|
-
const files = await sftp.listFiles();
|
|
1015
|
-
// ... process files
|
|
1016
|
-
} finally {
|
|
1017
|
-
await sftp.dispose(); // CRITICAL!
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
// ✅ Use absolute paths
|
|
1021
|
-
await sftp.downloadFile('/data/file.csv'); // ✅
|
|
1022
|
-
// NOT: await sftp.downloadFile('data/file.csv'); // ❌
|
|
1023
|
-
|
|
1024
|
-
// ✅ Use createDirectories flag when necessary
|
|
1025
|
-
await sftp.moveFile(
|
|
1026
|
-
'/source/file.csv',
|
|
1027
|
-
'/archive/2025/01/file.csv',
|
|
1028
|
-
true // Create /archive/2025/01/ if it doesn't exist
|
|
1029
|
-
);
|
|
1030
|
-
|
|
1031
|
-
// ✅ Reuse connection for multiple operations
|
|
1032
|
-
try {
|
|
1033
|
-
for (const file of files) {
|
|
1034
|
-
await sftp.downloadFile(file.path);
|
|
1035
|
-
}
|
|
1036
|
-
} finally {
|
|
1037
|
-
await sftp.dispose(); // Once at the end
|
|
1038
|
-
}
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
|
-
## See Also
|
|
1042
|
-
|
|
1043
|
-
- [Module 1: Foundations](./file-operations-01-foundations.md) - Core concepts
|
|
1044
|
-
- [Module 2: Quick Start](./file-operations-02-quick-start.md) - Working examples
|
|
1045
|
-
- [Module 3: S3 Operations](./file-operations-03-s3-operations.md) - S3 deep dive
|
|
1046
|
-
- [Module 4: SFTP Operations](./file-operations-04-sftp-operations.md) - SFTP deep dive
|
|
1047
|
-
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Cheat sheet
|
|
1048
|
-
|
|
1049
|
-
---
|
|
1050
|
-
|
|
1051
|
-
**Need Help?**
|
|
1052
|
-
|
|
1053
|
-
- 📖 Browse [Examples](../examples/)
|
|
1054
|
-
- 🔍 Check [Troubleshooting](./file-operations-07-testing-troubleshooting.md)
|
|
1055
|
-
- 📧 Contact support@fluentcommerce.com
|
|
1
|
+
# Module 8: API Reference
|
|
2
|
+
|
|
3
|
+
**Level:** Reference
|
|
4
|
+
**Estimated Time:** Reference material
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Complete API reference for all file operation methods in S3DataSource and SftpDataSource.
|
|
9
|
+
|
|
10
|
+
## S3DataSource API
|
|
11
|
+
|
|
12
|
+
### Constructor
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
constructor(
|
|
16
|
+
config: {
|
|
17
|
+
s3Config: S3ClientConfig;
|
|
18
|
+
bucketName: string;
|
|
19
|
+
},
|
|
20
|
+
logger: Logger
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Parameters:**
|
|
25
|
+
|
|
26
|
+
- `s3Config`: AWS S3 client configuration
|
|
27
|
+
- `region`: AWS region (e.g., 'us-east-1')
|
|
28
|
+
- `credentials`: AWS credentials object
|
|
29
|
+
- `accessKeyId`: AWS access key ID
|
|
30
|
+
- `secretAccessKey`: AWS secret access key
|
|
31
|
+
- `bucketName`: S3 bucket name
|
|
32
|
+
- `logger`: Logger instance for logging
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const s3 = new S3DataSource(
|
|
38
|
+
{
|
|
39
|
+
type: 'S3_CSV',
|
|
40
|
+
connectionId: 's3-api',
|
|
41
|
+
name: 'S3 API Example',
|
|
42
|
+
s3Config: {
|
|
43
|
+
region: 'us-east-1',
|
|
44
|
+
bucket: 'my-bucket',
|
|
45
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
46
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
logger
|
|
50
|
+
);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### listFiles()
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
listFiles(params?: {
|
|
57
|
+
prefix?: string;
|
|
58
|
+
delimiter?: string;
|
|
59
|
+
maxKeys?: number;
|
|
60
|
+
continuationToken?: string;
|
|
61
|
+
}): Promise<FileMetadata[]>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Parameters:**
|
|
65
|
+
|
|
66
|
+
- `params.prefix`: Filter files by key prefix (optional)
|
|
67
|
+
- `params.delimiter`: Delimiter for grouping keys (optional, e.g., '/' for folder structure)
|
|
68
|
+
- `params.maxKeys`: Maximum number of keys to return (optional, default: 1000)
|
|
69
|
+
- `params.continuationToken`: Token for pagination (optional, from previous response)
|
|
70
|
+
|
|
71
|
+
**Returns:** Array of FileMetadata objects (see [FileMetadata interface](#filemetadata))
|
|
72
|
+
|
|
73
|
+
**Example:**
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// List all files
|
|
77
|
+
const allFiles = await s3.listFiles();
|
|
78
|
+
|
|
79
|
+
// List with prefix
|
|
80
|
+
const csvFiles = await s3.listFiles({ prefix: 'incoming/', maxKeys: 100 });
|
|
81
|
+
|
|
82
|
+
// List with pagination
|
|
83
|
+
const firstPage = await s3.listFiles({ prefix: 'data/', maxKeys: 100 });
|
|
84
|
+
// Use continuationToken from response metadata for next page
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### downloadFile()
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
downloadFile(
|
|
91
|
+
key: string,
|
|
92
|
+
options?: {
|
|
93
|
+
encoding?: 'utf8' | 'binary';
|
|
94
|
+
responseHeaders?: Record<string, string>;
|
|
95
|
+
}
|
|
96
|
+
): Promise<string | Buffer>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Parameters:**
|
|
100
|
+
|
|
101
|
+
- `key`: S3 object key (no leading slash)
|
|
102
|
+
- `options.encoding`: Return encoding ('utf8' for string, 'binary' for Buffer) (optional)
|
|
103
|
+
- `options.responseHeaders`: Custom response headers (optional)
|
|
104
|
+
|
|
105
|
+
**Returns:** File content as string (default) or Buffer (if encoding: 'binary')
|
|
106
|
+
|
|
107
|
+
**Throws:**
|
|
108
|
+
|
|
109
|
+
- `NoSuchKey`: If file doesn't exist
|
|
110
|
+
- `AccessDenied`: If no read permission
|
|
111
|
+
|
|
112
|
+
**Example:**
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const content = await s3.downloadFile('data/orders.csv');
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### uploadFile()
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
uploadFile(
|
|
122
|
+
key: string,
|
|
123
|
+
content: string | Buffer,
|
|
124
|
+
options?: {
|
|
125
|
+
contentType?: string;
|
|
126
|
+
metadata?: Record<string, string>;
|
|
127
|
+
}
|
|
128
|
+
): Promise<void>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Parameters:**
|
|
132
|
+
|
|
133
|
+
- `key`: S3 object key (no leading slash)
|
|
134
|
+
- `content`: Content to upload (string or Buffer)
|
|
135
|
+
- `options.contentType`: MIME type of the content (optional, auto-detected if not provided)
|
|
136
|
+
- `options.metadata`: Custom metadata key-value pairs (optional)
|
|
137
|
+
|
|
138
|
+
**Returns:** Promise<void>
|
|
139
|
+
|
|
140
|
+
**Throws:**
|
|
141
|
+
|
|
142
|
+
- `AccessDenied`: If no write permission
|
|
143
|
+
|
|
144
|
+
**Example:**
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
await s3.uploadFile('output/results.json', JSON.stringify(data));
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### moveFile()
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
moveFile(
|
|
154
|
+
sourcePath: string,
|
|
155
|
+
destPath: string,
|
|
156
|
+
deleteSource: boolean = true
|
|
157
|
+
): Promise<void>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Parameters:**
|
|
161
|
+
|
|
162
|
+
- `sourcePath`: Source S3 key (no leading slash)
|
|
163
|
+
- `destPath`: Destination S3 key (no leading slash)
|
|
164
|
+
- `deleteSource`: Delete source file after copy (default: **true**)
|
|
165
|
+
|
|
166
|
+
**Returns:** Promise<void>
|
|
167
|
+
|
|
168
|
+
**Implementation:** Copies file to destination, then optionally deletes source (2 operations if deleteSource=true, 1 if false)
|
|
169
|
+
|
|
170
|
+
⚠️ **IMPORTANT:** `deleteSource` defaults to `true` - the source file WILL BE DELETED unless you explicitly pass `false`
|
|
171
|
+
|
|
172
|
+
**Throws:**
|
|
173
|
+
|
|
174
|
+
- `NoSuchKey`: If source file doesn't exist
|
|
175
|
+
- `AccessDenied`: If no copy or delete permission
|
|
176
|
+
|
|
177
|
+
**Example:**
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// Move (copy + delete source) - DEFAULT BEHAVIOR
|
|
181
|
+
await s3.moveFile('incoming/data.csv', 'archive/data.csv');
|
|
182
|
+
|
|
183
|
+
// Copy without deleting source
|
|
184
|
+
await s3.moveFile('incoming/data.csv', 'archive/data.csv', false);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### copyFile()
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
copyFile(
|
|
191
|
+
sourceKey: string,
|
|
192
|
+
destKey: string,
|
|
193
|
+
options?: {
|
|
194
|
+
sourceBucket?: string;
|
|
195
|
+
metadata?: Record<string, string>;
|
|
196
|
+
}
|
|
197
|
+
): Promise<void>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Parameters:**
|
|
201
|
+
|
|
202
|
+
- `sourceKey`: Source S3 key (no leading slash)
|
|
203
|
+
- `destKey`: Destination S3 key (no leading slash)
|
|
204
|
+
- `options.sourceBucket`: Source bucket name (optional, defaults to same bucket)
|
|
205
|
+
- `options.metadata`: Custom metadata to apply to destination (optional)
|
|
206
|
+
|
|
207
|
+
**Returns:** Promise<void>
|
|
208
|
+
|
|
209
|
+
**Throws:**
|
|
210
|
+
|
|
211
|
+
- `NoSuchKey`: If source file doesn't exist
|
|
212
|
+
- `AccessDenied`: If no copy permission
|
|
213
|
+
|
|
214
|
+
**Example:**
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// Copy within same bucket
|
|
218
|
+
await s3.copyFile('important/data.csv', 'backup/data.csv');
|
|
219
|
+
|
|
220
|
+
// Copy with metadata
|
|
221
|
+
await s3.copyFile('source/file.txt', 'dest/file.txt', {
|
|
222
|
+
metadata: { processedBy: 'sdk' }
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Copy from different bucket
|
|
226
|
+
await s3.copyFile('source/file.txt', 'dest/file.txt', {
|
|
227
|
+
sourceBucket: 'other-bucket'
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### deleteFile()
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
deleteFile(key: string): Promise<void>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Parameters:**
|
|
238
|
+
|
|
239
|
+
- `key`: S3 object key to delete
|
|
240
|
+
|
|
241
|
+
**Returns:** Promise<void>
|
|
242
|
+
|
|
243
|
+
**Throws:**
|
|
244
|
+
|
|
245
|
+
- `AccessDenied`: If no delete permission
|
|
246
|
+
|
|
247
|
+
**Note:** Does not throw if file doesn't exist (idempotent)
|
|
248
|
+
|
|
249
|
+
**Example:**
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
await s3.deleteFile('temp/old-file.csv');
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### fileExists()
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
fileExists(key: string): Promise<boolean>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Parameters:**
|
|
262
|
+
|
|
263
|
+
- `key`: S3 object key to check
|
|
264
|
+
|
|
265
|
+
**Returns:** true if file exists, false otherwise
|
|
266
|
+
|
|
267
|
+
**Example:**
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
if (await s3.fileExists('config/settings.json')) {
|
|
271
|
+
const config = await s3.downloadFile('config/settings.json');
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### writeParquetContent()
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
writeParquetContent(
|
|
279
|
+
records: ParquetDataRecord[],
|
|
280
|
+
options?: {
|
|
281
|
+
compression?: 'UNCOMPRESSED' | 'GZIP' | 'SNAPPY' | 'LZO' | 'BROTLI';
|
|
282
|
+
schema?: Record<string, any>;
|
|
283
|
+
rowGroupSize?: number;
|
|
284
|
+
}
|
|
285
|
+
): Promise<Buffer>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Parameters:**
|
|
289
|
+
|
|
290
|
+
- `records`: Array of data records
|
|
291
|
+
- `options`: Optional Parquet generation options
|
|
292
|
+
- `compression`: Compression algorithm (default: `'UNCOMPRESSED'`)
|
|
293
|
+
- `schema`: Explicit schema definition (default: auto-detected)
|
|
294
|
+
- `rowGroupSize`: Number of rows per row group (default: 5000)
|
|
295
|
+
|
|
296
|
+
**Returns:** Promise<Buffer> - Parquet file content as Buffer
|
|
297
|
+
|
|
298
|
+
**Example:**
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
const records = [
|
|
302
|
+
{ sku: 'SKU-001', quantity: 10, price: 99.99 }
|
|
303
|
+
];
|
|
304
|
+
const parquetBuffer = await s3.writeParquetContent(records, {
|
|
305
|
+
compression: 'GZIP',
|
|
306
|
+
rowGroupSize: 5000
|
|
307
|
+
});
|
|
308
|
+
await s3.uploadFile('data/inventory.parquet', parquetBuffer);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Handling Large Files
|
|
312
|
+
|
|
313
|
+
For large files (>100MB), use `downloadFile()` with `encoding: 'binary'` and process in chunks:
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
import { Buffer } from 'node:buffer';
|
|
317
|
+
|
|
318
|
+
// Download as Buffer (use encoding: 'binary' for S3)
|
|
319
|
+
const buffer = await s3.downloadFile('large-file.csv', { encoding: 'binary' });
|
|
320
|
+
|
|
321
|
+
// Process in chunks
|
|
322
|
+
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
323
|
+
for (let offset = 0; offset < buffer.length; offset += chunkSize) {
|
|
324
|
+
const chunk = buffer.slice(offset, offset + chunkSize);
|
|
325
|
+
processChunk(chunk.toString('utf8'));
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Note:** The SDK does not provide built-in streaming. See [Module 5: Streaming & Performance](./file-operations-05-streaming-performance.md) for advanced patterns.
|
|
330
|
+
|
|
331
|
+
## SftpDataSource API
|
|
332
|
+
|
|
333
|
+
### Constructor
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
constructor(
|
|
337
|
+
config: {
|
|
338
|
+
settings: SftpSettings;
|
|
339
|
+
},
|
|
340
|
+
logger: Logger
|
|
341
|
+
)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Parameters:**
|
|
345
|
+
|
|
346
|
+
- `settings`: SFTP connection settings
|
|
347
|
+
- `host`: SFTP server hostname
|
|
348
|
+
- `port`: SFTP port (default: 22)
|
|
349
|
+
- `username`: SFTP username
|
|
350
|
+
- `password`: SFTP password (if password auth)
|
|
351
|
+
- `privateKey`: SSH private key (if key auth)
|
|
352
|
+
- `passphrase`: Private key passphrase (optional)
|
|
353
|
+
- `remotePath`: Base remote path
|
|
354
|
+
- `filePattern`: File pattern to match (e.g., '\*.csv')
|
|
355
|
+
- `connectTimeout`: Connection timeout in ms (optional)
|
|
356
|
+
- `logger`: Logger instance
|
|
357
|
+
|
|
358
|
+
**Example:**
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
const sftp = new SftpDataSource(
|
|
362
|
+
{
|
|
363
|
+
type: 'SFTP_CSV',
|
|
364
|
+
connectionId: 'sftp-api',
|
|
365
|
+
name: 'SFTP API Example',
|
|
366
|
+
settings: {
|
|
367
|
+
host: 'sftp.example.com',
|
|
368
|
+
port: 22,
|
|
369
|
+
username: 'myuser',
|
|
370
|
+
password: process.env.SFTP_PASSWORD!,
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
logger
|
|
374
|
+
);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### listFiles()
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
listFiles(params?: {
|
|
381
|
+
lastProcessedTimestamp?: string;
|
|
382
|
+
fileName?: string;
|
|
383
|
+
remotePath?: string;
|
|
384
|
+
filePattern?: string;
|
|
385
|
+
}): Promise<FileMetadata[]>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Parameters:**
|
|
389
|
+
|
|
390
|
+
- `params.lastProcessedTimestamp`: Filter files modified after this timestamp (optional)
|
|
391
|
+
- `params.fileName`: Filter by specific file name (optional)
|
|
392
|
+
- `params.remotePath`: Remote path to list (optional, uses constructor config if not provided)
|
|
393
|
+
- `params.filePattern`: File pattern to match (optional, uses constructor config if not provided)
|
|
394
|
+
|
|
395
|
+
**Returns:** Array of FileMetadata objects (see [FileMetadata interface](#filemetadata))
|
|
396
|
+
|
|
397
|
+
**Example:**
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
// List all files (uses constructor config)
|
|
401
|
+
const files = await sftp.listFiles();
|
|
402
|
+
|
|
403
|
+
// List files with custom path and pattern
|
|
404
|
+
const csvFiles = await sftp.listFiles({
|
|
405
|
+
remotePath: '/data/incoming',
|
|
406
|
+
filePattern: '*.csv'
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
// List files modified after specific timestamp
|
|
410
|
+
const recentFiles = await sftp.listFiles({
|
|
411
|
+
lastProcessedTimestamp: '2025-01-15T00:00:00Z'
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
files.forEach(f => console.log(f.path, f.source)); // path and source ('SFTP')
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### downloadFile()
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
downloadFile(path: string, options?: {
|
|
421
|
+
encoding?: string;
|
|
422
|
+
asBuffer?: boolean;
|
|
423
|
+
maxSize?: number;
|
|
424
|
+
}): Promise<string | Buffer>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**Parameters:**
|
|
428
|
+
|
|
429
|
+
- `path`: Absolute remote path (with leading slash)
|
|
430
|
+
- `options.encoding`: Character encoding (default: 'utf8'). Supported: 'utf8', 'ascii', 'base64', 'hex', 'utf16le', 'latin1'
|
|
431
|
+
- `options.asBuffer`: Return as Buffer instead of string (default: false)
|
|
432
|
+
- `options.maxSize`: Maximum file size in bytes (optional, throws error if exceeded)
|
|
433
|
+
|
|
434
|
+
**Returns:** File content as string (default) or Buffer (if `asBuffer: true`)
|
|
435
|
+
|
|
436
|
+
**Throws:**
|
|
437
|
+
|
|
438
|
+
- Error with "No such file" if file doesn't exist
|
|
439
|
+
- Error with "Permission denied" if no read permission
|
|
440
|
+
- Error if file size exceeds `maxSize`
|
|
441
|
+
|
|
442
|
+
**Example:**
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Download as string (default)
|
|
446
|
+
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
447
|
+
|
|
448
|
+
// Download as Buffer
|
|
449
|
+
const buffer = await sftp.downloadFile('/data/incoming/orders.csv', { asBuffer: true });
|
|
450
|
+
|
|
451
|
+
// Download with size limit
|
|
452
|
+
const smallFile = await sftp.downloadFile('/config/settings.json', {
|
|
453
|
+
maxSize: 1024 * 1024 // 1MB max
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Download with specific encoding
|
|
457
|
+
const latin1Content = await sftp.downloadFile('/data/older-system.txt', {
|
|
458
|
+
encoding: 'latin1'
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### uploadFile()
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
uploadFile(
|
|
466
|
+
remotePath: string,
|
|
467
|
+
content: string | Buffer,
|
|
468
|
+
options?: {
|
|
469
|
+
overwrite?: boolean;
|
|
470
|
+
createDirectories?: boolean;
|
|
471
|
+
permissions?: string;
|
|
472
|
+
encoding?: string;
|
|
473
|
+
}
|
|
474
|
+
): Promise<void>
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Parameters:**
|
|
478
|
+
|
|
479
|
+
- `remotePath`: Absolute remote path (with leading slash)
|
|
480
|
+
- `content`: Content to upload (string or Buffer)
|
|
481
|
+
- `options`: Optional upload parameters (default: all false/undefined)
|
|
482
|
+
- `overwrite`: Overwrite existing file (default: `false`)
|
|
483
|
+
- `false`: Throws `DataSourceError` if file already exists
|
|
484
|
+
- `true`: Replaces existing file without error
|
|
485
|
+
- `createDirectories`: Create parent directories if needed (default: `false`)
|
|
486
|
+
- `false`: Throws error if parent directory doesn't exist
|
|
487
|
+
- `true`: Creates all parent directories recursively
|
|
488
|
+
- `permissions`: File permissions in Unix octal notation (default: server default)
|
|
489
|
+
- Common values: `'0644'` (rw-r--r--), `'0755'` (rwxr-xr-x), `'0600'` (rw-------)
|
|
490
|
+
- `encoding`: Content encoding when `content` is string (default: `'utf8'`)
|
|
491
|
+
- Supported: `'utf8'`, `'ascii'`, `'base64'`, `'hex'`, `'utf16le'`, `'latin1'`
|
|
492
|
+
- Ignored when `content` is a Buffer
|
|
493
|
+
|
|
494
|
+
**Returns:** Promise<void>
|
|
495
|
+
|
|
496
|
+
**Throws:**
|
|
497
|
+
|
|
498
|
+
- `DataSourceError`: "Remote file already exists" when `overwrite: false` and file exists
|
|
499
|
+
- `DataSourceError`: "Permission denied" if no write permission
|
|
500
|
+
- `DataSourceError`: "No such file" if parent directory missing and `createDirectories: false`
|
|
501
|
+
- `DataSourceError`: Network/connection failures (auto-retried per retry config)
|
|
502
|
+
|
|
503
|
+
**Example:**
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
// Simple upload
|
|
507
|
+
await sftp.uploadFile('/data/outgoing/results.json', JSON.stringify(data));
|
|
508
|
+
|
|
509
|
+
// With options
|
|
510
|
+
await sftp.uploadFile('/data/outgoing/results.json', JSON.stringify(data), {
|
|
511
|
+
overwrite: true,
|
|
512
|
+
createDirectories: true,
|
|
513
|
+
permissions: '0644'
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### moveFile()
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
moveFile(
|
|
521
|
+
oldPath: string,
|
|
522
|
+
newPath: string,
|
|
523
|
+
overwrite: boolean = false
|
|
524
|
+
): Promise<void>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Parameters:**
|
|
528
|
+
|
|
529
|
+
- `oldPath`: Absolute source path (with leading slash)
|
|
530
|
+
- `newPath`: Absolute destination path (with leading slash)
|
|
531
|
+
- `overwrite`: Overwrite destination if it exists (default: false)
|
|
532
|
+
|
|
533
|
+
**Returns:** Promise<void>
|
|
534
|
+
|
|
535
|
+
**Implementation:** Native SFTP rename operation (1 operation)
|
|
536
|
+
|
|
537
|
+
**Throws:**
|
|
538
|
+
|
|
539
|
+
- Error with "No such file" if source doesn't exist
|
|
540
|
+
- Error with "Permission denied" if no rename permission
|
|
541
|
+
- Error if destination exists and `overwrite: false`
|
|
542
|
+
|
|
543
|
+
**Example:**
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
// Simple move
|
|
547
|
+
await sftp.moveFile('/data/incoming/orders.csv', '/data/processed/orders.csv');
|
|
548
|
+
|
|
549
|
+
// Move with overwrite
|
|
550
|
+
await sftp.moveFile(
|
|
551
|
+
'/data/incoming/orders.csv',
|
|
552
|
+
'/archive/orders.csv',
|
|
553
|
+
true // Overwrite if exists
|
|
554
|
+
);
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### copyFile()
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
copyFile(
|
|
561
|
+
sourcePath: string,
|
|
562
|
+
destPath: string,
|
|
563
|
+
overwrite: boolean = false
|
|
564
|
+
): Promise<void>
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
**Parameters:**
|
|
568
|
+
|
|
569
|
+
- `sourcePath`: Absolute source path (with leading slash)
|
|
570
|
+
- `destPath`: Absolute destination path (with leading slash)
|
|
571
|
+
- `overwrite`: Overwrite destination if it exists (default: false)
|
|
572
|
+
|
|
573
|
+
**Returns:** Promise<void>
|
|
574
|
+
|
|
575
|
+
**Throws:**
|
|
576
|
+
|
|
577
|
+
- Error with "No such file" if source doesn't exist
|
|
578
|
+
- Error with "Permission denied" if no read/write permission
|
|
579
|
+
- Error if destination exists and `overwrite: false`
|
|
580
|
+
|
|
581
|
+
**Example:**
|
|
582
|
+
|
|
583
|
+
```typescript
|
|
584
|
+
// Simple copy
|
|
585
|
+
await sftp.copyFile('/data/important/config.json', '/backup/config.json');
|
|
586
|
+
|
|
587
|
+
// Copy with overwrite
|
|
588
|
+
await sftp.copyFile(
|
|
589
|
+
'/data/important/config.json',
|
|
590
|
+
'/backup/config.json',
|
|
591
|
+
true // Overwrite if exists
|
|
592
|
+
);
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### deleteFile()
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
deleteFile(remotePath: string): Promise<void>
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Parameters:**
|
|
602
|
+
|
|
603
|
+
- `remotePath`: Absolute remote path (with leading slash)
|
|
604
|
+
|
|
605
|
+
**Returns:** Promise<void>
|
|
606
|
+
|
|
607
|
+
**Throws:**
|
|
608
|
+
|
|
609
|
+
- Error with "No such file" if file doesn't exist
|
|
610
|
+
- Error with "Permission denied" if no delete permission
|
|
611
|
+
|
|
612
|
+
**Example:**
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
await sftp.deleteFile('/data/temp/old-file.csv');
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### fileExists()
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
fileExists(remotePath: string): Promise<boolean>
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Parameters:**
|
|
625
|
+
|
|
626
|
+
- `remotePath`: Absolute remote path (with leading slash)
|
|
627
|
+
|
|
628
|
+
**Returns:** true if file exists, false otherwise
|
|
629
|
+
|
|
630
|
+
**Example:**
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
if (await sftp.fileExists('/data/incoming/orders.csv')) {
|
|
634
|
+
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### createDirectory()
|
|
639
|
+
|
|
640
|
+
```typescript
|
|
641
|
+
createDirectory(
|
|
642
|
+
remotePath: string,
|
|
643
|
+
recursive: boolean = false,
|
|
644
|
+
permissions?: string
|
|
645
|
+
): Promise<void>
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**Parameters:**
|
|
649
|
+
|
|
650
|
+
- `remotePath`: Absolute remote directory path (with leading slash)
|
|
651
|
+
- `recursive`: Create parent directories if they don't exist (default: `false`)
|
|
652
|
+
- `permissions`: Optional directory permissions in Unix octal notation (e.g., `'0755'`)
|
|
653
|
+
|
|
654
|
+
**Returns:** Promise<void>
|
|
655
|
+
|
|
656
|
+
**Throws:**
|
|
657
|
+
|
|
658
|
+
- `DataSourceError`: "Permission denied" if no write permission
|
|
659
|
+
- `DataSourceError`: "No such file" if parent directory missing and `recursive: false`
|
|
660
|
+
|
|
661
|
+
**Example:**
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
// Create single directory
|
|
665
|
+
await sftp.createDirectory('/data/incoming');
|
|
666
|
+
|
|
667
|
+
// Create recursively
|
|
668
|
+
await sftp.createDirectory('/data/archive/2025/01/15', true);
|
|
669
|
+
|
|
670
|
+
// Create with permissions
|
|
671
|
+
await sftp.createDirectory('/data/public', true, '0755');
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### directoryExists()
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
directoryExists(remotePath: string): Promise<boolean>
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
**Parameters:**
|
|
681
|
+
|
|
682
|
+
- `remotePath`: Absolute remote directory path (with leading slash)
|
|
683
|
+
|
|
684
|
+
**Returns:** true if directory exists, false otherwise
|
|
685
|
+
|
|
686
|
+
**Example:**
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
if (!(await sftp.directoryExists('/data/incoming'))) {
|
|
690
|
+
await sftp.createDirectory('/data/incoming', true);
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### parseCsvContent()
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
parseCsvContent(
|
|
698
|
+
csvContent: string,
|
|
699
|
+
fileMetadata: FileMetadata
|
|
700
|
+
): CsvRecord[]
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Parameters:**
|
|
704
|
+
|
|
705
|
+
- `csvContent`: CSV content as string
|
|
706
|
+
- `fileMetadata`: File metadata for context (includes path, name, size, source)
|
|
707
|
+
|
|
708
|
+
**Returns:** Array of parsed CSV records (objects with column names as keys)
|
|
709
|
+
|
|
710
|
+
**Example:**
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
const content = await sftp.downloadFile('/data/incoming/orders.csv');
|
|
714
|
+
const records = sftp.parseCsvContent(content as string, {
|
|
715
|
+
path: '/data/incoming/orders.csv',
|
|
716
|
+
name: 'orders.csv',
|
|
717
|
+
size: content.length,
|
|
718
|
+
source: 'SFTP'
|
|
719
|
+
});
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### parseJsonContent()
|
|
723
|
+
|
|
724
|
+
```typescript
|
|
725
|
+
parseJsonContent(
|
|
726
|
+
jsonContent: string,
|
|
727
|
+
fileMetadata: FileMetadata,
|
|
728
|
+
options?: {
|
|
729
|
+
format?: 'json' | 'jsonl';
|
|
730
|
+
validate?: boolean;
|
|
731
|
+
maxDepth?: number;
|
|
732
|
+
}
|
|
733
|
+
): Record<string, unknown>[]
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
**Parameters:**
|
|
737
|
+
|
|
738
|
+
- `jsonContent`: JSON content as string
|
|
739
|
+
- `fileMetadata`: File metadata for context
|
|
740
|
+
- `options`: Optional parsing options
|
|
741
|
+
- `format`: `'json'` for JSON array or `'jsonl'` for JSON Lines (default: auto-detect)
|
|
742
|
+
- `validate`: Throw error on invalid JSON (default: `false`)
|
|
743
|
+
- `maxDepth`: Limit nesting depth (default: unlimited)
|
|
744
|
+
|
|
745
|
+
**Returns:** Array of parsed JSON objects
|
|
746
|
+
|
|
747
|
+
**Example:**
|
|
748
|
+
|
|
749
|
+
```typescript
|
|
750
|
+
const content = await sftp.downloadFile('/data/incoming/orders.json');
|
|
751
|
+
const records = sftp.parseJsonContent(content as string, {
|
|
752
|
+
path: '/data/incoming/orders.json',
|
|
753
|
+
name: 'orders.json',
|
|
754
|
+
size: content.length,
|
|
755
|
+
source: 'SFTP'
|
|
756
|
+
}, {
|
|
757
|
+
format: 'json',
|
|
758
|
+
validate: true,
|
|
759
|
+
maxDepth: 10
|
|
760
|
+
});
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### writeCsvContent()
|
|
764
|
+
|
|
765
|
+
```typescript
|
|
766
|
+
writeCsvContent(
|
|
767
|
+
records: Record<string, any>[],
|
|
768
|
+
options?: {
|
|
769
|
+
headers?: string[];
|
|
770
|
+
delimiter?: string;
|
|
771
|
+
includeHeaders?: boolean;
|
|
772
|
+
}
|
|
773
|
+
): string
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
**Parameters:**
|
|
777
|
+
|
|
778
|
+
- `records`: Array of objects to convert to CSV
|
|
779
|
+
- `options`: Optional CSV generation options
|
|
780
|
+
- `headers`: Column names (default: inferred from first record)
|
|
781
|
+
- `delimiter`: Field delimiter (default: `','`)
|
|
782
|
+
- `includeHeaders`: Include header row (default: `true`)
|
|
783
|
+
|
|
784
|
+
**Returns:** CSV content as string
|
|
785
|
+
|
|
786
|
+
**Example:**
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
const records = [
|
|
790
|
+
{ sku: 'SKU-001', quantity: 10 },
|
|
791
|
+
{ sku: 'SKU-002', quantity: 25 }
|
|
792
|
+
];
|
|
793
|
+
const csv = sftp.writeCsvContent(records, {
|
|
794
|
+
headers: ['sku', 'quantity'],
|
|
795
|
+
delimiter: ',',
|
|
796
|
+
includeHeaders: true
|
|
797
|
+
});
|
|
798
|
+
await sftp.uploadFile('/data/outgoing/inventory.csv', csv);
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### writeJsonContent()
|
|
802
|
+
|
|
803
|
+
```typescript
|
|
804
|
+
writeJsonContent(
|
|
805
|
+
records: Record<string, any>[],
|
|
806
|
+
options?: {
|
|
807
|
+
format?: 'json' | 'jsonl';
|
|
808
|
+
pretty?: boolean;
|
|
809
|
+
}
|
|
810
|
+
): string
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
**Parameters:**
|
|
814
|
+
|
|
815
|
+
- `records`: Array of objects to convert to JSON
|
|
816
|
+
- `options`: Optional JSON generation options
|
|
817
|
+
- `format`: `'json'` for JSON array or `'jsonl'` for JSON Lines (default: `'json'`)
|
|
818
|
+
- `pretty`: Pretty-print JSON (default: `false`)
|
|
819
|
+
|
|
820
|
+
**Returns:** JSON content as string
|
|
821
|
+
|
|
822
|
+
**Example:**
|
|
823
|
+
|
|
824
|
+
```typescript
|
|
825
|
+
const orders = [{ id: 'ORD-001', total: 99.99 }];
|
|
826
|
+
const json = sftp.writeJsonContent(orders, {
|
|
827
|
+
format: 'json',
|
|
828
|
+
pretty: true
|
|
829
|
+
});
|
|
830
|
+
await sftp.uploadFile('/data/outgoing/orders.json', json);
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
### writeParquetContent()
|
|
834
|
+
|
|
835
|
+
```typescript
|
|
836
|
+
writeParquetContent(
|
|
837
|
+
records: ParquetDataRecord[],
|
|
838
|
+
options?: {
|
|
839
|
+
compression?: 'UNCOMPRESSED' | 'GZIP' | 'SNAPPY' | 'LZO' | 'BROTLI';
|
|
840
|
+
schema?: Record<string, any>;
|
|
841
|
+
rowGroupSize?: number;
|
|
842
|
+
}
|
|
843
|
+
): Promise<Buffer>
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**Parameters:**
|
|
847
|
+
|
|
848
|
+
- `records`: Array of data records
|
|
849
|
+
- `options`: Optional Parquet generation options
|
|
850
|
+
- `compression`: Compression algorithm (default: `'UNCOMPRESSED'`)
|
|
851
|
+
- `schema`: Explicit schema definition (default: auto-detected)
|
|
852
|
+
- `rowGroupSize`: Number of rows per row group (default: 5000)
|
|
853
|
+
|
|
854
|
+
**Returns:** Promise<Buffer> - Parquet file content as Buffer
|
|
855
|
+
|
|
856
|
+
**Example:**
|
|
857
|
+
|
|
858
|
+
```typescript
|
|
859
|
+
const records = [
|
|
860
|
+
{ sku: 'SKU-001', quantity: 10, price: 99.99 }
|
|
861
|
+
];
|
|
862
|
+
const parquetBuffer = await sftp.writeParquetContent(records, {
|
|
863
|
+
compression: 'GZIP',
|
|
864
|
+
rowGroupSize: 5000
|
|
865
|
+
});
|
|
866
|
+
await sftp.uploadFile('/data/outgoing/inventory.parquet', parquetBuffer);
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
### Handling Large Files
|
|
870
|
+
|
|
871
|
+
For large files (>100MB), use `downloadFile()` with `asBuffer: true` and `maxSize` option:
|
|
872
|
+
|
|
873
|
+
```typescript
|
|
874
|
+
import { Buffer } from 'node:buffer';
|
|
875
|
+
|
|
876
|
+
// Download as Buffer with size limit
|
|
877
|
+
const buffer = await sftp.downloadFile('/data/large-file.csv', {
|
|
878
|
+
asBuffer: true,
|
|
879
|
+
maxSize: 100 * 1024 * 1024 // 100 MB limit
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
// Process in chunks
|
|
883
|
+
const chunkSize = 1024 * 1024; // 1MB chunks
|
|
884
|
+
for (let offset = 0; offset < buffer.length; offset += chunkSize) {
|
|
885
|
+
const chunk = buffer.slice(offset, offset + chunkSize);
|
|
886
|
+
processChunk(chunk.toString('utf8'));
|
|
887
|
+
}
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
**Note:** The SDK does not provide built-in streaming. See [Module 5: Streaming & Performance](./file-operations-05-streaming-performance.md) for advanced patterns.
|
|
891
|
+
|
|
892
|
+
### dispose()
|
|
893
|
+
|
|
894
|
+
```typescript
|
|
895
|
+
dispose(): Promise<void>
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
**Parameters:** None
|
|
899
|
+
|
|
900
|
+
**Returns:** Promise<void>
|
|
901
|
+
|
|
902
|
+
**Purpose:** Close SFTP connection and free resources
|
|
903
|
+
|
|
904
|
+
**CRITICAL:** Always call in `finally` block
|
|
905
|
+
|
|
906
|
+
**Example:**
|
|
907
|
+
|
|
908
|
+
```typescript
|
|
909
|
+
const sftp = new SftpDataSource(config, logger);
|
|
910
|
+
try {
|
|
911
|
+
await sftp.listFiles();
|
|
912
|
+
} finally {
|
|
913
|
+
await sftp.dispose(); // REQUIRED!
|
|
914
|
+
}
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
## Common Types
|
|
918
|
+
|
|
919
|
+
### FileMetadata
|
|
920
|
+
|
|
921
|
+
```typescript
|
|
922
|
+
interface FileMetadata {
|
|
923
|
+
path: string; // REQUIRED: Full file path/key
|
|
924
|
+
name: string; // REQUIRED: File name
|
|
925
|
+
size?: number; // File size in bytes (optional)
|
|
926
|
+
lastModified?: string; // ISO 8601 timestamp string (NOT Date object!)
|
|
927
|
+
contentType?: string; // MIME type (optional, S3 only)
|
|
928
|
+
source: string; // REQUIRED: Data source type ('S3' or 'SFTP')
|
|
929
|
+
etag?: string; // S3 ETag (optional, S3 only)
|
|
930
|
+
bucket?: string; // S3 bucket name (optional, S3 only)
|
|
931
|
+
region?: string; // S3 region (optional, S3 only)
|
|
932
|
+
}
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
**Key Points:**
|
|
936
|
+
|
|
937
|
+
- ✅ `path` is REQUIRED (not optional!)
|
|
938
|
+
- ✅ `lastModified` is an ISO string, NOT a Date object
|
|
939
|
+
- ✅ `source` indicates the data source type ('S3' or 'SFTP')
|
|
940
|
+
- ✅ S3-specific fields: `contentType`, `etag`, `bucket`, `region`
|
|
941
|
+
|
|
942
|
+
**Example Usage:**
|
|
943
|
+
|
|
944
|
+
```typescript
|
|
945
|
+
const files: FileMetadata[] = await dataSource.listFiles();
|
|
946
|
+
|
|
947
|
+
files.forEach(file => {
|
|
948
|
+
console.log(`File: ${file.name}`);
|
|
949
|
+
console.log(`Path: ${file.path}`);
|
|
950
|
+
console.log(`Source: ${file.source}`); // 'S3' or 'SFTP'
|
|
951
|
+
console.log(`Modified: ${file.lastModified}`); // ISO string
|
|
952
|
+
if (file.contentType) {
|
|
953
|
+
console.log(`Type: ${file.contentType}`); // S3 only
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
### Logger
|
|
959
|
+
|
|
960
|
+
```typescript
|
|
961
|
+
interface Logger {
|
|
962
|
+
debug(message: string, meta?: any): void;
|
|
963
|
+
info(message: string, meta?: any): void;
|
|
964
|
+
warn(message: string, meta?: any): void;
|
|
965
|
+
error(message: string, error?: Error, meta?: any): void;
|
|
966
|
+
}
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
**Note:** Use `createConsoleLogger()` or `toStructuredLogger()` from the SDK to create Logger instances. See [Logging Guide](../../../02-CORE-GUIDES/logging-guide.md) for details.
|
|
970
|
+
|
|
971
|
+
## Key Differences: S3 vs SFTP
|
|
972
|
+
|
|
973
|
+
| Feature | S3DataSource | SftpDataSource |
|
|
974
|
+
| ----------------------- | ------------------------------------- | ----------------------------------------------- |
|
|
975
|
+
| **Path Format** | No leading slash: `folder/file.csv` | Leading slash: `/folder/file.csv` |
|
|
976
|
+
| **List Method** | `listFiles({ prefix?, delimiter?, maxKeys?, continuationToken? })` | `listFiles({ lastProcessedTimestamp?, fileName?, remotePath?, filePattern? })` |
|
|
977
|
+
| **Upload Signature** | `uploadFile(key, content, options?)` | `uploadFile(remotePath, content, options?)` |
|
|
978
|
+
| **Move Signature** | `moveFile(sourcePath, destPath, deleteSource?)` | `moveFile(oldPath, newPath, overwrite?)` |
|
|
979
|
+
| **Move Implementation** | Copy + Delete (2 ops) | Native rename (1 op) |
|
|
980
|
+
| **Directory Creation** | Automatic | Optional (`createDirectories` flag) |
|
|
981
|
+
| **Connection** | Stateless (per-request) | Stateful (must dispose) |
|
|
982
|
+
| **Cleanup** | Not needed | **Required** (`dispose()`) |
|
|
983
|
+
|
|
984
|
+
## Best Practices
|
|
985
|
+
|
|
986
|
+
### S3 Best Practices
|
|
987
|
+
|
|
988
|
+
```typescript
|
|
989
|
+
// ✅ Use meaningful prefixes
|
|
990
|
+
await s3.listFiles({ prefix: 'incoming/orders/' });
|
|
991
|
+
|
|
992
|
+
// ✅ Use maxKeys for pagination control
|
|
993
|
+
await s3.listFiles({ prefix: 'data/', maxKeys: 100 });
|
|
994
|
+
|
|
995
|
+
// ✅ Check existence before operations
|
|
996
|
+
if (await s3.fileExists('file.csv')) {
|
|
997
|
+
await s3.downloadFile('file.csv');
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// ✅ Use chunked processing for large files
|
|
1001
|
+
if (fileSize > 100 * 1024 * 1024) {
|
|
1002
|
+
// >100MB: Download as Buffer and process in chunks
|
|
1003
|
+
import { Buffer } from 'node:buffer';
|
|
1004
|
+
const buffer = await s3.downloadFile('large-file.csv', { encoding: 'binary' });
|
|
1005
|
+
// Process buffer in chunks (see Module 5 for patterns)
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### SFTP Best Practices
|
|
1010
|
+
|
|
1011
|
+
```typescript
|
|
1012
|
+
// ✅ Always use try/finally with dispose
|
|
1013
|
+
try {
|
|
1014
|
+
const files = await sftp.listFiles();
|
|
1015
|
+
// ... process files
|
|
1016
|
+
} finally {
|
|
1017
|
+
await sftp.dispose(); // CRITICAL!
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// ✅ Use absolute paths
|
|
1021
|
+
await sftp.downloadFile('/data/file.csv'); // ✅
|
|
1022
|
+
// NOT: await sftp.downloadFile('data/file.csv'); // ❌
|
|
1023
|
+
|
|
1024
|
+
// ✅ Use createDirectories flag when necessary
|
|
1025
|
+
await sftp.moveFile(
|
|
1026
|
+
'/source/file.csv',
|
|
1027
|
+
'/archive/2025/01/file.csv',
|
|
1028
|
+
true // Create /archive/2025/01/ if it doesn't exist
|
|
1029
|
+
);
|
|
1030
|
+
|
|
1031
|
+
// ✅ Reuse connection for multiple operations
|
|
1032
|
+
try {
|
|
1033
|
+
for (const file of files) {
|
|
1034
|
+
await sftp.downloadFile(file.path);
|
|
1035
|
+
}
|
|
1036
|
+
} finally {
|
|
1037
|
+
await sftp.dispose(); // Once at the end
|
|
1038
|
+
}
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
## See Also
|
|
1042
|
+
|
|
1043
|
+
- [Module 1: Foundations](./file-operations-01-foundations.md) - Core concepts
|
|
1044
|
+
- [Module 2: Quick Start](./file-operations-02-quick-start.md) - Working examples
|
|
1045
|
+
- [Module 3: S3 Operations](./file-operations-03-s3-operations.md) - S3 deep dive
|
|
1046
|
+
- [Module 4: SFTP Operations](./file-operations-04-sftp-operations.md) - SFTP deep dive
|
|
1047
|
+
- [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md) - Cheat sheet
|
|
1048
|
+
|
|
1049
|
+
---
|
|
1050
|
+
|
|
1051
|
+
**Need Help?**
|
|
1052
|
+
|
|
1053
|
+
- 📖 Browse [Examples](../examples/)
|
|
1054
|
+
- 🔍 Check [Troubleshooting](./file-operations-07-testing-troubleshooting.md)
|
|
1055
|
+
- 📧 Contact support@fluentcommerce.com
|