UNPKG

@dwp/govuk-casa

Version:

A framework for building GOVUK Collect-And-Submit-Applications

418 lines (417 loc) 15.4 kB
/** * @typedef {import("../casa").ContextEventUserInfo} ContextEventUserInfo * @access private */ /** * @typedef {import("../casa").Page} Page * @access private */ /** * @typedef {import("../casa").ContextEventHandler} ContextEventHandler * @access private */ /** * @typedef {import("../casa").ContextEvent} ContextEvent * @access private */ /** * @typedef {import("../casa").JourneyContextObject} JourneyContextObject * @access private */ /** * @typedef {import("express").Request} ExpressRequest * @access private */ /** * @param {any} key Object key to validate * @returns {string} Validated key */ export function validateObjectKey(key?: any): string; /** @memberof module:@dwp/govuk-casa */ export default class JourneyContext { static DEFAULT_CONTEXT_ID: string; /** @type {symbol} */ static ID_GENERATOR_REQ_LOG: symbol; /** @type {symbol} */ static ID_GENERATOR_REQ_KEY: symbol; /** * Create a new JourneyContext using the plain object. * * @param {JourneyContextObject} obj Object. * @returns {JourneyContext} Instance. */ static fromObject({ data, validation, nav, identity, }?: JourneyContextObject): JourneyContext; /** * Construct a new ephemeral JourneyContext instance with a unique ID. * * Note: In later versions of CASA, the `req` property will be mandatory. * * @param {ExpressRequest} [req] Request session * @returns {JourneyContext} Constructed JourneyContext instance */ static createEphemeralContext(req?: ExpressRequest): JourneyContext; /** * Construct a new JourneyContext instance from another instance. * * Note: In later versions of CASA, the `req` property will be mandatory. * * @param {JourneyContext} context Context to copy from * @param {ExpressRequest} [req] Request * @returns {JourneyContext} Constructed JourneyContext instance * @throws {TypeError} When context is not a valid type */ static fromContext(context: JourneyContext, req?: ExpressRequest): JourneyContext; /** * Initialise session with an empty entry for the "default" context. * * @param {object} session Request session * @returns {void} */ static initContextStore(session: object): void; /** * Validate the format of a context ID: * * - Between 1 and 64 characters * - Contain only the characters a-z, 0-9, - * * @param {string} id Context ID * @returns {string} Original ID if it's valid * @throws {TypeError} When id is not a valid type * @throws {SyntaxError} When id is not a valid format */ static validateContextId(id: string): string; /** * Generate a new context ID, validate it, and throw if the ID has already * been generated during this request lifecycle. This may happen if an ID was * generated, but never used to store a new context in the session. Therefore * it is important for user code to always call `putContext()` before * generating another ID. * * @param {ExpressRequest} [req] Request * @returns {string} New ID * @throws {Error} When generated ID has already been used */ static generateContextId(req?: ExpressRequest): string; /** * Retrieve the default Journey Context. This is just a convenient wrapper * around `getContextById()`. * * @param {object} session Request session * @returns {JourneyContext} The default Journey Context */ static getDefaultContext(session: object): JourneyContext; /** * Lookup context from session using the ID. * * @param {object} session Request session * @param {string} id Context ID * @returns {JourneyContext} The discovered JourneyContext instance */ static getContextById(session: object, id: string): JourneyContext; /** * Lookup context from session using the name. * * @param {object} session Request session * @param {string} name Context name * @returns {JourneyContext} The discovered JourneyContext instance */ static getContextByName(session: object, name: string): JourneyContext; /** * Lookup contexts from session using the tag. * * @param {object} session Request session * @param {string} tag Context tag * @returns {JourneyContext[]} The discovered JourneyContext instance */ static getContextsByTag(session: object, tag: string): JourneyContext[]; /** * Return all contexts currently stored in the session. * * @param {object} session Request session * @returns {Array} Array of contexts */ static getContexts(session: object): any[]; /** * Put context back into the session store. * * @param {object} session Request session * @param {JourneyContext} context Context * @param {object} options Options * @param {ContextEventUserInfo | object} [options.userInfo] Pass-through * event info * @returns {void} * @throws {TypeError} When session is not a valid type, or context has no ID */ static putContext(session: object, context: JourneyContext, options?: { userInfo?: object | import("../casa").ContextEventUserInfo | undefined; }): void; /** * Remove a context from the session store. * * @param {object} session Request session * @param {JourneyContext} context Context * @returns {void} */ static removeContext(session: object, context: JourneyContext): void; /** * Remove context from session using the ID. * * @param {object} session Request session * @param {string} id Context ID * @returns {void} */ static removeContextById(session: object, id: string): void; /** * Remove context from session using the name. * * @param {object} session Request session * @param {string} name Context name * @returns {void} */ static removeContextByName(session: object, name: string): void; /** * Remove context from session using the tag. * * @param {object} session Request session * @param {string} tag Context tag * @returns {void} */ static removeContextsByTag(session: object, tag: string): void; /** * Remove call contexts. * * @param {object} session Request session * @returns {void} */ static removeContexts(session: object): void; /** * Extract the Journey Context referred to in the incoming request. * * This will look in `req.params`, `req.query` and `req.body` for a * `contextid` parameter, and use that to load the correct Journey Context * from the session. * * @param {ExpressRequest} req ExpressJS incoming request * @returns {JourneyContext} The Journey Context */ static extractContextFromRequest(req: ExpressRequest): JourneyContext; /** * Constructor. * * `data` is the "single source of truth" for all data gathered during the * user's journey. This is referred to as the "canonical data model". * Page-specific "views" of this data are generated at runtime in order to * populate/validate specific form fields. * * `validation` holds the results of form field validation carried out when * page forms are POSTed. These results are mapped directly to per-page, * per-field. * * `nav` holds information about the current navigation state. Currently this * comprises of the language in which the user is navigating the service. * * `identity` holds information that helps uniquely identify this context * among a group of contexts stored in the session. * * @param {Record<string, any>} data Entire journey data. * @param {object} validation Page errors (indexed by waypoint id). * @param {object} nav Navigation context. * @param {object} identity Some metadata for identifying this context among * others. */ constructor(data?: Record<string, any>, validation?: object, nav?: object, identity?: object); /** * Clone into an object that can be stringified. * * @returns {JourneyContextObject} Plain object. */ toObject(): JourneyContextObject; configureFromObject(object: any): void; set data(value: Record<string, any>); get data(): Record<string, any>; get validation(): object; get nav(): object; get identity(): object; /** * Get data context for a specific a specific page. * * @param {string | Page} page Page waypoint ID, or Page object. * @returns {object} Page data. * @throws {TypeError} When page is invalid. */ getDataForPage(page: string | Page): object; /** * Get all data. * * @returns {object} Page data */ getData(): object; /** * Overwrite the data context with a new object. * * @param {object} data Data that will overwrite all existing data. * @returns {JourneyContext} Chain. */ setData(data: object): JourneyContext; /** * Write field form data from a page HTML form, into the `data` model. * * @param {string | Page} page Page waypoint ID, or Page object * @param {object} webFormData Data to overwrite with * @returns {JourneyContext} Chain * @throws {TypeError} When page is invalid. */ setDataForPage(page: string | Page, webFormData: object): JourneyContext; /** * Return validation errors for all pages. * * @returns {object} All page validation errors. */ getValidationErrors(): object; /** * Removes any validation state for the given page. Clearing validation state * completely will, by default, prevent onward traversal from this page. See * the traversal logic in Plan class. * * @param {string} pageId Page ID. * @returns {JourneyContext} Chain. */ removeValidationStateForPage(pageId: string): JourneyContext; /** * Clear any validation errors for the given page. This effectively declares * that this page has been successfully validated, and so can be traversed. If * you want to remove any knowledge of validation success/failure, use * `removeValidationStateForPage()` instead. * * @param {string} pageId Page ID. * @returns {JourneyContext} Chain. */ clearValidationErrorsForPage(pageId: string): JourneyContext; /** * Set validation errors for a page. * * @param {string} pageId Page ID. * @param {ValidationError[]} errors Errors * @returns {JourneyContext} Chain. * @throws {SyntaxError} When errors are invalid. */ setValidationErrorsForPage(pageId: string, errors?: ValidationError[]): JourneyContext; /** * Return the validation errors associated with the page's currently held data * context (if any). * * @param {string} pageId Page ID. * @returns {ValidationError[]} An array of errors */ getValidationErrorsForPage(pageId: string): ValidationError[]; /** * Same as `getValidationErrorsForPage()`, but the return value is an object * whose keys are the field names, and values are the list of errors * associated with that particular field. * * @param {string} pageId Page ID. * @returns {object} Object indexed by field names; values containing list of * errors */ getValidationErrorsForPageByField(pageId: string): object; /** * Determine whether the specified page has any errors in its validation * context. * * @param {string} pageId Page ID. * @returns {boolean} Result. */ hasValidationErrorsForPage(pageId: string): boolean; /** * Set language of the context. * * @param {string} language Language to set (ISO 639-1 2-letter code). * @returns {JourneyContext} Chain. */ setNavigationLanguage(language?: string): JourneyContext; /** * Convenience function to test if page is valid. * * @param {string} pageId Page ID. * @returns {boolean} True if the page is valid. */ isPageValid(pageId: string): boolean; /** * Remove information about these waypoints. * * @param {string[]} waypoints Waypoints to be removed */ purge(waypoints?: string[]): void; /** * Remove validation state from these waypoints. This is useful to quickly * force the user to revisit some waypoints. * * @param {string[]} waypoints Waypoints to be invalidated * @returns {void} */ invalidate(waypoints?: string[]): void; /** * Event listeners are transient. They are not stored in session, and * generally only apply for the current request. * * They also only act on a fixed snapshot of this context's state, which is * taken at the point of attaching the listeners (in the "data" middleware). * This is important because JourneyContext.putContext()` could be called many * times during a request, so the context will be constantly changing. * * @param {ContextEvent[]} events Event listeners * @returns {JourneyContext} Chain */ addEventListeners(events: ContextEvent[]): JourneyContext; /** * Execute all listeners for the given event. * * The `userInfo` parameter is simply passed straight through to the event * listeners. * * @param {object} params Params * @param {string} params.event Event (waypoint-change | context-change) * @param {object} params.session Session * @param {ContextEventUserInfo | object} [params.userInfo] Pass-through info * @returns {JourneyContext} Chain */ applyEventListeners({ event, session, userInfo }: { event: string; session: object; userInfo?: object | import("../casa").ContextEventUserInfo | undefined; }): JourneyContext; /** * Convenience method to determine if this is the default context. * * @returns {boolean} True if this is the "default" journey context */ isDefault(): boolean; /** * Set page skipped status. * * @param {string} waypoint Waypoint to skip. * @param {boolean | object} opts Is skipped flag or options. * @param {string} opts.to Waypoint to skip to. */ setSkipped(waypoint: string, opts: boolean | object): void; /** * Tests if a page has been skipped. * * @param {string} waypoint Page ID (waypoint). * @param {object} opts Skip ptions. * @param {string} opts.to Waypoint that should be skipped to. * @returns {boolean} True if the page has been skipped, or if it has been * skipped to a specific page. */ isSkipped(waypoint: string, opts: { to: string; }): boolean; #private; } export type ContextEventUserInfo = import("../casa").ContextEventUserInfo; export type Page = import("../casa").Page; export type ContextEventHandler = import("../casa").ContextEventHandler; export type ContextEvent = import("../casa").ContextEvent; export type JourneyContextObject = import("../casa").JourneyContextObject; export type ExpressRequest = import("express").Request; import ValidationError from "./ValidationError.js";