@vivoa/plugin-sdk 0.5.0 → 0.5.2

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/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  declare const PAYMENT_PLUGIN_TOKEN: "PAYMENT_PLUGINS";
2
2
  declare const SHIPPING_PLUGIN_TOKEN: "SHIPPING_PLUGINS";
3
+ declare const SUPPLIERS_PLUGIN_TOKEN: "SUPPLIERS_PLUGINS";
3
4
 
4
5
  declare enum FieldType {
5
6
  String = "string",
@@ -509,7 +510,14 @@ declare enum ShippingFeature {
509
510
  Tracking = "tracking",
510
511
  Cod = "cod",
511
512
  Quotes = "quotes",
512
- Labels = "labels"
513
+ Labels = "labels",
514
+ /**
515
+ * The carrier pushes shipment status changes to a registered webhook URL,
516
+ * and the plugin can normalize + authenticate that payload via
517
+ * {@link IShippingPlugin.parseWebhook}. Enables unattended order transitions
518
+ * (e.g. → delivered) instead of manual admin updates.
519
+ */
520
+ TrackingSync = "tracking-sync"
513
521
  }
514
522
  declare enum CodFeeType {
515
523
  Percentage = "percentage",
@@ -610,6 +618,24 @@ interface ShipmentResult {
610
618
  status: string;
611
619
  rawResponse?: Record<string, unknown>;
612
620
  }
621
+ /**
622
+ * Normalized, carrier-agnostic shipment status event produced by
623
+ * {@link IShippingPlugin.parseWebhook}. The host matches `trackingNumber`
624
+ * against its stored shipment to resolve the order, so the plugin never needs
625
+ * host identifiers. `status: 'unknown'` is a first-class value for carrier
626
+ * states the plugin does not map — the host treats it as a no-op instead of
627
+ * guessing a transition.
628
+ */
629
+ interface TrackingEvent {
630
+ trackingNumber: string;
631
+ status: 'in_transit' | 'delivered' | 'cancelled' | 'unknown';
632
+ /** ISO-8601 instant the carrier reported the change, when available. */
633
+ occurredAt?: string;
634
+ /** Human-readable carrier status, for audit/logging. */
635
+ statusDescription?: string;
636
+ /** Untouched carrier payload, for diagnostics. Never trusted for control flow. */
637
+ raw?: unknown;
638
+ }
613
639
  interface IShippingPlugin extends IPlugin {
614
640
  readonly name: string;
615
641
  readonly shippingConfig: ShippingPluginConfig;
@@ -617,6 +643,191 @@ interface IShippingPlugin extends IPlugin {
617
643
  getQuotes?(params: ShippingQuoteParams, ctx: DispatchContext): Promise<ShippingQuote[]>;
618
644
  /** Pure — a tracking URL never depends on tenant config. */
619
645
  getTrackingUrl(trackingNumber: string): string;
646
+ parseWebhook?(body: unknown, headers: Record<string, string>, ctx: DispatchContext): TrackingEvent | null;
647
+ isConfigured?(ctx: DispatchContext): boolean;
648
+ }
649
+
650
+ declare enum SuppliersFeature {
651
+ /** Browse/search the supplier catalog. */
652
+ CatalogSearch = "catalog-search",
653
+ /** Pull a full listing snapshot to seed a native product. */
654
+ CatalogImport = "catalog-import",
655
+ /** Place + track orders against the supplier. */
656
+ Orders = "orders",
657
+ /** Supplier pushes order status to a registered webhook. */
658
+ FulfillmentSync = "fulfillment-sync",
659
+ /**
660
+ * Poll the supplier for stock levels. SoyDrop has no inventory webhook, so
661
+ * stock is reconciled by polling rather than push.
662
+ */
663
+ StockSync = "stock-sync"
664
+ }
665
+ /**
666
+ * ISO-4217 money in minor units — mirrors the store's Money VO
667
+ * (`core/source/contracts/source-dtos.ts`) so the host maps 1:1 without a
668
+ * currency guess. Kept local so the SDK stays dependency-free.
669
+ */
670
+ interface SupplierMoney {
671
+ amountMinor: number;
672
+ currency: string;
673
+ }
674
+ interface SuppliersDefaultConfig {
675
+ global?: Record<string, unknown>;
676
+ countries?: Record<string, Record<string, unknown>>;
677
+ }
678
+ interface SuppliersPluginConfig {
679
+ supportedCountries: string[];
680
+ supportedCapabilities: SuppliersFeature[];
681
+ configSchema: PluginConfigField[];
682
+ defaultConfig?: SuppliersDefaultConfig;
683
+ }
684
+ interface SuppliersStaticConfig {
685
+ code: string;
686
+ displayName: string;
687
+ description: string;
688
+ iconUrl?: string;
689
+ supportedCountries: string[];
690
+ supportedCapabilities: SuppliersFeature[];
691
+ configSchema: PluginConfigField[];
692
+ }
693
+ interface SupplierCatalogQuery {
694
+ text?: string;
695
+ country?: string;
696
+ cursor?: string;
697
+ limit?: number;
698
+ }
699
+ interface SupplierListingVariant {
700
+ externalVariantId: string;
701
+ sku?: string | null;
702
+ title: string;
703
+ wholesalePrice: SupplierMoney;
704
+ options?: Record<string, string>;
705
+ imageUrl?: string | null;
706
+ available?: boolean;
707
+ }
708
+ interface SupplierListingAttribute {
709
+ name: string;
710
+ value: string;
711
+ }
712
+ interface SupplierStock {
713
+ externalId: string;
714
+ quantity: number;
715
+ inStock: boolean;
716
+ }
717
+ interface SupplierListing {
718
+ /** Native id in the supplier catalog (product or catalog-item id). */
719
+ externalId: string;
720
+ title: string;
721
+ description?: string | null;
722
+ sku?: string | null;
723
+ /** ABSOLUTE image URLs. `imageUrl` is the primary; `images` the gallery. */
724
+ imageUrl?: string | null;
725
+ images?: string[];
726
+ /** Wholesale cost the merchant pays the supplier (per unit). */
727
+ wholesalePrice: SupplierMoney;
728
+ /** Supplier's suggested retail, when provided. */
729
+ suggestedPrice?: SupplierMoney | null;
730
+ stock: SupplierStock;
731
+ categories?: string[];
732
+ attributes?: SupplierListingAttribute[];
733
+ hasVariants: boolean;
734
+ variants?: SupplierListingVariant[];
735
+ moq?: number | null;
736
+ /** Untouched supplier payload, for diagnostics. Never trusted for control flow. */
737
+ raw?: unknown;
738
+ }
739
+ interface SupplierListingPage {
740
+ items: SupplierListing[];
741
+ nextCursor?: string | null;
742
+ }
743
+ interface SupplierOrderCustomer {
744
+ name: string;
745
+ lastName?: string | null;
746
+ phoneAreaCode: string;
747
+ phone: string;
748
+ email?: string | null;
749
+ }
750
+ interface SupplierOrderAddressLevel {
751
+ levelKey: string;
752
+ valueId: string;
753
+ }
754
+ interface SupplierShipTo {
755
+ address: string;
756
+ referencePoint?: string | null;
757
+ /** Supplier geo ids — resolved against the supplier's own geo endpoints. */
758
+ stateId: string;
759
+ cityId: string;
760
+ extraLevels?: SupplierOrderAddressLevel[];
761
+ latitude?: number;
762
+ longitude?: number;
763
+ instructions?: string | null;
764
+ }
765
+ interface SupplierOrderLine {
766
+ /** Supplier catalog/variant id to order. */
767
+ externalListingId: string;
768
+ quantity: number;
769
+ /** Optional price override; omit to use the supplier's catalog price. */
770
+ unitPrice?: SupplierMoney | null;
771
+ }
772
+ interface PlaceSupplierOrderInput {
773
+ /** Host order id — the idempotency key the supplier dedupes on. */
774
+ externalOrderId: string;
775
+ customer: SupplierOrderCustomer;
776
+ shipTo: SupplierShipTo;
777
+ lines: SupplierOrderLine[];
778
+ cod: boolean;
779
+ /** Exact amount to collect on COD; defaults to the line total. */
780
+ codAmount?: SupplierMoney | null;
781
+ /** Optional carrier choice; the supplier picks a default when omitted. */
782
+ courierId?: string | null;
783
+ note?: string | null;
784
+ }
785
+ /**
786
+ * Normalized supplier-order status. `unknown` is a first-class value for
787
+ * supplier states the adapter does not map — the host treats it as a no-op.
788
+ */
789
+ type SupplierOrderStatus = 'pending' | 'accepted' | 'in_transit' | 'shipped' | 'delivered' | 'cancelled' | 'rejected' | 'unknown';
790
+ interface SupplierOrderResult {
791
+ /** Supplier-side order id. */
792
+ externalId: string;
793
+ orderNumber?: string | null;
794
+ /** The host order id echoed back, when the supplier stores it. */
795
+ externalOrderId?: string | null;
796
+ status: SupplierOrderStatus;
797
+ statusLabel?: string | null;
798
+ trackingCode?: string | null;
799
+ trackingUrl?: string | null;
800
+ carrier?: string | null;
801
+ shippingCost?: SupplierMoney | null;
802
+ codAmount?: SupplierMoney | null;
803
+ raw?: unknown;
804
+ }
805
+ /**
806
+ * Normalized, supplier-agnostic fulfillment event produced by
807
+ * {@link ISuppliersPlugin.parseWebhook}. The host matches `externalOrderId`
808
+ * against its stored SupplierOrder to resolve the local order, so the adapter
809
+ * never needs host identifiers.
810
+ */
811
+ interface SupplierFulfillmentEvent {
812
+ externalOrderId: string;
813
+ status: SupplierOrderStatus;
814
+ trackingCode?: string | null;
815
+ carrier?: string | null;
816
+ /** ISO-8601 instant the supplier reported the change, when available. */
817
+ occurredAt?: string;
818
+ statusDescription?: string;
819
+ /** Untouched supplier payload, for diagnostics. */
820
+ raw?: unknown;
821
+ }
822
+ interface ISuppliersPlugin extends IPlugin {
823
+ readonly name: string;
824
+ readonly suppliersConfig: SuppliersPluginConfig;
825
+ searchCatalog(query: SupplierCatalogQuery, ctx: DispatchContext): Promise<SupplierListingPage>;
826
+ getListing(externalId: string, ctx: DispatchContext): Promise<SupplierListing>;
827
+ placeOrder(order: PlaceSupplierOrderInput, ctx: DispatchContext): Promise<SupplierOrderResult>;
828
+ getOrderStatus(externalOrderId: string, ctx: DispatchContext): Promise<SupplierOrderResult>;
829
+ syncStock?(externalIds: string[], ctx: DispatchContext): Promise<SupplierStock[]>;
830
+ parseWebhook?(body: unknown, headers: Record<string, string>, ctx: DispatchContext): SupplierFulfillmentEvent | null;
620
831
  isConfigured?(ctx: DispatchContext): boolean;
621
832
  }
622
833
 
@@ -633,12 +844,14 @@ interface Capability<T = unknown> {
633
844
  declare const CapabilityKind: {
634
845
  readonly Payment: "payment";
635
846
  readonly Shipping: "shipping";
847
+ readonly Suppliers: "suppliers";
636
848
  readonly Analytics: "analytics";
637
849
  };
638
850
  type CapabilityKind = (typeof CapabilityKind)[keyof typeof CapabilityKind];
639
851
  declare function capability<T>(kind: string, impl: T): Capability<T>;
640
852
  declare function paymentCapability(impl: IPaymentPlugin): Capability<IPaymentPlugin>;
641
853
  declare function shippingCapability(impl: IShippingPlugin): Capability<IShippingPlugin>;
854
+ declare function suppliersCapability(impl: ISuppliersPlugin): Capability<ISuppliersPlugin>;
642
855
  /**
643
856
  * A constructed plugin. `capabilities` is the static declaration the host reads
644
857
  * up front; `onActivate` runs when the host mounts the plugin for a tenant and
@@ -776,7 +989,7 @@ declare function checkPermissions(required: string[], grantedRaw: string[]): Per
776
989
  * - MINOR: additive (new optional fields, new tokens) — backwards compatible.
777
990
  * - PATCH: docs/fixes with zero shape changes.
778
991
  */
779
- declare const SDK_VERSION = "0.5.0";
992
+ declare const SDK_VERSION = "0.5.2";
780
993
  /**
781
994
  * True when a plugin built against `pluginSdkVersion` can run on a host that
782
995
  * ships `hostSdkVersion`. Rule: same major, host minor >= plugin minor.
@@ -785,4 +998,4 @@ declare const SDK_VERSION = "0.5.0";
785
998
  */
786
999
  declare function isSdkCompatible(pluginSdkVersion: string, hostSdkVersion: string): boolean;
787
1000
 
788
- export { type AccordionBlock, type AccordionSection, type ActionBlock, ActionVariant, type BannerBlock, type Block, type BlockBase, BlockType, type CalloutBlock, type Capability, CapabilityKind, type CardBlock, type CodConfig, type CodFeeConfig, CodFeeType, type ConditionalBlock, type ConditionalEquals, type ConditionalWhen, ConfigScope, type ConfigurablePlugin, type CopyFieldBlock, type CreateShipmentParams, type DispatchContext, type DividerBlock, type DomainEventHandler, type DomainEventName, type FieldBlock, type FieldDefinition, type FieldDependsOn, type FieldMap, type FieldOption, FieldType, FieldVariant, GatewayEnvironment, type GatewayStaticConfig, type GroupBlock, type HostApi, type HttpClient, type HttpRequest, type HttpResponse, type IPaymentPlugin, type IPlugin, type IShippingPlugin, type InlineRowBlock, type KeyValueBlock, type KeyValueRow, LayoutMode, type Logger, type MarkdownBlock, MessageVariant, PAYMENT_PLUGIN_TOKEN, type PaymentCard, type PaymentCustomer, type PaymentGatewayCode, type PaymentPayload, type PaymentPluginConfig, type PaymentResult, type PaymentVerifyPayload, type Permission, type PermissionCheck, type Plugin, type PluginActionContext, type PluginActionResult, type PluginConfigField, type PluginConfigFieldDependency, type PluginConfigResult, type PluginConfigValidation, type PluginFactory, type PluginManifest, PluginType, type RepeaterBlock, RepeaterSource, SDK_VERSION, SHIPPING_PLUGIN_TOKEN, type SecretStore, type SelectOption, type SequenceStore, type SetupAction, type SetupLayout, type SetupLayoutValidation, type SetupStep, type ShipmentAddress, type ShipmentParcel, type ShipmentResult, type ShippingDefaultConfig, ShippingFeature, type ShippingPluginConfig, type ShippingQuote, type ShippingQuoteParams, type ShippingStaticConfig, StepStatusFrom, type StepStatusFromAction, type StepStatusFromFields, type StepStatusSource, type StorageBroker, type TabItem, type TabsBlock, type ToggleBlock, TransactionStatus, type WebhookSignatureResult, capability, checkPermissions, createPluginConfig, crossValidateSetupLayout, definePlugin, field, isConfigurablePlugin, isPermissionGranted, isPluginFactory, isSdkCompatible, parsePermission, paymentCapability, shippingCapability, validateSetupLayout };
1001
+ export { type AccordionBlock, type AccordionSection, type ActionBlock, ActionVariant, type BannerBlock, type Block, type BlockBase, BlockType, type CalloutBlock, type Capability, CapabilityKind, type CardBlock, type CodConfig, type CodFeeConfig, CodFeeType, type ConditionalBlock, type ConditionalEquals, type ConditionalWhen, ConfigScope, type ConfigurablePlugin, type CopyFieldBlock, type CreateShipmentParams, type DispatchContext, type DividerBlock, type DomainEventHandler, type DomainEventName, type FieldBlock, type FieldDefinition, type FieldDependsOn, type FieldMap, type FieldOption, FieldType, FieldVariant, GatewayEnvironment, type GatewayStaticConfig, type GroupBlock, type HostApi, type HttpClient, type HttpRequest, type HttpResponse, type IPaymentPlugin, type IPlugin, type IShippingPlugin, type ISuppliersPlugin, type InlineRowBlock, type KeyValueBlock, type KeyValueRow, LayoutMode, type Logger, type MarkdownBlock, MessageVariant, PAYMENT_PLUGIN_TOKEN, type PaymentCard, type PaymentCustomer, type PaymentGatewayCode, type PaymentPayload, type PaymentPluginConfig, type PaymentResult, type PaymentVerifyPayload, type Permission, type PermissionCheck, type PlaceSupplierOrderInput, type Plugin, type PluginActionContext, type PluginActionResult, type PluginConfigField, type PluginConfigFieldDependency, type PluginConfigResult, type PluginConfigValidation, type PluginFactory, type PluginManifest, PluginType, type RepeaterBlock, RepeaterSource, SDK_VERSION, SHIPPING_PLUGIN_TOKEN, SUPPLIERS_PLUGIN_TOKEN, type SecretStore, type SelectOption, type SequenceStore, type SetupAction, type SetupLayout, type SetupLayoutValidation, type SetupStep, type ShipmentAddress, type ShipmentParcel, type ShipmentResult, type ShippingDefaultConfig, ShippingFeature, type ShippingPluginConfig, type ShippingQuote, type ShippingQuoteParams, type ShippingStaticConfig, StepStatusFrom, type StepStatusFromAction, type StepStatusFromFields, type StepStatusSource, type StorageBroker, type SupplierCatalogQuery, type SupplierFulfillmentEvent, type SupplierListing, type SupplierListingAttribute, type SupplierListingPage, type SupplierListingVariant, type SupplierMoney, type SupplierOrderAddressLevel, type SupplierOrderCustomer, type SupplierOrderLine, type SupplierOrderResult, type SupplierOrderStatus, type SupplierShipTo, type SupplierStock, type SuppliersDefaultConfig, SuppliersFeature, type SuppliersPluginConfig, type SuppliersStaticConfig, type TabItem, type TabsBlock, type ToggleBlock, type TrackingEvent, TransactionStatus, type WebhookSignatureResult, capability, checkPermissions, createPluginConfig, crossValidateSetupLayout, definePlugin, field, isConfigurablePlugin, isPermissionGranted, isPluginFactory, isSdkCompatible, parsePermission, paymentCapability, shippingCapability, suppliersCapability, validateSetupLayout };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  declare const PAYMENT_PLUGIN_TOKEN: "PAYMENT_PLUGINS";
2
2
  declare const SHIPPING_PLUGIN_TOKEN: "SHIPPING_PLUGINS";
3
+ declare const SUPPLIERS_PLUGIN_TOKEN: "SUPPLIERS_PLUGINS";
3
4
 
4
5
  declare enum FieldType {
5
6
  String = "string",
@@ -509,7 +510,14 @@ declare enum ShippingFeature {
509
510
  Tracking = "tracking",
510
511
  Cod = "cod",
511
512
  Quotes = "quotes",
512
- Labels = "labels"
513
+ Labels = "labels",
514
+ /**
515
+ * The carrier pushes shipment status changes to a registered webhook URL,
516
+ * and the plugin can normalize + authenticate that payload via
517
+ * {@link IShippingPlugin.parseWebhook}. Enables unattended order transitions
518
+ * (e.g. → delivered) instead of manual admin updates.
519
+ */
520
+ TrackingSync = "tracking-sync"
513
521
  }
514
522
  declare enum CodFeeType {
515
523
  Percentage = "percentage",
@@ -610,6 +618,24 @@ interface ShipmentResult {
610
618
  status: string;
611
619
  rawResponse?: Record<string, unknown>;
612
620
  }
621
+ /**
622
+ * Normalized, carrier-agnostic shipment status event produced by
623
+ * {@link IShippingPlugin.parseWebhook}. The host matches `trackingNumber`
624
+ * against its stored shipment to resolve the order, so the plugin never needs
625
+ * host identifiers. `status: 'unknown'` is a first-class value for carrier
626
+ * states the plugin does not map — the host treats it as a no-op instead of
627
+ * guessing a transition.
628
+ */
629
+ interface TrackingEvent {
630
+ trackingNumber: string;
631
+ status: 'in_transit' | 'delivered' | 'cancelled' | 'unknown';
632
+ /** ISO-8601 instant the carrier reported the change, when available. */
633
+ occurredAt?: string;
634
+ /** Human-readable carrier status, for audit/logging. */
635
+ statusDescription?: string;
636
+ /** Untouched carrier payload, for diagnostics. Never trusted for control flow. */
637
+ raw?: unknown;
638
+ }
613
639
  interface IShippingPlugin extends IPlugin {
614
640
  readonly name: string;
615
641
  readonly shippingConfig: ShippingPluginConfig;
@@ -617,6 +643,191 @@ interface IShippingPlugin extends IPlugin {
617
643
  getQuotes?(params: ShippingQuoteParams, ctx: DispatchContext): Promise<ShippingQuote[]>;
618
644
  /** Pure — a tracking URL never depends on tenant config. */
619
645
  getTrackingUrl(trackingNumber: string): string;
646
+ parseWebhook?(body: unknown, headers: Record<string, string>, ctx: DispatchContext): TrackingEvent | null;
647
+ isConfigured?(ctx: DispatchContext): boolean;
648
+ }
649
+
650
+ declare enum SuppliersFeature {
651
+ /** Browse/search the supplier catalog. */
652
+ CatalogSearch = "catalog-search",
653
+ /** Pull a full listing snapshot to seed a native product. */
654
+ CatalogImport = "catalog-import",
655
+ /** Place + track orders against the supplier. */
656
+ Orders = "orders",
657
+ /** Supplier pushes order status to a registered webhook. */
658
+ FulfillmentSync = "fulfillment-sync",
659
+ /**
660
+ * Poll the supplier for stock levels. SoyDrop has no inventory webhook, so
661
+ * stock is reconciled by polling rather than push.
662
+ */
663
+ StockSync = "stock-sync"
664
+ }
665
+ /**
666
+ * ISO-4217 money in minor units — mirrors the store's Money VO
667
+ * (`core/source/contracts/source-dtos.ts`) so the host maps 1:1 without a
668
+ * currency guess. Kept local so the SDK stays dependency-free.
669
+ */
670
+ interface SupplierMoney {
671
+ amountMinor: number;
672
+ currency: string;
673
+ }
674
+ interface SuppliersDefaultConfig {
675
+ global?: Record<string, unknown>;
676
+ countries?: Record<string, Record<string, unknown>>;
677
+ }
678
+ interface SuppliersPluginConfig {
679
+ supportedCountries: string[];
680
+ supportedCapabilities: SuppliersFeature[];
681
+ configSchema: PluginConfigField[];
682
+ defaultConfig?: SuppliersDefaultConfig;
683
+ }
684
+ interface SuppliersStaticConfig {
685
+ code: string;
686
+ displayName: string;
687
+ description: string;
688
+ iconUrl?: string;
689
+ supportedCountries: string[];
690
+ supportedCapabilities: SuppliersFeature[];
691
+ configSchema: PluginConfigField[];
692
+ }
693
+ interface SupplierCatalogQuery {
694
+ text?: string;
695
+ country?: string;
696
+ cursor?: string;
697
+ limit?: number;
698
+ }
699
+ interface SupplierListingVariant {
700
+ externalVariantId: string;
701
+ sku?: string | null;
702
+ title: string;
703
+ wholesalePrice: SupplierMoney;
704
+ options?: Record<string, string>;
705
+ imageUrl?: string | null;
706
+ available?: boolean;
707
+ }
708
+ interface SupplierListingAttribute {
709
+ name: string;
710
+ value: string;
711
+ }
712
+ interface SupplierStock {
713
+ externalId: string;
714
+ quantity: number;
715
+ inStock: boolean;
716
+ }
717
+ interface SupplierListing {
718
+ /** Native id in the supplier catalog (product or catalog-item id). */
719
+ externalId: string;
720
+ title: string;
721
+ description?: string | null;
722
+ sku?: string | null;
723
+ /** ABSOLUTE image URLs. `imageUrl` is the primary; `images` the gallery. */
724
+ imageUrl?: string | null;
725
+ images?: string[];
726
+ /** Wholesale cost the merchant pays the supplier (per unit). */
727
+ wholesalePrice: SupplierMoney;
728
+ /** Supplier's suggested retail, when provided. */
729
+ suggestedPrice?: SupplierMoney | null;
730
+ stock: SupplierStock;
731
+ categories?: string[];
732
+ attributes?: SupplierListingAttribute[];
733
+ hasVariants: boolean;
734
+ variants?: SupplierListingVariant[];
735
+ moq?: number | null;
736
+ /** Untouched supplier payload, for diagnostics. Never trusted for control flow. */
737
+ raw?: unknown;
738
+ }
739
+ interface SupplierListingPage {
740
+ items: SupplierListing[];
741
+ nextCursor?: string | null;
742
+ }
743
+ interface SupplierOrderCustomer {
744
+ name: string;
745
+ lastName?: string | null;
746
+ phoneAreaCode: string;
747
+ phone: string;
748
+ email?: string | null;
749
+ }
750
+ interface SupplierOrderAddressLevel {
751
+ levelKey: string;
752
+ valueId: string;
753
+ }
754
+ interface SupplierShipTo {
755
+ address: string;
756
+ referencePoint?: string | null;
757
+ /** Supplier geo ids — resolved against the supplier's own geo endpoints. */
758
+ stateId: string;
759
+ cityId: string;
760
+ extraLevels?: SupplierOrderAddressLevel[];
761
+ latitude?: number;
762
+ longitude?: number;
763
+ instructions?: string | null;
764
+ }
765
+ interface SupplierOrderLine {
766
+ /** Supplier catalog/variant id to order. */
767
+ externalListingId: string;
768
+ quantity: number;
769
+ /** Optional price override; omit to use the supplier's catalog price. */
770
+ unitPrice?: SupplierMoney | null;
771
+ }
772
+ interface PlaceSupplierOrderInput {
773
+ /** Host order id — the idempotency key the supplier dedupes on. */
774
+ externalOrderId: string;
775
+ customer: SupplierOrderCustomer;
776
+ shipTo: SupplierShipTo;
777
+ lines: SupplierOrderLine[];
778
+ cod: boolean;
779
+ /** Exact amount to collect on COD; defaults to the line total. */
780
+ codAmount?: SupplierMoney | null;
781
+ /** Optional carrier choice; the supplier picks a default when omitted. */
782
+ courierId?: string | null;
783
+ note?: string | null;
784
+ }
785
+ /**
786
+ * Normalized supplier-order status. `unknown` is a first-class value for
787
+ * supplier states the adapter does not map — the host treats it as a no-op.
788
+ */
789
+ type SupplierOrderStatus = 'pending' | 'accepted' | 'in_transit' | 'shipped' | 'delivered' | 'cancelled' | 'rejected' | 'unknown';
790
+ interface SupplierOrderResult {
791
+ /** Supplier-side order id. */
792
+ externalId: string;
793
+ orderNumber?: string | null;
794
+ /** The host order id echoed back, when the supplier stores it. */
795
+ externalOrderId?: string | null;
796
+ status: SupplierOrderStatus;
797
+ statusLabel?: string | null;
798
+ trackingCode?: string | null;
799
+ trackingUrl?: string | null;
800
+ carrier?: string | null;
801
+ shippingCost?: SupplierMoney | null;
802
+ codAmount?: SupplierMoney | null;
803
+ raw?: unknown;
804
+ }
805
+ /**
806
+ * Normalized, supplier-agnostic fulfillment event produced by
807
+ * {@link ISuppliersPlugin.parseWebhook}. The host matches `externalOrderId`
808
+ * against its stored SupplierOrder to resolve the local order, so the adapter
809
+ * never needs host identifiers.
810
+ */
811
+ interface SupplierFulfillmentEvent {
812
+ externalOrderId: string;
813
+ status: SupplierOrderStatus;
814
+ trackingCode?: string | null;
815
+ carrier?: string | null;
816
+ /** ISO-8601 instant the supplier reported the change, when available. */
817
+ occurredAt?: string;
818
+ statusDescription?: string;
819
+ /** Untouched supplier payload, for diagnostics. */
820
+ raw?: unknown;
821
+ }
822
+ interface ISuppliersPlugin extends IPlugin {
823
+ readonly name: string;
824
+ readonly suppliersConfig: SuppliersPluginConfig;
825
+ searchCatalog(query: SupplierCatalogQuery, ctx: DispatchContext): Promise<SupplierListingPage>;
826
+ getListing(externalId: string, ctx: DispatchContext): Promise<SupplierListing>;
827
+ placeOrder(order: PlaceSupplierOrderInput, ctx: DispatchContext): Promise<SupplierOrderResult>;
828
+ getOrderStatus(externalOrderId: string, ctx: DispatchContext): Promise<SupplierOrderResult>;
829
+ syncStock?(externalIds: string[], ctx: DispatchContext): Promise<SupplierStock[]>;
830
+ parseWebhook?(body: unknown, headers: Record<string, string>, ctx: DispatchContext): SupplierFulfillmentEvent | null;
620
831
  isConfigured?(ctx: DispatchContext): boolean;
621
832
  }
622
833
 
@@ -633,12 +844,14 @@ interface Capability<T = unknown> {
633
844
  declare const CapabilityKind: {
634
845
  readonly Payment: "payment";
635
846
  readonly Shipping: "shipping";
847
+ readonly Suppliers: "suppliers";
636
848
  readonly Analytics: "analytics";
637
849
  };
638
850
  type CapabilityKind = (typeof CapabilityKind)[keyof typeof CapabilityKind];
639
851
  declare function capability<T>(kind: string, impl: T): Capability<T>;
640
852
  declare function paymentCapability(impl: IPaymentPlugin): Capability<IPaymentPlugin>;
641
853
  declare function shippingCapability(impl: IShippingPlugin): Capability<IShippingPlugin>;
854
+ declare function suppliersCapability(impl: ISuppliersPlugin): Capability<ISuppliersPlugin>;
642
855
  /**
643
856
  * A constructed plugin. `capabilities` is the static declaration the host reads
644
857
  * up front; `onActivate` runs when the host mounts the plugin for a tenant and
@@ -776,7 +989,7 @@ declare function checkPermissions(required: string[], grantedRaw: string[]): Per
776
989
  * - MINOR: additive (new optional fields, new tokens) — backwards compatible.
777
990
  * - PATCH: docs/fixes with zero shape changes.
778
991
  */
779
- declare const SDK_VERSION = "0.5.0";
992
+ declare const SDK_VERSION = "0.5.2";
780
993
  /**
781
994
  * True when a plugin built against `pluginSdkVersion` can run on a host that
782
995
  * ships `hostSdkVersion`. Rule: same major, host minor >= plugin minor.
@@ -785,4 +998,4 @@ declare const SDK_VERSION = "0.5.0";
785
998
  */
786
999
  declare function isSdkCompatible(pluginSdkVersion: string, hostSdkVersion: string): boolean;
787
1000
 
788
- export { type AccordionBlock, type AccordionSection, type ActionBlock, ActionVariant, type BannerBlock, type Block, type BlockBase, BlockType, type CalloutBlock, type Capability, CapabilityKind, type CardBlock, type CodConfig, type CodFeeConfig, CodFeeType, type ConditionalBlock, type ConditionalEquals, type ConditionalWhen, ConfigScope, type ConfigurablePlugin, type CopyFieldBlock, type CreateShipmentParams, type DispatchContext, type DividerBlock, type DomainEventHandler, type DomainEventName, type FieldBlock, type FieldDefinition, type FieldDependsOn, type FieldMap, type FieldOption, FieldType, FieldVariant, GatewayEnvironment, type GatewayStaticConfig, type GroupBlock, type HostApi, type HttpClient, type HttpRequest, type HttpResponse, type IPaymentPlugin, type IPlugin, type IShippingPlugin, type InlineRowBlock, type KeyValueBlock, type KeyValueRow, LayoutMode, type Logger, type MarkdownBlock, MessageVariant, PAYMENT_PLUGIN_TOKEN, type PaymentCard, type PaymentCustomer, type PaymentGatewayCode, type PaymentPayload, type PaymentPluginConfig, type PaymentResult, type PaymentVerifyPayload, type Permission, type PermissionCheck, type Plugin, type PluginActionContext, type PluginActionResult, type PluginConfigField, type PluginConfigFieldDependency, type PluginConfigResult, type PluginConfigValidation, type PluginFactory, type PluginManifest, PluginType, type RepeaterBlock, RepeaterSource, SDK_VERSION, SHIPPING_PLUGIN_TOKEN, type SecretStore, type SelectOption, type SequenceStore, type SetupAction, type SetupLayout, type SetupLayoutValidation, type SetupStep, type ShipmentAddress, type ShipmentParcel, type ShipmentResult, type ShippingDefaultConfig, ShippingFeature, type ShippingPluginConfig, type ShippingQuote, type ShippingQuoteParams, type ShippingStaticConfig, StepStatusFrom, type StepStatusFromAction, type StepStatusFromFields, type StepStatusSource, type StorageBroker, type TabItem, type TabsBlock, type ToggleBlock, TransactionStatus, type WebhookSignatureResult, capability, checkPermissions, createPluginConfig, crossValidateSetupLayout, definePlugin, field, isConfigurablePlugin, isPermissionGranted, isPluginFactory, isSdkCompatible, parsePermission, paymentCapability, shippingCapability, validateSetupLayout };
1001
+ export { type AccordionBlock, type AccordionSection, type ActionBlock, ActionVariant, type BannerBlock, type Block, type BlockBase, BlockType, type CalloutBlock, type Capability, CapabilityKind, type CardBlock, type CodConfig, type CodFeeConfig, CodFeeType, type ConditionalBlock, type ConditionalEquals, type ConditionalWhen, ConfigScope, type ConfigurablePlugin, type CopyFieldBlock, type CreateShipmentParams, type DispatchContext, type DividerBlock, type DomainEventHandler, type DomainEventName, type FieldBlock, type FieldDefinition, type FieldDependsOn, type FieldMap, type FieldOption, FieldType, FieldVariant, GatewayEnvironment, type GatewayStaticConfig, type GroupBlock, type HostApi, type HttpClient, type HttpRequest, type HttpResponse, type IPaymentPlugin, type IPlugin, type IShippingPlugin, type ISuppliersPlugin, type InlineRowBlock, type KeyValueBlock, type KeyValueRow, LayoutMode, type Logger, type MarkdownBlock, MessageVariant, PAYMENT_PLUGIN_TOKEN, type PaymentCard, type PaymentCustomer, type PaymentGatewayCode, type PaymentPayload, type PaymentPluginConfig, type PaymentResult, type PaymentVerifyPayload, type Permission, type PermissionCheck, type PlaceSupplierOrderInput, type Plugin, type PluginActionContext, type PluginActionResult, type PluginConfigField, type PluginConfigFieldDependency, type PluginConfigResult, type PluginConfigValidation, type PluginFactory, type PluginManifest, PluginType, type RepeaterBlock, RepeaterSource, SDK_VERSION, SHIPPING_PLUGIN_TOKEN, SUPPLIERS_PLUGIN_TOKEN, type SecretStore, type SelectOption, type SequenceStore, type SetupAction, type SetupLayout, type SetupLayoutValidation, type SetupStep, type ShipmentAddress, type ShipmentParcel, type ShipmentResult, type ShippingDefaultConfig, ShippingFeature, type ShippingPluginConfig, type ShippingQuote, type ShippingQuoteParams, type ShippingStaticConfig, StepStatusFrom, type StepStatusFromAction, type StepStatusFromFields, type StepStatusSource, type StorageBroker, type SupplierCatalogQuery, type SupplierFulfillmentEvent, type SupplierListing, type SupplierListingAttribute, type SupplierListingPage, type SupplierListingVariant, type SupplierMoney, type SupplierOrderAddressLevel, type SupplierOrderCustomer, type SupplierOrderLine, type SupplierOrderResult, type SupplierOrderStatus, type SupplierShipTo, type SupplierStock, type SuppliersDefaultConfig, SuppliersFeature, type SuppliersPluginConfig, type SuppliersStaticConfig, type TabItem, type TabsBlock, type ToggleBlock, type TrackingEvent, TransactionStatus, type WebhookSignatureResult, capability, checkPermissions, createPluginConfig, crossValidateSetupLayout, definePlugin, field, isConfigurablePlugin, isPermissionGranted, isPluginFactory, isSdkCompatible, parsePermission, paymentCapability, shippingCapability, suppliersCapability, validateSetupLayout };
package/dist/index.js CHANGED
@@ -35,8 +35,10 @@ __export(index_exports, {
35
35
  RepeaterSource: () => RepeaterSource,
36
36
  SDK_VERSION: () => SDK_VERSION,
37
37
  SHIPPING_PLUGIN_TOKEN: () => SHIPPING_PLUGIN_TOKEN,
38
+ SUPPLIERS_PLUGIN_TOKEN: () => SUPPLIERS_PLUGIN_TOKEN,
38
39
  ShippingFeature: () => ShippingFeature,
39
40
  StepStatusFrom: () => StepStatusFrom,
41
+ SuppliersFeature: () => SuppliersFeature,
40
42
  TransactionStatus: () => TransactionStatus,
41
43
  capability: () => capability,
42
44
  checkPermissions: () => checkPermissions,
@@ -51,6 +53,7 @@ __export(index_exports, {
51
53
  parsePermission: () => parsePermission,
52
54
  paymentCapability: () => paymentCapability,
53
55
  shippingCapability: () => shippingCapability,
56
+ suppliersCapability: () => suppliersCapability,
54
57
  validateSetupLayout: () => validateSetupLayout
55
58
  });
56
59
  module.exports = __toCommonJS(index_exports);
@@ -58,6 +61,7 @@ module.exports = __toCommonJS(index_exports);
58
61
  // src/tokens.ts
59
62
  var PAYMENT_PLUGIN_TOKEN = "PAYMENT_PLUGINS";
60
63
  var SHIPPING_PLUGIN_TOKEN = "SHIPPING_PLUGINS";
64
+ var SUPPLIERS_PLUGIN_TOKEN = "SUPPLIERS_PLUGINS";
61
65
 
62
66
  // src/plugin.ts
63
67
  var PluginType = /* @__PURE__ */ ((PluginType2) => {
@@ -177,6 +181,7 @@ var ShippingFeature = /* @__PURE__ */ ((ShippingFeature2) => {
177
181
  ShippingFeature2["Cod"] = "cod";
178
182
  ShippingFeature2["Quotes"] = "quotes";
179
183
  ShippingFeature2["Labels"] = "labels";
184
+ ShippingFeature2["TrackingSync"] = "tracking-sync";
180
185
  return ShippingFeature2;
181
186
  })(ShippingFeature || {});
182
187
  var CodFeeType = /* @__PURE__ */ ((CodFeeType2) => {
@@ -185,6 +190,16 @@ var CodFeeType = /* @__PURE__ */ ((CodFeeType2) => {
185
190
  return CodFeeType2;
186
191
  })(CodFeeType || {});
187
192
 
193
+ // src/suppliers.ts
194
+ var SuppliersFeature = /* @__PURE__ */ ((SuppliersFeature2) => {
195
+ SuppliersFeature2["CatalogSearch"] = "catalog-search";
196
+ SuppliersFeature2["CatalogImport"] = "catalog-import";
197
+ SuppliersFeature2["Orders"] = "orders";
198
+ SuppliersFeature2["FulfillmentSync"] = "fulfillment-sync";
199
+ SuppliersFeature2["StockSync"] = "stock-sync";
200
+ return SuppliersFeature2;
201
+ })(SuppliersFeature || {});
202
+
188
203
  // src/setup-layout.ts
189
204
  var import_superstruct2 = require("superstruct");
190
205
  var FieldVariant = /* @__PURE__ */ ((FieldVariant2) => {
@@ -455,6 +470,7 @@ function crossValidateSetupLayout(layout, configSchema) {
455
470
  var CapabilityKind = {
456
471
  Payment: "payment",
457
472
  Shipping: "shipping",
473
+ Suppliers: "suppliers",
458
474
  Analytics: "analytics"
459
475
  };
460
476
  function capability(kind, impl) {
@@ -466,6 +482,9 @@ function paymentCapability(impl) {
466
482
  function shippingCapability(impl) {
467
483
  return { kind: CapabilityKind.Shipping, impl };
468
484
  }
485
+ function suppliersCapability(impl) {
486
+ return { kind: CapabilityKind.Suppliers, impl };
487
+ }
469
488
  var PLUGIN_FACTORY_BRAND = /* @__PURE__ */ Symbol.for("vivoa.plugin.factory");
470
489
  function definePlugin(factory) {
471
490
  Object.defineProperty(factory, PLUGIN_FACTORY_BRAND, {
@@ -511,7 +530,7 @@ function checkPermissions(required, grantedRaw) {
511
530
  }
512
531
 
513
532
  // src/version.ts
514
- var SDK_VERSION = "0.5.0";
533
+ var SDK_VERSION = "0.5.2";
515
534
  function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
516
535
  const parse = (v) => {
517
536
  const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
@@ -543,8 +562,10 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
543
562
  RepeaterSource,
544
563
  SDK_VERSION,
545
564
  SHIPPING_PLUGIN_TOKEN,
565
+ SUPPLIERS_PLUGIN_TOKEN,
546
566
  ShippingFeature,
547
567
  StepStatusFrom,
568
+ SuppliersFeature,
548
569
  TransactionStatus,
549
570
  capability,
550
571
  checkPermissions,
@@ -559,5 +580,6 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
559
580
  parsePermission,
560
581
  paymentCapability,
561
582
  shippingCapability,
583
+ suppliersCapability,
562
584
  validateSetupLayout
563
585
  });
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/tokens.ts
2
2
  var PAYMENT_PLUGIN_TOKEN = "PAYMENT_PLUGINS";
3
3
  var SHIPPING_PLUGIN_TOKEN = "SHIPPING_PLUGINS";
4
+ var SUPPLIERS_PLUGIN_TOKEN = "SUPPLIERS_PLUGINS";
4
5
 
5
6
  // src/plugin.ts
6
7
  var PluginType = /* @__PURE__ */ ((PluginType2) => {
@@ -128,6 +129,7 @@ var ShippingFeature = /* @__PURE__ */ ((ShippingFeature2) => {
128
129
  ShippingFeature2["Cod"] = "cod";
129
130
  ShippingFeature2["Quotes"] = "quotes";
130
131
  ShippingFeature2["Labels"] = "labels";
132
+ ShippingFeature2["TrackingSync"] = "tracking-sync";
131
133
  return ShippingFeature2;
132
134
  })(ShippingFeature || {});
133
135
  var CodFeeType = /* @__PURE__ */ ((CodFeeType2) => {
@@ -136,6 +138,16 @@ var CodFeeType = /* @__PURE__ */ ((CodFeeType2) => {
136
138
  return CodFeeType2;
137
139
  })(CodFeeType || {});
138
140
 
141
+ // src/suppliers.ts
142
+ var SuppliersFeature = /* @__PURE__ */ ((SuppliersFeature2) => {
143
+ SuppliersFeature2["CatalogSearch"] = "catalog-search";
144
+ SuppliersFeature2["CatalogImport"] = "catalog-import";
145
+ SuppliersFeature2["Orders"] = "orders";
146
+ SuppliersFeature2["FulfillmentSync"] = "fulfillment-sync";
147
+ SuppliersFeature2["StockSync"] = "stock-sync";
148
+ return SuppliersFeature2;
149
+ })(SuppliersFeature || {});
150
+
139
151
  // src/setup-layout.ts
140
152
  import {
141
153
  array,
@@ -419,6 +431,7 @@ function crossValidateSetupLayout(layout, configSchema) {
419
431
  var CapabilityKind = {
420
432
  Payment: "payment",
421
433
  Shipping: "shipping",
434
+ Suppliers: "suppliers",
422
435
  Analytics: "analytics"
423
436
  };
424
437
  function capability(kind, impl) {
@@ -430,6 +443,9 @@ function paymentCapability(impl) {
430
443
  function shippingCapability(impl) {
431
444
  return { kind: CapabilityKind.Shipping, impl };
432
445
  }
446
+ function suppliersCapability(impl) {
447
+ return { kind: CapabilityKind.Suppliers, impl };
448
+ }
433
449
  var PLUGIN_FACTORY_BRAND = /* @__PURE__ */ Symbol.for("vivoa.plugin.factory");
434
450
  function definePlugin(factory) {
435
451
  Object.defineProperty(factory, PLUGIN_FACTORY_BRAND, {
@@ -475,7 +491,7 @@ function checkPermissions(required, grantedRaw) {
475
491
  }
476
492
 
477
493
  // src/version.ts
478
- var SDK_VERSION = "0.5.0";
494
+ var SDK_VERSION = "0.5.2";
479
495
  function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
480
496
  const parse = (v) => {
481
497
  const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
@@ -506,8 +522,10 @@ export {
506
522
  RepeaterSource,
507
523
  SDK_VERSION,
508
524
  SHIPPING_PLUGIN_TOKEN,
525
+ SUPPLIERS_PLUGIN_TOKEN,
509
526
  ShippingFeature,
510
527
  StepStatusFrom,
528
+ SuppliersFeature,
511
529
  TransactionStatus,
512
530
  capability,
513
531
  checkPermissions,
@@ -522,5 +540,6 @@ export {
522
540
  parsePermission,
523
541
  paymentCapability,
524
542
  shippingCapability,
543
+ suppliersCapability,
525
544
  validateSetupLayout
526
545
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vivoa/plugin-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Public contracts for Vivoa plugins (types, DI tokens, config + setup-layout validators)",
5
5
  "license": "MIT",
6
6
  "author": "Vivoa",
@@ -56,4 +56,4 @@
56
56
  "esbuild"
57
57
  ]
58
58
  }
59
- }
59
+ }