@dutchfurniturefulfilment/skik-client
Version:
Javascript package for integrating a SKIK configurator inside web projects.
401 lines (336 loc) • 13.3 kB
TypeScript
declare const SKIKClient: SKIKClient.Static;
export default SKIKClient;
export as namespace SKIKClient;
/**
* Type declarations for the skik-client JS package used to integrate a SKIK
* closet system configurator into another web page. The configurator is
* externally hosted, and will be implemented through an embedded i-frame.
* This package makes integration easy by providing an expressive interface
* to communicate with the application, and subscribe to events and changes
* to the configuration state.
*
* @author Jeffrey Westerkamp <jeffrey@pixelindustries.com> (https://github.com/JJWesterkamp)
*/
declare namespace SKIKClient {
// -----------------------------------------------------------------------
// Type aliases (for semantics)
// -----------------------------------------------------------------------
/**
* A SKIK Configuration hash is a string representing a certain SKIK
* closet configuration. Such a hash can after retrieval be used to query
* for the relevant product data server-side (e.g. for adding items to cart)
* or simply to associate it as a 'favorite' of a certain user account.
* Hashes represent persisted, immutable SKIK closet configurations.
*/
type SKIKConfigurationHash = string;
/**
* Valid languages the configurator is able to run in, in ISO 639-1 format.
*/
type AvailableLocale = 'nl' | 'en';
// -----------------------------------------------------------------------
// Mapping of public event names to their associated payload signatures.
// -----------------------------------------------------------------------
interface EventPayloadMap {
/**
* Event fired when the height of the SKIK Configurator document
* changed. The new height in pixels is the event's payload.
* This event is mostly relevant for custom i-frame size management.
*/
'child-document-height-changed': number;
/**
* Event fired when the height of the i-frame was explicitly set by
* the SKIK Client instance. The new height of the frame is the
* event's payload.
*/
'frame-height-set': number;
/**
* Event fired when the price of the active configuration changed.
* A price-mutation report object is the event's payload. This event
* can be used to display the price of the currently active closet
* configuration. (The configurator itself does not display prices)
*/
'price-changed': PriceMutationReport;
/**
* Event fired when the display locale (language) changed in the
* configurator. Locale is in ISO 639-1 format.
*/
'locale-changed': AvailableLocale;
}
// -----------------------------------------------------------------------
// Event channel and payload types
// -----------------------------------------------------------------------
type EventChannel = keyof EventPayloadMap;
type EventPayload<E extends EventChannel> = EventPayloadMap[E];
// -----------------------------------------------------------------------
// Event subscription interface
// -----------------------------------------------------------------------
interface EventSubscription<E extends EventChannel> {
/**
* The channel name of the event this subscription belongs to.
*/
readonly channelName: E;
/**
* Boolean to check if the event-subscriber unsubscribed. If true,
* the subscription is effectively dead.
*/
readonly isUnsubscribed: boolean;
/**
* Boolean indicating whether handling of events is disabled. if
* true, events will not be handled, until resume() is called.
*/
readonly isPaused: boolean;
/**
* Pauses this event subscription. New events will not be handled,
* until resume() is called.
*/
pause(): this;
/**
* Resumes this event subscription. New events will be handled again.
*/
resume(): this;
/**
* Un-subscribes from the event, essentially killing this subscription.
* After unsubscribe is called, the subscription object can be
* disposed of (i.e. out of scope / unset reference).
*/
unsubscribe(): void;
}
// ---------------------------------------------------------------------
// Constructor options signature for creating new SKIKClient instances.
// ---------------------------------------------------------------------
/**
* Constructor options interface for SKIKClient.Client instance creation.
*
* @property {string} containerId
* @property {string} apiKey
* @property {boolean} [autoResizeFrame = true]
* @property {string | null} [configurationHash = null]
* @property {string} [configuratorOrigin = 'ht']
*/
interface ConstructorOptions {
/**
* The ID attribute value of the DOM element in which to build the
* SKIK-Configurator i-frame.
*/
containerId: string;
/**
* Your API key for the SKIK Configurator application
*/
apiKey: string;
/**
* Boolean indicating whether the i-frame should resize automatically.
* In most cases this is desired, to prevent double scrollbars in the
* browser window. Can be disabled if necessary.
*
* @default false
*/
autoResizeFrame?: boolean;
/**
* Optionally provide a SKIK-Configuration hash that should be used
* to boot the configurator with. The configuration that's represented
* by the hash will be shown initially. If no hash is given, a default
* configuration will be shown.
*
* @default null
*/
configurationHash?: string | null;
/**
* Optionally define a language for the configurator to run in.
*
* @default 'nl'
*/
locale?: SKIKClient.AvailableLocale;
/**
* Optional boolean indicating whether or not to display a locale / language
* switch within the configurator header.
*
* @default true
*/
showLocaleSwitch?: boolean;
/**
* Optional boolean indicating whether or not to display a button to activate
* display of a product list modal.
*
* @default true
*/
showProductManifestButton?: boolean;
}
// ---------------------------------------------------------------------
// Static main module interface
// ---------------------------------------------------------------------
/**
* The static interface of this package.
*/
interface Static {
/**
* Creates a new SKIKClient instance, and returns a public API object
* to manage the configurator with, and listen for external events.
*/
create(options: SKIKClient.ConstructorOptions): SKIKClient.Client;
}
// ---------------------------------------------------------------------
// Client instance interface
// ---------------------------------------------------------------------
/**
* The public interface for a SKIKClient instance.
*/
interface Client {
/**
* Express interest in a certain event channel, and provide a function
* to call whenever that event fires, receiving the event's payload as
* first and only argument.
*
* @param {string} eventChannel
* @param {function(payload: *): void} handler
* @return {SKIKClient.EventSubscription}
*/
on<E extends EventChannel>(eventChannel: E, handler: (payload: EventPayload<E>) => void): SKIKClient.EventSubscription<E>;
/**
* Returns a promise that will in time resolve in the currently active
* configuration of the SKIK Configurator.
*
* @return {Promise<SKIKConfigurationHash>}
*/
getConfigurationHash(): Promise<SKIKConfigurationHash>;
/**
* Returns the IFrame element object in which the configurator is loaded.
*
* @return {HTMLIFrameElement}
*/
frameElement(): HTMLIFrameElement;
// ---------------------------------------------------------------------
// Display settings
// ---------------------------------------------------------------------
/**
* Enables auto-resizing of the i-frame, to keep its height a match
* with the contained document.
*
* @return {Client}
*/
enableAutoResize(): this;
/**
* Disables auto-resizing of the i-frame, to keep its height a match
* with the contained document.
*
* @return {Client}
*/
disableAutoResize(): this;
/**
* Sets the locale (language) of the configurator to given value. Text of
* the configurator is updated in real-time.
*
* @return {Client}
*/
setLocale(locale: SKIKClient.AvailableLocale): this;
/**
* Shows the locale switch at the top right, if it was not already shown.
*/
showLocaleSwitch(): this;
/**
* Hides the locale switch at the top right, if it was not already hidden.
*/
hideLocaleSwitch(): this;
/**
* Shows the locale switch at the top right, if it was not already shown.
*/
showProductManifestButton(): this;
/**
* Hides the locale switch at the top right, if it was not already hidden.
*/
hideProductManifestButton(): this;
// ---------------------------------------------------------------------
// Decorating product data
// ---------------------------------------------------------------------
/**
* Returns all EAN codes of products for which data is required, before the
* application can ensure proper calculation of configuration prices.
*/
getEANCodes(): Promise<string[]>;
/**
* Stores given product prices, and then uses it to calculate / publish the
* total price of the current configuration.
*/
setProductPrices(prices: ProductPrices[]): Promise<boolean>;
/**
* Stores given article numbers, and then uses them instead of EAN codes for
* display purposes.
*/
setArticleNumbers(articleNumbers: ArticleNumber[]): Promise<boolean>;
}
// ---------------------------------------------------------------------
// Product data interface
// ---------------------------------------------------------------------
/**
* A ProductPrices interface describes vendor-specific prices
* for a certain product, identified by its EAN product code. this
* data is optionally injected in real-time into the configurator,
* to activate automated price calculations.
*
* @see {SKIKClient.Client.setProductData}
*/
interface ProductPrices {
/**
* The EAN code for the product.
*/
EANCode: string;
/**
* The original selling price in cents, including VAT.
*/
originalPrice: number;
/**
* A discount price in cents, including VAT. If no discount should be
* applied to the product's price, discountPrice must equal originalPrice.
*/
discountPrice: number;
}
/**
*
*/
interface ArticleNumber {
EANCode: string;
articleNumber: string;
}
// ---------------------------------------------------------------------
// Price mutation reports
// ---------------------------------------------------------------------
/**
* Represents a price in cents.
*
* @property {number} cents
* @property {string} formatted
*/
interface Price {
/**
* The amount of cents this price represents
*/
readonly cents: number;
/**
* A pre-formatted string representing the price in euros (€). if
* a custom format is required, it should be manually derived from
* the cents property.
*/
readonly formatted: string;
}
/**
* The payload for 'price-changed' events.
*
* @property {{ originalPrice: Price, discountPrice: Price }} before
* @property {{ originalPrice: Price, discountPrice: Price }} after
*/
interface PriceMutationReport {
/**
* The original and discount prices before the mutation happened.
*/
readonly before: {
originalPrice: Price;
discountPrice: Price;
};
/**
* The original and discount prices after the mutation happened.
*/
readonly after: {
originalPrice: Price;
discountPrice: Price;
};
}
}