@oronts/vendure-data-hub-plugin 0.1.2 → 0.1.4
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 +33 -1
- package/README.md +36 -10
- package/dashboard/components/pipelines/PipelineEditor.tsx +159 -5
- package/dashboard/components/pipelines/ReactFlowPipelineEditor.tsx +3 -3
- package/dashboard/components/pipelines/shared/NodePropertiesPanel.tsx +42 -4
- package/dashboard/components/pipelines/shared/StepListItem.tsx +2 -2
- package/dashboard/components/shared/CodeEditor.tsx +289 -0
- package/dashboard/components/shared/schema-form/fields/TextareaField.tsx +19 -4
- package/dashboard/components/shared/step-config/AdapterSelector.tsx +2 -2
- package/dashboard/components/shared/step-config/OperatorFieldInput.tsx +19 -0
- package/dashboard/components/shared/step-config/RouteConfigComponent.tsx +218 -29
- package/dashboard/components/shared/step-config/StepConfigPanel.tsx +24 -10
- package/dashboard/constants/ui-dimensions.ts +2 -1
- package/dashboard/constants/ui-states.ts +1 -0
- package/dashboard/gql/gql.ts +6 -6
- package/dashboard/gql/graphql.ts +9 -4
- package/dashboard/hooks/api/use-pipeline-runs.ts +1 -0
- package/dashboard/hooks/api/use-queues.ts +1 -0
- package/dashboard/hooks/use-adapter-catalog.ts +4 -32
- package/dashboard/routes/connections/ConnectionDetail.tsx +7 -1
- package/dashboard/routes/pipelines/RunDetailsPanel.tsx +1 -1
- package/dashboard/routes/pipelines/components/PipelineActionButtons.tsx +3 -3
- package/dashboard/routes/pipelines/utils/pipeline-conversion.ts +3 -5
- package/dashboard/utils/formatters.ts +6 -4
- package/dist/dashboard/components/pipelines/PipelineEditor.tsx +159 -5
- package/dist/dashboard/components/pipelines/ReactFlowPipelineEditor.tsx +3 -3
- package/dist/dashboard/components/pipelines/shared/NodePropertiesPanel.tsx +42 -4
- package/dist/dashboard/components/pipelines/shared/StepListItem.tsx +2 -2
- package/dist/dashboard/components/shared/CodeEditor.tsx +289 -0
- package/dist/dashboard/components/shared/schema-form/fields/TextareaField.tsx +19 -4
- package/dist/dashboard/components/shared/step-config/AdapterSelector.tsx +2 -2
- package/dist/dashboard/components/shared/step-config/OperatorFieldInput.tsx +19 -0
- package/dist/dashboard/components/shared/step-config/RouteConfigComponent.tsx +218 -29
- package/dist/dashboard/components/shared/step-config/StepConfigPanel.tsx +24 -10
- package/dist/dashboard/constants/ui-dimensions.ts +2 -1
- package/dist/dashboard/constants/ui-states.ts +1 -0
- package/dist/dashboard/gql/gql.ts +6 -6
- package/dist/dashboard/gql/graphql.ts +9 -4
- package/dist/dashboard/hooks/api/use-pipeline-runs.ts +1 -0
- package/dist/dashboard/hooks/api/use-queues.ts +1 -0
- package/dist/dashboard/hooks/use-adapter-catalog.ts +4 -32
- package/dist/dashboard/routes/connections/ConnectionDetail.tsx +7 -1
- package/dist/dashboard/routes/pipelines/RunDetailsPanel.tsx +1 -1
- package/dist/dashboard/routes/pipelines/components/PipelineActionButtons.tsx +3 -3
- package/dist/dashboard/routes/pipelines/utils/pipeline-conversion.ts +3 -5
- package/dist/dashboard/utils/formatters.ts +6 -4
- package/dist/shared/types/adapter-config.types.d.ts +400 -13
- package/dist/shared/types/adapter-config.types.d.ts.map +1 -1
- package/dist/shared/types/index.d.ts +1 -1
- package/dist/shared/types/index.d.ts.map +1 -1
- package/dist/shared/types/index.js.map +1 -1
- package/dist/shared/types/loader.types.d.ts +4 -0
- package/dist/shared/types/loader.types.d.ts.map +1 -1
- package/dist/shared/types/step.types.d.ts +6 -0
- package/dist/shared/types/step.types.d.ts.map +1 -1
- package/dist/shared/utils/error.d.ts +5 -0
- package/dist/shared/utils/error.d.ts.map +1 -1
- package/dist/shared/utils/error.js +11 -0
- package/dist/shared/utils/error.js.map +1 -1
- package/dist/src/adapters/registry.d.ts.map +1 -1
- package/dist/src/adapters/registry.js +2 -1
- package/dist/src/adapters/registry.js.map +1 -1
- package/dist/src/api/controllers/webhook.controller.d.ts +10 -0
- package/dist/src/api/controllers/webhook.controller.d.ts.map +1 -1
- package/dist/src/api/controllers/webhook.controller.js +50 -10
- package/dist/src/api/controllers/webhook.controller.js.map +1 -1
- package/dist/src/api/resolvers/queue.resolver.d.ts +3 -1
- package/dist/src/api/resolvers/queue.resolver.d.ts.map +1 -1
- package/dist/src/api/resolvers/queue.resolver.js +6 -5
- package/dist/src/api/resolvers/queue.resolver.js.map +1 -1
- package/dist/src/api/schema/pipeline.schema.d.ts +1 -1
- package/dist/src/api/schema/pipeline.schema.d.ts.map +1 -1
- package/dist/src/api/schema/pipeline.schema.js +6 -0
- package/dist/src/api/schema/pipeline.schema.js.map +1 -1
- package/dist/src/api/schema/test.schema.d.ts +1 -1
- package/dist/src/api/schema/test.schema.d.ts.map +1 -1
- package/dist/src/api/schema/test.schema.js +5 -1
- package/dist/src/api/schema/test.schema.js.map +1 -1
- package/dist/src/bootstrap/initialization.d.ts.map +1 -1
- package/dist/src/bootstrap/initialization.js +6 -0
- package/dist/src/bootstrap/initialization.js.map +1 -1
- package/dist/src/constants/adapter-schema-options.d.ts +65 -0
- package/dist/src/constants/adapter-schema-options.d.ts.map +1 -1
- package/dist/src/constants/adapter-schema-options.js +79 -3
- package/dist/src/constants/adapter-schema-options.js.map +1 -1
- package/dist/src/constants/builtin-adapters.d.ts +1 -1
- package/dist/src/constants/builtin-adapters.d.ts.map +1 -1
- package/dist/src/constants/builtin-adapters.js +19 -1
- package/dist/src/constants/builtin-adapters.js.map +1 -1
- package/dist/src/constants/core.d.ts +10 -0
- package/dist/src/constants/core.d.ts.map +1 -1
- package/dist/src/constants/core.js +10 -0
- package/dist/src/constants/core.js.map +1 -1
- package/dist/src/constants/defaults/webhook-defaults.d.ts +2 -0
- package/dist/src/constants/defaults/webhook-defaults.d.ts.map +1 -1
- package/dist/src/constants/defaults/webhook-defaults.js +2 -0
- package/dist/src/constants/defaults/webhook-defaults.js.map +1 -1
- package/dist/src/constants/enum-metadata.d.ts.map +1 -1
- package/dist/src/constants/enum-metadata.js +3 -0
- package/dist/src/constants/enum-metadata.js.map +1 -1
- package/dist/src/constants/hook-stage-metadata.d.ts.map +1 -1
- package/dist/src/constants/hook-stage-metadata.js +42 -0
- package/dist/src/constants/hook-stage-metadata.js.map +1 -1
- package/dist/src/constants/services.d.ts.map +1 -1
- package/dist/src/constants/services.js +7 -0
- package/dist/src/constants/services.js.map +1 -1
- package/dist/src/constants/time.d.ts +2 -0
- package/dist/src/constants/time.d.ts.map +1 -1
- package/dist/src/constants/time.js +2 -0
- package/dist/src/constants/time.js.map +1 -1
- package/dist/src/entities/data/error-record.entity.d.ts +1 -0
- package/dist/src/entities/data/error-record.entity.d.ts.map +1 -1
- package/dist/src/entities/data/error-record.entity.js +4 -0
- package/dist/src/entities/data/error-record.entity.js.map +1 -1
- package/dist/src/entities/pipeline/pipeline-run.entity.d.ts +4 -0
- package/dist/src/entities/pipeline/pipeline-run.entity.d.ts.map +1 -1
- package/dist/src/entities/pipeline/pipeline-run.entity.js +8 -0
- package/dist/src/entities/pipeline/pipeline-run.entity.js.map +1 -1
- package/dist/src/extractors/cdc/cdc.extractor.d.ts.map +1 -1
- package/dist/src/extractors/cdc/cdc.extractor.js +7 -2
- package/dist/src/extractors/cdc/cdc.extractor.js.map +1 -1
- package/dist/src/extractors/cdc/types.d.ts +1 -1
- package/dist/src/extractors/cdc/types.d.ts.map +1 -1
- package/dist/src/extractors/extractor-handler-registry.d.ts.map +1 -1
- package/dist/src/extractors/extractor-handler-registry.js +3 -0
- package/dist/src/extractors/extractor-handler-registry.js.map +1 -1
- package/dist/src/extractors/vendure-query/helpers.d.ts +9 -4
- package/dist/src/extractors/vendure-query/helpers.d.ts.map +1 -1
- package/dist/src/extractors/vendure-query/helpers.js +98 -32
- package/dist/src/extractors/vendure-query/helpers.js.map +1 -1
- package/dist/src/extractors/vendure-query/schema.d.ts.map +1 -1
- package/dist/src/extractors/vendure-query/schema.js +13 -0
- package/dist/src/extractors/vendure-query/schema.js.map +1 -1
- package/dist/src/feeds/generators/csv-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/csv-feed.generator.js +5 -4
- package/dist/src/feeds/generators/csv-feed.generator.js.map +1 -1
- package/dist/src/feeds/generators/facebook-catalog.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/facebook-catalog.generator.js +83 -114
- package/dist/src/feeds/generators/facebook-catalog.generator.js.map +1 -1
- package/dist/src/feeds/generators/feed-constants.d.ts +1 -0
- package/dist/src/feeds/generators/feed-constants.d.ts.map +1 -1
- package/dist/src/feeds/generators/feed-constants.js +1 -0
- package/dist/src/feeds/generators/feed-constants.js.map +1 -1
- package/dist/src/feeds/generators/feed-helpers.d.ts +10 -8
- package/dist/src/feeds/generators/feed-helpers.d.ts.map +1 -1
- package/dist/src/feeds/generators/feed-helpers.js +23 -3
- package/dist/src/feeds/generators/feed-helpers.js.map +1 -1
- package/dist/src/feeds/generators/feed-item-builder.d.ts +59 -0
- package/dist/src/feeds/generators/feed-item-builder.d.ts.map +1 -0
- package/dist/src/feeds/generators/feed-item-builder.js +93 -0
- package/dist/src/feeds/generators/feed-item-builder.js.map +1 -0
- package/dist/src/feeds/generators/google-shopping.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/google-shopping.generator.js +52 -64
- package/dist/src/feeds/generators/google-shopping.generator.js.map +1 -1
- package/dist/src/feeds/generators/json-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/json-feed.generator.js +4 -3
- package/dist/src/feeds/generators/json-feed.generator.js.map +1 -1
- package/dist/src/feeds/generators/xml-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/xml-feed.generator.js +6 -5
- package/dist/src/feeds/generators/xml-feed.generator.js.map +1 -1
- package/dist/src/gql/generated.d.ts +5 -0
- package/dist/src/gql/generated.d.ts.map +1 -1
- package/dist/src/gql/generated.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/loaders/asset/asset.loader.d.ts.map +1 -1
- package/dist/src/loaders/asset/asset.loader.js +5 -1
- package/dist/src/loaders/asset/asset.loader.js.map +1 -1
- package/dist/src/loaders/base/validation-builder.d.ts +128 -3
- package/dist/src/loaders/base/validation-builder.d.ts.map +1 -1
- package/dist/src/loaders/base/validation-builder.js +177 -6
- package/dist/src/loaders/base/validation-builder.js.map +1 -1
- package/dist/src/loaders/collection/collection.loader.d.ts.map +1 -1
- package/dist/src/loaders/collection/collection.loader.js +22 -1
- package/dist/src/loaders/collection/collection.loader.js.map +1 -1
- package/dist/src/loaders/collection/helpers.d.ts +16 -1
- package/dist/src/loaders/collection/helpers.d.ts.map +1 -1
- package/dist/src/loaders/collection/helpers.js +37 -0
- package/dist/src/loaders/collection/helpers.js.map +1 -1
- package/dist/src/loaders/customer/customer.loader.d.ts.map +1 -1
- package/dist/src/loaders/customer/customer.loader.js +13 -1
- package/dist/src/loaders/customer/customer.loader.js.map +1 -1
- package/dist/src/loaders/customer/helpers.d.ts +15 -3
- package/dist/src/loaders/customer/helpers.d.ts.map +1 -1
- package/dist/src/loaders/customer/helpers.js +188 -7
- package/dist/src/loaders/customer/helpers.js.map +1 -1
- package/dist/src/loaders/facet-value/facet-value.loader.d.ts.map +1 -1
- package/dist/src/loaders/facet-value/facet-value.loader.js +18 -0
- package/dist/src/loaders/facet-value/facet-value.loader.js.map +1 -1
- package/dist/src/loaders/facet-value/types.d.ts +1 -1
- package/dist/src/loaders/facet-value/types.js +1 -1
- package/dist/src/loaders/facet-value/types.js.map +1 -1
- package/dist/src/loaders/inventory/inventory.loader.d.ts.map +1 -1
- package/dist/src/loaders/inventory/inventory.loader.js +1 -2
- package/dist/src/loaders/inventory/inventory.loader.js.map +1 -1
- package/dist/src/loaders/order/helpers.d.ts +16 -2
- package/dist/src/loaders/order/helpers.d.ts.map +1 -1
- package/dist/src/loaders/order/helpers.js +108 -0
- package/dist/src/loaders/order/helpers.js.map +1 -1
- package/dist/src/loaders/order/order.loader.d.ts +38 -0
- package/dist/src/loaders/order/order.loader.d.ts.map +1 -1
- package/dist/src/loaders/order/order.loader.js +238 -24
- package/dist/src/loaders/order/order.loader.js.map +1 -1
- package/dist/src/loaders/order/types.d.ts +10 -3
- package/dist/src/loaders/order/types.d.ts.map +1 -1
- package/dist/src/loaders/order/types.js +13 -2
- package/dist/src/loaders/order/types.js.map +1 -1
- package/dist/src/loaders/product/product.loader.d.ts.map +1 -1
- package/dist/src/loaders/product/product.loader.js +18 -2
- package/dist/src/loaders/product/product.loader.js.map +1 -1
- package/dist/src/loaders/product-variant/helpers.d.ts +20 -0
- package/dist/src/loaders/product-variant/helpers.d.ts.map +1 -0
- package/dist/src/loaders/product-variant/helpers.js +103 -0
- package/dist/src/loaders/product-variant/helpers.js.map +1 -0
- package/dist/src/loaders/product-variant/product-variant.loader.d.ts.map +1 -1
- package/dist/src/loaders/product-variant/product-variant.loader.js +76 -10
- package/dist/src/loaders/product-variant/product-variant.loader.js.map +1 -1
- package/dist/src/loaders/product-variant/types.d.ts +7 -0
- package/dist/src/loaders/product-variant/types.d.ts.map +1 -1
- package/dist/src/loaders/product-variant/types.js.map +1 -1
- package/dist/src/loaders/promotion/helpers.d.ts +29 -0
- package/dist/src/loaders/promotion/helpers.d.ts.map +1 -1
- package/dist/src/loaders/promotion/helpers.js +68 -0
- package/dist/src/loaders/promotion/helpers.js.map +1 -1
- package/dist/src/loaders/promotion/promotion.loader.d.ts.map +1 -1
- package/dist/src/loaders/promotion/promotion.loader.js +12 -2
- package/dist/src/loaders/promotion/promotion.loader.js.map +1 -1
- package/dist/src/loaders/shared-helpers.d.ts +42 -2
- package/dist/src/loaders/shared-helpers.d.ts.map +1 -1
- package/dist/src/loaders/shared-helpers.js +384 -5
- package/dist/src/loaders/shared-helpers.js.map +1 -1
- package/dist/src/operators/data/copy.operator.js +2 -2
- package/dist/src/operators/data/copy.operator.js.map +1 -1
- package/dist/src/operators/data/rename.operator.js +1 -1
- package/dist/src/operators/data/rename.operator.js.map +1 -1
- package/dist/src/operators/helpers.d.ts.map +1 -1
- package/dist/src/operators/helpers.js +11 -1
- package/dist/src/operators/helpers.js.map +1 -1
- package/dist/src/operators/operator-runtime-registry.d.ts +2 -2
- package/dist/src/operators/operator-runtime-registry.d.ts.map +1 -1
- package/dist/src/operators/operator-runtime-registry.js +1 -1
- package/dist/src/operators/operator-runtime-registry.js.map +1 -1
- package/dist/src/operators/script/script.operators.d.ts.map +1 -1
- package/dist/src/operators/script/script.operators.js +9 -3
- package/dist/src/operators/script/script.operators.js.map +1 -1
- package/dist/src/runtime/config-types.d.ts +6 -0
- package/dist/src/runtime/config-types.d.ts.map +1 -1
- package/dist/src/runtime/executor-helpers.d.ts +77 -0
- package/dist/src/runtime/executor-helpers.d.ts.map +1 -0
- package/dist/src/runtime/executor-helpers.js +143 -0
- package/dist/src/runtime/executor-helpers.js.map +1 -0
- package/dist/src/runtime/executor-types.d.ts +3 -2
- package/dist/src/runtime/executor-types.d.ts.map +1 -1
- package/dist/src/runtime/executors/export.executor.d.ts +3 -1
- package/dist/src/runtime/executors/export.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/export.executor.js +15 -3
- package/dist/src/runtime/executors/export.executor.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler-registry.js +5 -0
- package/dist/src/runtime/executors/exporters/export-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler.types.d.ts +3 -0
- package/dist/src/runtime/executors/exporters/export-handler.types.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler.types.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-helpers.d.ts +1 -0
- package/dist/src/runtime/executors/exporters/export-helpers.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-helpers.js +33 -4
- package/dist/src/runtime/executors/exporters/export-helpers.js.map +1 -1
- package/dist/src/runtime/executors/exporters/http-export.handler.js +4 -4
- package/dist/src/runtime/executors/exporters/http-export.handler.js.map +1 -1
- package/dist/src/runtime/executors/extractors/file-extract.handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/extractors/file-extract.handler.js +33 -13
- package/dist/src/runtime/executors/extractors/file-extract.handler.js.map +1 -1
- package/dist/src/runtime/executors/extractors/memory-extract.handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/extractors/memory-extract.handler.js +17 -9
- package/dist/src/runtime/executors/extractors/memory-extract.handler.js.map +1 -1
- package/dist/src/runtime/executors/feed.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/feed.executor.js +11 -2
- package/dist/src/runtime/executors/feed.executor.js.map +1 -1
- package/dist/src/runtime/executors/feeds/feed-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/feeds/feed-handler-registry.js +4 -0
- package/dist/src/runtime/executors/feeds/feed-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/gate.executor.d.ts +3 -1
- package/dist/src/runtime/executors/gate.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/gate.executor.js +47 -26
- package/dist/src/runtime/executors/gate.executor.js.map +1 -1
- package/dist/src/runtime/executors/loaders/asset-handler.js +1 -1
- package/dist/src/runtime/executors/loaders/asset-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/asset-import-handler.js +1 -1
- package/dist/src/runtime/executors/loaders/asset-import-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/channel-handler.d.ts +3 -1
- package/dist/src/runtime/executors/loaders/channel-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/channel-handler.js +28 -5
- package/dist/src/runtime/executors/loaders/channel-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/collection-handler.d.ts +14 -2
- package/dist/src/runtime/executors/loaders/collection-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/collection-handler.js +113 -23
- package/dist/src/runtime/executors/loaders/collection-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-group-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-group-handler.js +2 -20
- package/dist/src/runtime/executors/loaders/customer-group-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-handler.d.ts +6 -1
- package/dist/src/runtime/executors/loaders/customer-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-handler.js +128 -15
- package/dist/src/runtime/executors/loaders/customer-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/deletion-handler.d.ts +39 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.d.ts.map +1 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.js +414 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.js.map +1 -0
- package/dist/src/runtime/executors/loaders/facet-handler.d.ts +18 -3
- package/dist/src/runtime/executors/loaders/facet-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/facet-handler.js +161 -28
- package/dist/src/runtime/executors/loaders/facet-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/graphql-mutation-handler.js +1 -1
- package/dist/src/runtime/executors/loaders/graphql-mutation-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/index.d.ts +2 -0
- package/dist/src/runtime/executors/loaders/index.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/index.js +5 -1
- package/dist/src/runtime/executors/loaders/index.js.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.js +2 -21
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.d.ts +2 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.js +11 -9
- package/dist/src/runtime/executors/loaders/inventory-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/loader-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/loader-handler-registry.js +150 -11
- package/dist/src/runtime/executors/loaders/loader-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/loaders/order-handler.d.ts +32 -4
- package/dist/src/runtime/executors/loaders/order-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/order-handler.js +201 -18
- package/dist/src/runtime/executors/loaders/order-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/order-upsert-handler.d.ts +15 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.d.ts.map +1 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.js +89 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.js.map +1 -0
- package/dist/src/runtime/executors/loaders/payment-method-handler.d.ts +11 -2
- package/dist/src/runtime/executors/loaders/payment-method-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/payment-method-handler.js +92 -34
- package/dist/src/runtime/executors/loaders/payment-method-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/product-handler.d.ts +20 -0
- package/dist/src/runtime/executors/loaders/product-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/product-handler.js +121 -31
- package/dist/src/runtime/executors/loaders/product-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/promotion-handler.d.ts +9 -2
- package/dist/src/runtime/executors/loaders/promotion-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/promotion-handler.js +134 -68
- package/dist/src/runtime/executors/loaders/promotion-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/rest-handler.js +1 -1
- package/dist/src/runtime/executors/loaders/rest-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.d.ts +62 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.js +238 -0
- package/dist/src/runtime/executors/loaders/shared-lookups.js.map +1 -1
- package/dist/src/runtime/executors/loaders/shipping-method-handler.d.ts +11 -6
- package/dist/src/runtime/executors/loaders/shipping-method-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/shipping-method-handler.js +168 -54
- package/dist/src/runtime/executors/loaders/shipping-method-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/stock-location-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/stock-location-handler.js +2 -20
- package/dist/src/runtime/executors/loaders/stock-location-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/tax-rate-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/tax-rate-handler.js +14 -1
- package/dist/src/runtime/executors/loaders/tax-rate-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/types.d.ts +2 -0
- package/dist/src/runtime/executors/loaders/types.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/variant-handler.d.ts +24 -2
- package/dist/src/runtime/executors/loaders/variant-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/variant-handler.js +266 -47
- package/dist/src/runtime/executors/loaders/variant-handler.js.map +1 -1
- package/dist/src/runtime/executors/sink-handler-registry.d.ts +7 -11
- package/dist/src/runtime/executors/sink-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/sink-handler-registry.js +376 -10
- package/dist/src/runtime/executors/sink-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/sink.executor.d.ts +1 -0
- package/dist/src/runtime/executors/sink.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/sink.executor.js +82 -12
- package/dist/src/runtime/executors/sink.executor.js.map +1 -1
- package/dist/src/runtime/executors/transform.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/transform.executor.js +31 -2
- package/dist/src/runtime/executors/transform.executor.js.map +1 -1
- package/dist/src/runtime/orchestration/graph-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/graph-executor.js +3 -2
- package/dist/src/runtime/orchestration/graph-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/helpers.d.ts +4 -1
- package/dist/src/runtime/orchestration/helpers.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/helpers.js +7 -2
- package/dist/src/runtime/orchestration/helpers.js.map +1 -1
- package/dist/src/runtime/orchestration/linear-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/linear-executor.js +3 -2
- package/dist/src/runtime/orchestration/linear-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/replay-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/replay-executor.js +3 -2
- package/dist/src/runtime/orchestration/replay-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/load-step.strategy.js +2 -2
- package/dist/src/runtime/orchestration/step-strategies/load-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.js +4 -3
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/transform-step.strategy.js +4 -4
- package/dist/src/runtime/orchestration/step-strategies/transform-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/types.d.ts +1 -0
- package/dist/src/runtime/orchestration/types.d.ts.map +1 -1
- package/dist/src/runtime/utils.d.ts.map +1 -1
- package/dist/src/runtime/utils.js +8 -1
- package/dist/src/runtime/utils.js.map +1 -1
- package/dist/src/sdk/adapters/queue/index.d.ts +1 -0
- package/dist/src/sdk/adapters/queue/index.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/index.js +1 -0
- package/dist/src/sdk/adapters/queue/index.js.map +1 -1
- package/dist/src/sdk/adapters/queue/internal.adapter.d.ts +32 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.d.ts.map +1 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.js +68 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.js.map +1 -0
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.js +3 -0
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.js.map +1 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.js +2 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.js.map +1 -1
- package/dist/src/sdk/constants.d.ts +2 -2
- package/dist/src/sdk/constants.d.ts.map +1 -1
- package/dist/src/sdk/dsl/pipeline-builder.d.ts +8 -2
- package/dist/src/sdk/dsl/pipeline-builder.d.ts.map +1 -1
- package/dist/src/sdk/dsl/pipeline-builder.js +115 -19
- package/dist/src/sdk/dsl/pipeline-builder.js.map +1 -1
- package/dist/src/sdk/dsl/step-configs.d.ts +24 -0
- package/dist/src/sdk/dsl/step-configs.d.ts.map +1 -1
- package/dist/src/services/data/record-error.service.d.ts +1 -1
- package/dist/src/services/data/record-error.service.d.ts.map +1 -1
- package/dist/src/services/data/record-error.service.js +4 -1
- package/dist/src/services/data/record-error.service.js.map +1 -1
- package/dist/src/services/events/consumer-discovery.d.ts.map +1 -1
- package/dist/src/services/events/consumer-discovery.js +2 -1
- package/dist/src/services/events/consumer-discovery.js.map +1 -1
- package/dist/src/services/events/consumer-lifecycle.d.ts.map +1 -1
- package/dist/src/services/events/consumer-lifecycle.js +19 -15
- package/dist/src/services/events/consumer-lifecycle.js.map +1 -1
- package/dist/src/services/events/event-trigger.service.d.ts.map +1 -1
- package/dist/src/services/events/event-trigger.service.js +9 -3
- package/dist/src/services/events/event-trigger.service.js.map +1 -1
- package/dist/src/services/events/hook.service.d.ts.map +1 -1
- package/dist/src/services/events/hook.service.js +7 -3
- package/dist/src/services/events/hook.service.js.map +1 -1
- package/dist/src/services/events/message-processing.d.ts.map +1 -1
- package/dist/src/services/events/message-processing.js +13 -8
- package/dist/src/services/events/message-processing.js.map +1 -1
- package/dist/src/services/logger/datahub-logger.d.ts +7 -0
- package/dist/src/services/logger/datahub-logger.d.ts.map +1 -1
- package/dist/src/services/logger/datahub-logger.js +9 -0
- package/dist/src/services/logger/datahub-logger.js.map +1 -1
- package/dist/src/services/logger/execution-logger.d.ts +1 -1
- package/dist/src/services/logger/execution-logger.d.ts.map +1 -1
- package/dist/src/services/logger/execution-logger.js +8 -4
- package/dist/src/services/logger/execution-logger.js.map +1 -1
- package/dist/src/services/pipeline/pipeline-runner.service.d.ts +3 -1
- package/dist/src/services/pipeline/pipeline-runner.service.d.ts.map +1 -1
- package/dist/src/services/pipeline/pipeline-runner.service.js +17 -7
- package/dist/src/services/pipeline/pipeline-runner.service.js.map +1 -1
- package/dist/src/services/pipeline/pipeline.service.d.ts.map +1 -1
- package/dist/src/services/pipeline/pipeline.service.js +8 -2
- package/dist/src/services/pipeline/pipeline.service.js.map +1 -1
- package/dist/src/services/storage/retention.service.d.ts.map +1 -1
- package/dist/src/services/storage/retention.service.js +22 -0
- package/dist/src/services/storage/retention.service.js.map +1 -1
- package/dist/src/services/testing/step-test.service.d.ts.map +1 -1
- package/dist/src/services/testing/step-test.service.js +17 -1
- package/dist/src/services/testing/step-test.service.js.map +1 -1
- package/dist/src/services/validation/definition-validation.service.d.ts.map +1 -1
- package/dist/src/services/validation/definition-validation.service.js +4 -1
- package/dist/src/services/validation/definition-validation.service.js.map +1 -1
- package/dist/src/services/validation/trigger-validation.d.ts.map +1 -1
- package/dist/src/services/validation/trigger-validation.js +76 -2
- package/dist/src/services/validation/trigger-validation.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/loader-configs.d.ts +1071 -0
- package/dist/src/types/loader-configs.d.ts.map +1 -0
- package/dist/src/types/loader-configs.js +54 -0
- package/dist/src/types/loader-configs.js.map +1 -0
- package/dist/src/types/step-configs.d.ts +1 -0
- package/dist/src/types/step-configs.d.ts.map +1 -1
- package/dist/src/types/step-configs.js +3 -0
- package/dist/src/types/step-configs.js.map +1 -1
- package/dist/src/utils/code-security.utils.d.ts +18 -0
- package/dist/src/utils/code-security.utils.d.ts.map +1 -1
- package/dist/src/utils/code-security.utils.js +125 -9
- package/dist/src/utils/code-security.utils.js.map +1 -1
- package/dist/src/utils/error.utils.d.ts +1 -1
- package/dist/src/utils/error.utils.d.ts.map +1 -1
- package/dist/src/utils/error.utils.js +2 -1
- package/dist/src/utils/error.utils.js.map +1 -1
- package/dist/src/utils/url-security.utils.d.ts +5 -3
- package/dist/src/utils/url-security.utils.d.ts.map +1 -1
- package/dist/src/utils/url-security.utils.js +20 -4
- package/dist/src/utils/url-security.utils.js.map +1 -1
- package/dist/src/validation/pipeline-definition.validator.js +2 -1
- package/dist/src/validation/pipeline-definition.validator.js.map +1 -1
- package/docs/developer-guide/README.md +2 -0
- package/docs/developer-guide/dsl/pipeline-builder.md +12 -0
- package/docs/developer-guide/extending/README.md +230 -10
- package/docs/developer-guide/extending/custom-sinks.md +87 -0
- package/docs/developer-guide/extending/events.md +4 -1
- package/docs/examples/validation-error-messages.md +246 -0
- package/docs/guides/multi-channel.md +1190 -0
- package/docs/guides/multi-currency.md +881 -0
- package/docs/guides/multi-entity.md +597 -0
- package/docs/guides/multi-language.md +957 -0
- package/docs/reference/README.md +11 -4
- package/docs/reference/extractors.md +30 -0
- package/docs/reference/loaders.md +396 -21
- package/docs/reference/operators-complete.md +1251 -0
- package/docs/reference/operators.md +36 -2
- package/docs/reference/sinks.md +7 -6
- package/docs/reference/step-types.md +12 -5
- package/docs/user-guide/pipelines.md +82 -13
- package/package.json +1 -1
- package/shared/types/adapter-config.types.ts +439 -10
- package/shared/types/index.ts +25 -0
- package/shared/types/loader.types.ts +4 -0
- package/shared/types/step.types.ts +6 -0
- package/shared/utils/error.ts +11 -0
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
# Multi-Language Import/Export Guide
|
|
2
|
+
|
|
3
|
+
Complete guide to importing and exporting multi-language data in the Data Hub plugin.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
Import products in multiple languages (English and German):
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
datahub.pipeline('import-products-multilang')
|
|
13
|
+
.extract('csv', {
|
|
14
|
+
path: '/data/products-multilang.csv'
|
|
15
|
+
})
|
|
16
|
+
.load('product', {
|
|
17
|
+
nameField: 'name_en',
|
|
18
|
+
slugField: 'slug_en',
|
|
19
|
+
translationsField: 'translations' // ← Magic field for multi-language
|
|
20
|
+
})
|
|
21
|
+
.run();
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**CSV Data Format**:
|
|
25
|
+
```csv
|
|
26
|
+
name_en,slug_en,translations
|
|
27
|
+
"Premium Widget","premium-widget","{""de"":{""name"":""Premium-Widget"",""slug"":""premium-widget"",""description"":""Hochwertige Qualität""},""en"":{""name"":""Premium Widget"",""slug"":""premium-widget"",""description"":""High quality""}}"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Or JSON format** (cleaner):
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"name_en": "Premium Widget",
|
|
34
|
+
"slug_en": "premium-widget",
|
|
35
|
+
"translations": {
|
|
36
|
+
"de": {
|
|
37
|
+
"name": "Premium-Widget",
|
|
38
|
+
"slug": "premium-widget",
|
|
39
|
+
"description": "Hochwertige Qualität"
|
|
40
|
+
},
|
|
41
|
+
"en": {
|
|
42
|
+
"name": "Premium Widget",
|
|
43
|
+
"slug": "premium-widget",
|
|
44
|
+
"description": "High quality"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
✅ **One pipeline handles ALL languages** - no need for separate imports per language!
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Supported Entities
|
|
55
|
+
|
|
56
|
+
The `translationsField` configuration is available for the following 8 loaders:
|
|
57
|
+
|
|
58
|
+
### 1. Product Loader
|
|
59
|
+
|
|
60
|
+
**Translatable Fields**: `name`, `slug`, `description`
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
.load('product', {
|
|
64
|
+
translationsField: 'translations'
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Input Format**:
|
|
69
|
+
```typescript
|
|
70
|
+
{
|
|
71
|
+
"translations": {
|
|
72
|
+
"de": {
|
|
73
|
+
"name": "Premium-Widget",
|
|
74
|
+
"slug": "premium-widget",
|
|
75
|
+
"description": "Hochwertige Qualität"
|
|
76
|
+
},
|
|
77
|
+
"en": {
|
|
78
|
+
"name": "Premium Widget",
|
|
79
|
+
"slug": "premium-widget",
|
|
80
|
+
"description": "High quality"
|
|
81
|
+
},
|
|
82
|
+
"fr": {
|
|
83
|
+
"name": "Widget Premium",
|
|
84
|
+
"slug": "widget-premium",
|
|
85
|
+
"description": "Haute qualité"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Fallback Behavior**:
|
|
92
|
+
- If `translationsField` is NOT set, the loader uses `nameField`, `slugField`, `descriptionField` to create a SINGLE translation in the current request context language
|
|
93
|
+
- If `translationsField` IS set AND translations are missing `name`/`slug`, the loader falls back to the top-level `nameField`/`slugField` values for the first translation
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### 2. Variant Loader
|
|
98
|
+
|
|
99
|
+
**Translatable Fields**: `name`
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
.load('variant', {
|
|
103
|
+
translationsField: 'translations'
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Input Format**:
|
|
108
|
+
```typescript
|
|
109
|
+
{
|
|
110
|
+
"sku": "WIDGET-001",
|
|
111
|
+
"price": 99.99,
|
|
112
|
+
"translations": {
|
|
113
|
+
"de": { "name": "Premium-Widget (klein)" },
|
|
114
|
+
"en": { "name": "Premium Widget (small)" },
|
|
115
|
+
"fr": { "name": "Widget Premium (petit)" }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Fallback**: If `name` is missing in translations, uses top-level `nameField` value.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 3. Collection Loader
|
|
125
|
+
|
|
126
|
+
**Translatable Fields**: `name`, `slug`, `description`
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
.load('collection', {
|
|
130
|
+
translationsField: 'translations'
|
|
131
|
+
})
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Input Format**:
|
|
135
|
+
```typescript
|
|
136
|
+
{
|
|
137
|
+
"translations": {
|
|
138
|
+
"de": {
|
|
139
|
+
"name": "Elektronik",
|
|
140
|
+
"slug": "elektronik",
|
|
141
|
+
"description": "Alle elektronischen Produkte"
|
|
142
|
+
},
|
|
143
|
+
"en": {
|
|
144
|
+
"name": "Electronics",
|
|
145
|
+
"slug": "electronics",
|
|
146
|
+
"description": "All electronic products"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### 4. Facet Loader
|
|
155
|
+
|
|
156
|
+
**Translatable Fields**: `name`
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
.load('facet', {
|
|
160
|
+
translationsField: 'translations'
|
|
161
|
+
})
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Input Format**:
|
|
165
|
+
```typescript
|
|
166
|
+
{
|
|
167
|
+
"code": "brand",
|
|
168
|
+
"translations": {
|
|
169
|
+
"de": { "name": "Marke" },
|
|
170
|
+
"en": { "name": "Brand" },
|
|
171
|
+
"fr": { "name": "Marque" }
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Fallback**: If translations are missing, uses top-level `nameField` (defaults to `code` if name is missing).
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### 5. FacetValue Loader
|
|
181
|
+
|
|
182
|
+
**Translatable Fields**: `name`
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
.load('facet-value', {
|
|
186
|
+
translationsField: 'translations'
|
|
187
|
+
})
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Input Format**:
|
|
191
|
+
```typescript
|
|
192
|
+
{
|
|
193
|
+
"facetCode": "brand",
|
|
194
|
+
"code": "acme",
|
|
195
|
+
"translations": {
|
|
196
|
+
"de": { "name": "ACME GmbH" },
|
|
197
|
+
"en": { "name": "ACME Corp" },
|
|
198
|
+
"fr": { "name": "ACME SA" }
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
### 6. Promotion Loader
|
|
206
|
+
|
|
207
|
+
**Translatable Fields**: `name`, `description`
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
.load('promotion', {
|
|
211
|
+
translationsField: 'translations'
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Input Format**:
|
|
216
|
+
```typescript
|
|
217
|
+
{
|
|
218
|
+
"code": "SUMMER2024",
|
|
219
|
+
"translations": {
|
|
220
|
+
"de": {
|
|
221
|
+
"name": "Sommeraktion 2024",
|
|
222
|
+
"description": "20% Rabatt auf alle Artikel"
|
|
223
|
+
},
|
|
224
|
+
"en": {
|
|
225
|
+
"name": "Summer Sale 2024",
|
|
226
|
+
"description": "20% off all items"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### 7. Shipping Method Loader
|
|
235
|
+
|
|
236
|
+
**Translatable Fields**: `name`, `description`
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
.load('shipping-method', {
|
|
240
|
+
translationsField: 'translations'
|
|
241
|
+
})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Input Format**:
|
|
245
|
+
```typescript
|
|
246
|
+
{
|
|
247
|
+
"code": "express",
|
|
248
|
+
"translations": {
|
|
249
|
+
"de": {
|
|
250
|
+
"name": "Expressversand",
|
|
251
|
+
"description": "Zustellung innerhalb von 24 Stunden"
|
|
252
|
+
},
|
|
253
|
+
"en": {
|
|
254
|
+
"name": "Express Shipping",
|
|
255
|
+
"description": "Delivery within 24 hours"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### 8. Payment Method Loader
|
|
264
|
+
|
|
265
|
+
**Translatable Fields**: `name`, `description`
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
.load('payment-method', {
|
|
269
|
+
translationsField: 'translations'
|
|
270
|
+
})
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Input Format**:
|
|
274
|
+
```typescript
|
|
275
|
+
{
|
|
276
|
+
"code": "paypal",
|
|
277
|
+
"translations": {
|
|
278
|
+
"de": {
|
|
279
|
+
"name": "PayPal",
|
|
280
|
+
"description": "Bezahlen Sie sicher mit PayPal"
|
|
281
|
+
},
|
|
282
|
+
"en": {
|
|
283
|
+
"name": "PayPal",
|
|
284
|
+
"description": "Pay securely with PayPal"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Translation Data Formats
|
|
293
|
+
|
|
294
|
+
The `translationsField` supports **two formats**:
|
|
295
|
+
|
|
296
|
+
### 1. Object Map (Recommended)
|
|
297
|
+
|
|
298
|
+
**Best for**: JSON/XML files, API responses
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
{
|
|
302
|
+
"translations": {
|
|
303
|
+
"de": {
|
|
304
|
+
"name": "Premium-Widget",
|
|
305
|
+
"slug": "premium-widget",
|
|
306
|
+
"description": "Hochwertige Qualität"
|
|
307
|
+
},
|
|
308
|
+
"en": {
|
|
309
|
+
"name": "Premium Widget",
|
|
310
|
+
"slug": "premium-widget",
|
|
311
|
+
"description": "High quality"
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**How it's parsed**:
|
|
318
|
+
- Keys are language codes (`de`, `en`, `fr`, etc.)
|
|
319
|
+
- Values are objects with translatable fields
|
|
320
|
+
- Plugin internally converts to array format: `[{languageCode: 'de', ...}, {languageCode: 'en', ...}]`
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### 2. Array of Objects
|
|
325
|
+
|
|
326
|
+
**Best for**: Precise control, programmatic generation
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
{
|
|
330
|
+
"translations": [
|
|
331
|
+
{
|
|
332
|
+
"languageCode": "de",
|
|
333
|
+
"name": "Premium-Widget",
|
|
334
|
+
"slug": "premium-widget",
|
|
335
|
+
"description": "Hochwertige Qualität"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"languageCode": "en",
|
|
339
|
+
"name": "Premium Widget",
|
|
340
|
+
"slug": "premium-widget",
|
|
341
|
+
"description": "High quality"
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Requirements**:
|
|
348
|
+
- Each object MUST have a `languageCode` field
|
|
349
|
+
- Invalid entries (missing `languageCode`) are silently skipped
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Translation Fallback Logic
|
|
354
|
+
|
|
355
|
+
### Primary Source: translationsField
|
|
356
|
+
|
|
357
|
+
If `translationsField` is configured AND the record contains valid translations:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// Input record
|
|
361
|
+
{
|
|
362
|
+
"name": "Fallback Name", // ← Ignored
|
|
363
|
+
"translations": {
|
|
364
|
+
"de": { "name": "German Name" }, // ← Used
|
|
365
|
+
"en": { "name": "English Name" } // ← Used
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
✅ Result: 2 translations created (German + English), top-level `name` ignored
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
### Secondary Source: Top-Level Fields
|
|
375
|
+
|
|
376
|
+
If `translationsField` is NOT configured OR translations are empty:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// Input record
|
|
380
|
+
{
|
|
381
|
+
"name": "Single Language Name",
|
|
382
|
+
"description": "Single Language Description"
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
✅ Result: 1 translation created in the current request context language (e.g., `en`)
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### Partial Translation Handling
|
|
391
|
+
|
|
392
|
+
If translations are provided but missing `name`/`slug`, the loader falls back to top-level fields:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// Input record
|
|
396
|
+
{
|
|
397
|
+
"name_en": "Premium Widget", // ← Fallback for missing translation names
|
|
398
|
+
"slug_en": "premium-widget", // ← Fallback for missing translation slugs
|
|
399
|
+
"translations": {
|
|
400
|
+
"de": { "description": "Nur Beschreibung" }, // ← Missing name/slug
|
|
401
|
+
"en": { "description": "Only description" } // ← Missing name/slug
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
✅ Result:
|
|
407
|
+
- German translation: `name` = "Premium Widget", `slug` = "premium-widget", `description` = "Nur Beschreibung"
|
|
408
|
+
- English translation: `name` = "Premium Widget", `slug` = "premium-widget", `description` = "Only description"
|
|
409
|
+
|
|
410
|
+
**This prevents empty name/slug fields which would cause validation errors.**
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Adding New Languages
|
|
415
|
+
|
|
416
|
+
### Option 1: Add to Existing Translations
|
|
417
|
+
|
|
418
|
+
Update your source data to include the new language:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
{
|
|
422
|
+
"translations": {
|
|
423
|
+
"de": { "name": "Premium-Widget" },
|
|
424
|
+
"en": { "name": "Premium Widget" },
|
|
425
|
+
"fr": { "name": "Widget Premium" }, // ← New language
|
|
426
|
+
"es": { "name": "Widget Premium" } // ← Another new language
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Run the same pipeline → Vendure will create/update translations for all 4 languages.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### Option 2: Separate Import Per Language
|
|
436
|
+
|
|
437
|
+
If your source data only has one language at a time:
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
// Pipeline 1: Import English translations
|
|
441
|
+
datahub.pipeline('import-products-en')
|
|
442
|
+
.extract('csv', { path: '/data/products-en.csv' })
|
|
443
|
+
.load('product', {
|
|
444
|
+
nameField: 'name',
|
|
445
|
+
slugField: 'slug',
|
|
446
|
+
descriptionField: 'description'
|
|
447
|
+
})
|
|
448
|
+
.run();
|
|
449
|
+
|
|
450
|
+
// Pipeline 2: Import German translations
|
|
451
|
+
datahub.pipeline('import-products-de')
|
|
452
|
+
.extract('csv', { path: '/data/products-de.csv' })
|
|
453
|
+
.load('product', {
|
|
454
|
+
nameField: 'name',
|
|
455
|
+
slugField: 'slug',
|
|
456
|
+
descriptionField: 'description',
|
|
457
|
+
channel: 'default-channel' // Important: use same channel
|
|
458
|
+
})
|
|
459
|
+
.run();
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Important**:
|
|
463
|
+
- Use the SAME `slug` to match existing products
|
|
464
|
+
- Set `strategy: 'UPDATE'` to prevent creating duplicates
|
|
465
|
+
- Translations are merged (not replaced)
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## Common Pitfalls
|
|
470
|
+
|
|
471
|
+
### ❌ WRONG: Top-Level Name with translationsField
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
{
|
|
475
|
+
"name": "English Name", // ← This will be IGNORED
|
|
476
|
+
"translations": {
|
|
477
|
+
"de": { "name": "German Name" } // ← Only this is used
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Problem**: When `translationsField` is set, top-level fields are IGNORED (except as fallback for missing translation fields).
|
|
483
|
+
|
|
484
|
+
**Fix**: Include ALL languages in `translations`:
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
{
|
|
488
|
+
"translations": {
|
|
489
|
+
"de": { "name": "German Name" },
|
|
490
|
+
"en": { "name": "English Name" } // ← Include English here
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
### ❌ WRONG: Missing languageCode in Array
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
{
|
|
501
|
+
"translations": [
|
|
502
|
+
{ "name": "German Name" } // ← Missing languageCode!
|
|
503
|
+
]
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Problem**: Invalid translation entries are silently skipped.
|
|
508
|
+
|
|
509
|
+
**Fix**: Always include `languageCode`:
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
{
|
|
513
|
+
"translations": [
|
|
514
|
+
{ "languageCode": "de", "name": "German Name" } // ✅ Correct
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
### ❌ WRONG: Empty Translations Object
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
{
|
|
525
|
+
"name": "Fallback Name",
|
|
526
|
+
"translations": {} // ← Empty object = no translations
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Result**: No translations created from `translations` field → falls back to top-level `nameField`.
|
|
531
|
+
|
|
532
|
+
**Fix**: Either provide translations OR remove the `translationsField` config:
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
// Option 1: Provide translations
|
|
536
|
+
{
|
|
537
|
+
"name": "Fallback Name",
|
|
538
|
+
"translations": {
|
|
539
|
+
"en": { "name": "English Name" }
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Option 2: Remove translationsField config
|
|
544
|
+
.load('product', {
|
|
545
|
+
nameField: 'name',
|
|
546
|
+
slugField: 'slug'
|
|
547
|
+
// Don't set translationsField
|
|
548
|
+
})
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
### ❌ WRONG: Inconsistent Language Codes
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
{
|
|
557
|
+
"translations": {
|
|
558
|
+
"german": { "name": "German Name" }, // ← Invalid code
|
|
559
|
+
"en": { "name": "English Name" }
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
**Problem**: Vendure expects 2-letter ISO language codes (`de`, `en`, `fr`, `es`, etc.)
|
|
565
|
+
|
|
566
|
+
**Fix**: Use valid ISO 639-1 codes:
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
{
|
|
570
|
+
"translations": {
|
|
571
|
+
"de": { "name": "German Name" }, // ✅ Correct
|
|
572
|
+
"en": { "name": "English Name" }
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**Common Valid Codes**:
|
|
578
|
+
- `en` - English
|
|
579
|
+
- `de` - German
|
|
580
|
+
- `fr` - French
|
|
581
|
+
- `es` - Spanish
|
|
582
|
+
- `it` - Italian
|
|
583
|
+
- `nl` - Dutch
|
|
584
|
+
- `pt` - Portuguese
|
|
585
|
+
- `pl` - Polish
|
|
586
|
+
- `ja` - Japanese
|
|
587
|
+
- `zh` - Chinese
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
### ❌ WRONG: CSV with Complex JSON
|
|
592
|
+
|
|
593
|
+
```csv
|
|
594
|
+
translations
|
|
595
|
+
"{""de"":{""name"":""German""},""en"":{""name"":""English""}}"
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Problem**: Escaped JSON in CSV is hard to read/write/maintain.
|
|
599
|
+
|
|
600
|
+
**Fix 1**: Use JSON or XML instead of CSV:
|
|
601
|
+
|
|
602
|
+
```json
|
|
603
|
+
{
|
|
604
|
+
"translations": {
|
|
605
|
+
"de": { "name": "German Name" },
|
|
606
|
+
"en": { "name": "English Name" }
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**Fix 2**: Use separate language columns in CSV:
|
|
612
|
+
|
|
613
|
+
```csv
|
|
614
|
+
name_de,slug_de,description_de,name_en,slug_en,description_en
|
|
615
|
+
"German Name","german-name","German Desc","English Name","english-name","English Desc"
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
Then transform to translations format:
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
.transform('SCRIPT', {
|
|
622
|
+
expression: `
|
|
623
|
+
return {
|
|
624
|
+
...record,
|
|
625
|
+
translations: {
|
|
626
|
+
de: { name: record.name_de, slug: record.slug_de, description: record.description_de },
|
|
627
|
+
en: { name: record.name_en, slug: record.slug_en, description: record.description_en }
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
`
|
|
631
|
+
})
|
|
632
|
+
.load('product', {
|
|
633
|
+
translationsField: 'translations'
|
|
634
|
+
})
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
## Real-World Example: Multi-Language Product Import
|
|
640
|
+
|
|
641
|
+
**Source Data** (JSON):
|
|
642
|
+
```json
|
|
643
|
+
[
|
|
644
|
+
{
|
|
645
|
+
"sku": "WIDGET-001",
|
|
646
|
+
"price": 99.99,
|
|
647
|
+
"enabled": true,
|
|
648
|
+
"translations": {
|
|
649
|
+
"de": {
|
|
650
|
+
"name": "Premium-Widget",
|
|
651
|
+
"slug": "premium-widget",
|
|
652
|
+
"description": "<h1>Premium-Widget</h1><p>Hochwertige Qualität für anspruchsvolle Kunden.</p>"
|
|
653
|
+
},
|
|
654
|
+
"en": {
|
|
655
|
+
"name": "Premium Widget",
|
|
656
|
+
"slug": "premium-widget",
|
|
657
|
+
"description": "<h1>Premium Widget</h1><p>High quality for demanding customers.</p>"
|
|
658
|
+
},
|
|
659
|
+
"fr": {
|
|
660
|
+
"name": "Widget Premium",
|
|
661
|
+
"slug": "widget-premium",
|
|
662
|
+
"description": "<h1>Widget Premium</h1><p>Haute qualité pour les clients exigeants.</p>"
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
"facetValueCodes": ["category-electronics", "brand-acme"],
|
|
666
|
+
"assetUrls": [
|
|
667
|
+
"https://cdn.example.com/images/widget-001-1.jpg",
|
|
668
|
+
"https://cdn.example.com/images/widget-001-2.jpg"
|
|
669
|
+
],
|
|
670
|
+
"featuredAssetUrl": "https://cdn.example.com/images/widget-001-featured.jpg"
|
|
671
|
+
}
|
|
672
|
+
]
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
**Pipeline**:
|
|
676
|
+
```typescript
|
|
677
|
+
datahub.pipeline('import-multilang-products')
|
|
678
|
+
.extract('json', {
|
|
679
|
+
path: '/data/products-multilang.json'
|
|
680
|
+
})
|
|
681
|
+
.load('product', {
|
|
682
|
+
translationsField: 'translations', // ← Enable multi-language
|
|
683
|
+
skuField: 'sku',
|
|
684
|
+
priceField: 'price',
|
|
685
|
+
enabledField: 'enabled',
|
|
686
|
+
strategy: 'UPSERT' // Update if exists, create if not
|
|
687
|
+
})
|
|
688
|
+
.run();
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
**Result**:
|
|
692
|
+
✅ Product created with 3 translations (German, English, French)
|
|
693
|
+
✅ Single SKU shared across all languages
|
|
694
|
+
✅ Facet values assigned
|
|
695
|
+
✅ Assets created and linked
|
|
696
|
+
|
|
697
|
+
**Export the same product**:
|
|
698
|
+
```typescript
|
|
699
|
+
datahub.pipeline('export-multilang-products')
|
|
700
|
+
.extract('vendure', {
|
|
701
|
+
entityType: 'PRODUCT',
|
|
702
|
+
query: { take: 100 }
|
|
703
|
+
})
|
|
704
|
+
.export('json', {
|
|
705
|
+
path: '/data/products-export.json'
|
|
706
|
+
})
|
|
707
|
+
.run();
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
**Exported Data**:
|
|
711
|
+
```json
|
|
712
|
+
[
|
|
713
|
+
{
|
|
714
|
+
"id": "1",
|
|
715
|
+
"sku": "WIDGET-001",
|
|
716
|
+
"price": 9999,
|
|
717
|
+
"enabled": true,
|
|
718
|
+
"translations": [
|
|
719
|
+
{
|
|
720
|
+
"languageCode": "de",
|
|
721
|
+
"name": "Premium-Widget",
|
|
722
|
+
"slug": "premium-widget",
|
|
723
|
+
"description": "<h1>Premium-Widget</h1><p>Hochwertige Qualität für anspruchsvolle Kunden.</p>"
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
"languageCode": "en",
|
|
727
|
+
"name": "Premium Widget",
|
|
728
|
+
"slug": "premium-widget",
|
|
729
|
+
"description": "<h1>Premium Widget</h1><p>High quality for demanding customers.</p>"
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
"languageCode": "fr",
|
|
733
|
+
"name": "Widget Premium",
|
|
734
|
+
"slug": "widget-premium",
|
|
735
|
+
"description": "<h1>Widget Premium</h1><p>Haute qualité pour les clients exigeants.</p>"
|
|
736
|
+
}
|
|
737
|
+
]
|
|
738
|
+
}
|
|
739
|
+
]
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
✅ **Round-trip compatible**: Exported data can be re-imported with the same pipeline!
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## Performance Tips
|
|
747
|
+
|
|
748
|
+
### 1. Use Object Map Format for Large Imports
|
|
749
|
+
|
|
750
|
+
**Faster parsing**:
|
|
751
|
+
```typescript
|
|
752
|
+
{
|
|
753
|
+
"translations": {
|
|
754
|
+
"de": { "name": "..." },
|
|
755
|
+
"en": { "name": "..." }
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**vs**
|
|
761
|
+
|
|
762
|
+
```typescript
|
|
763
|
+
{
|
|
764
|
+
"translations": [
|
|
765
|
+
{ "languageCode": "de", "name": "..." },
|
|
766
|
+
{ "languageCode": "en", "name": "..." }
|
|
767
|
+
]
|
|
768
|
+
}
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
Both work, but object map is slightly faster because the plugin doesn't need to validate `languageCode` fields.
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
### 2. Batch Imports with Multiple Languages
|
|
776
|
+
|
|
777
|
+
**Good** (Single batch with all languages):
|
|
778
|
+
```typescript
|
|
779
|
+
.load('product', {
|
|
780
|
+
translationsField: 'translations',
|
|
781
|
+
batchSize: 100 // Process 100 products × 3 languages = 300 translations
|
|
782
|
+
})
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
**Bad** (Separate imports per language):
|
|
786
|
+
```typescript
|
|
787
|
+
// Pipeline 1: English
|
|
788
|
+
.load('product', { nameField: 'name_en' })
|
|
789
|
+
|
|
790
|
+
// Pipeline 2: German
|
|
791
|
+
.load('product', { nameField: 'name_de' })
|
|
792
|
+
|
|
793
|
+
// Pipeline 3: French
|
|
794
|
+
.load('product', { nameField: 'name_fr' })
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
**Why**: Single batch is 3× faster (no need to lookup products 3 times).
|
|
798
|
+
|
|
799
|
+
---
|
|
800
|
+
|
|
801
|
+
### 3. Minimize Translation Fields
|
|
802
|
+
|
|
803
|
+
Only include fields that actually differ by language:
|
|
804
|
+
|
|
805
|
+
**Good**:
|
|
806
|
+
```typescript
|
|
807
|
+
{
|
|
808
|
+
"sku": "WIDGET-001", // ← Same across languages (top-level)
|
|
809
|
+
"price": 99.99, // ← Same across languages (top-level)
|
|
810
|
+
"translations": {
|
|
811
|
+
"de": { "name": "...", "description": "..." }, // ← Different per language
|
|
812
|
+
"en": { "name": "...", "description": "..." }
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
**Bad** (Redundant data):
|
|
818
|
+
```typescript
|
|
819
|
+
{
|
|
820
|
+
"translations": {
|
|
821
|
+
"de": {
|
|
822
|
+
"name": "...",
|
|
823
|
+
"sku": "WIDGET-001", // ← Redundant (SKU is not translatable)
|
|
824
|
+
"price": 99.99 // ← Redundant (price is currency-specific, not language)
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
|
|
832
|
+
## FAQ
|
|
833
|
+
|
|
834
|
+
### Q: Can I update only one language without affecting others?
|
|
835
|
+
|
|
836
|
+
**A**: Yes, but you need to include ALL languages in the update:
|
|
837
|
+
|
|
838
|
+
```typescript
|
|
839
|
+
// Vendure behavior: Translations are REPLACED, not merged
|
|
840
|
+
// When you update a product with new translations, existing translations are kept ONLY if included
|
|
841
|
+
|
|
842
|
+
// WRONG (will lose German translation):
|
|
843
|
+
{
|
|
844
|
+
"slug": "premium-widget",
|
|
845
|
+
"translations": {
|
|
846
|
+
"en": { "name": "Updated English Name" } // ← German translation is REMOVED
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// CORRECT (keeps both languages):
|
|
851
|
+
{
|
|
852
|
+
"slug": "premium-widget",
|
|
853
|
+
"translations": {
|
|
854
|
+
"de": { "name": "Premium-Widget" }, // ← Keep German
|
|
855
|
+
"en": { "name": "Updated English Name" } // ← Update English
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Best Practice**: Always export → modify → import to preserve all languages.
|
|
861
|
+
|
|
862
|
+
---
|
|
863
|
+
|
|
864
|
+
### Q: What happens if I don't set translationsField?
|
|
865
|
+
|
|
866
|
+
**A**: The loader creates a SINGLE translation in the current request context language:
|
|
867
|
+
|
|
868
|
+
```typescript
|
|
869
|
+
.load('product', {
|
|
870
|
+
nameField: 'name',
|
|
871
|
+
slugField: 'slug'
|
|
872
|
+
// translationsField NOT set
|
|
873
|
+
})
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
Result: Product has 1 translation (e.g., English if context language is `en`).
|
|
877
|
+
|
|
878
|
+
---
|
|
879
|
+
|
|
880
|
+
### Q: Can I mix translationsField with top-level nameField?
|
|
881
|
+
|
|
882
|
+
**A**: Yes, top-level fields act as **fallback** for missing translation fields:
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
885
|
+
{
|
|
886
|
+
"name_fallback": "Fallback Name",
|
|
887
|
+
"translations": {
|
|
888
|
+
"de": { "slug": "german-slug" } // ← Missing name
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
Config:
|
|
894
|
+
```typescript
|
|
895
|
+
.load('product', {
|
|
896
|
+
nameField: 'name_fallback',
|
|
897
|
+
translationsField: 'translations'
|
|
898
|
+
})
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
Result: German translation gets `name: "Fallback Name"`, `slug: "german-slug"`.
|
|
902
|
+
|
|
903
|
+
---
|
|
904
|
+
|
|
905
|
+
### Q: How do I know which languages are supported in my Vendure store?
|
|
906
|
+
|
|
907
|
+
**A**: Check your Vendure config:
|
|
908
|
+
|
|
909
|
+
```typescript
|
|
910
|
+
// vendure-config.ts
|
|
911
|
+
export const config: VendureConfig = {
|
|
912
|
+
defaultLanguageCode: LanguageCode.en,
|
|
913
|
+
availableLanguageCodes: [
|
|
914
|
+
LanguageCode.en,
|
|
915
|
+
LanguageCode.de,
|
|
916
|
+
LanguageCode.fr
|
|
917
|
+
]
|
|
918
|
+
};
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
The Data Hub plugin accepts ANY `languageCode` in translations, but Vendure will only display languages configured in `availableLanguageCodes`.
|
|
922
|
+
|
|
923
|
+
---
|
|
924
|
+
|
|
925
|
+
### Q: Can I export products with translations?
|
|
926
|
+
|
|
927
|
+
**A**: Yes! The Vendure extractor automatically includes ALL translations:
|
|
928
|
+
|
|
929
|
+
```typescript
|
|
930
|
+
.extract('vendure', {
|
|
931
|
+
entityType: 'PRODUCT'
|
|
932
|
+
})
|
|
933
|
+
.export('json', {
|
|
934
|
+
path: '/data/products-export.json'
|
|
935
|
+
})
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
Exported data format:
|
|
939
|
+
```json
|
|
940
|
+
{
|
|
941
|
+
"translations": [
|
|
942
|
+
{ "languageCode": "de", "name": "..." },
|
|
943
|
+
{ "languageCode": "en", "name": "..." }
|
|
944
|
+
]
|
|
945
|
+
}
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
✅ **Round-trip compatible**: You can re-import this data using `translationsField: 'translations'`.
|
|
949
|
+
|
|
950
|
+
---
|
|
951
|
+
|
|
952
|
+
## See Also
|
|
953
|
+
|
|
954
|
+
- [Multi-Channel Guide](./multi-channel.md) - Assign products to multiple sales channels
|
|
955
|
+
- [Multi-Currency Guide](./multi-currency.md) - Price products in multiple currencies
|
|
956
|
+
- [Multi-Entity Mode Guide](./multi-entity.md) - Handle nested entity arrays (addresses, facet values, etc.)
|
|
957
|
+
- [Loader Reference](../reference/loaders.md) - Complete list of all 16 loaders with field schemas
|