@dwp/govuk-casa
Version:
A framework for building GOVUK Collect-And-Submit-Applications
391 lines • 16.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.corePlugins = exports.contextIdGenerators = exports.constants = exports.nunjucksFilters = exports.generateGovukErrors = exports.endSession = exports.waypointUrl = exports.MutableRouter = exports.ValidationError = exports.ValidatorFactory = exports.JourneyContext = exports.Plan = exports.field = exports.validators = exports.configure = void 0;
// NOTE: Any changes made here must be reflected in `scripts/esm-wrapper.js`
const configure_js_1 = __importDefault(require("./lib/configure.js"));
exports.configure = configure_js_1.default;
const index_js_1 = __importDefault(require("./lib/validators/index.js"));
exports.validators = index_js_1.default;
const field_js_1 = __importDefault(require("./lib/field.js"));
exports.field = field_js_1.default;
const Plan_js_1 = __importDefault(require("./lib/Plan.js"));
exports.Plan = Plan_js_1.default;
const JourneyContext_js_1 = __importDefault(require("./lib/JourneyContext.js"));
exports.JourneyContext = JourneyContext_js_1.default;
const ValidatorFactory_js_1 = __importDefault(require("./lib/ValidatorFactory.js"));
exports.ValidatorFactory = ValidatorFactory_js_1.default;
const ValidationError_js_1 = __importDefault(require("./lib/ValidationError.js"));
exports.ValidationError = ValidationError_js_1.default;
const MutableRouter_js_1 = __importDefault(require("./lib/MutableRouter.js"));
exports.MutableRouter = MutableRouter_js_1.default;
const waypoint_url_js_1 = __importDefault(require("./lib/waypoint-url.js"));
exports.waypointUrl = waypoint_url_js_1.default;
const end_session_js_1 = __importDefault(require("./lib/end-session.js"));
exports.endSession = end_session_js_1.default;
const journey_js_1 = require("./routes/journey.js");
Object.defineProperty(exports, "generateGovukErrors", { enumerable: true, get: function () { return journey_js_1.generateGovukErrors; } });
const nunjucksFilters = __importStar(require("./lib/nunjucks-filters.js"));
exports.nunjucksFilters = nunjucksFilters;
const constants = __importStar(require("./lib/constants.js"));
exports.constants = constants;
const contextIdGenerators = __importStar(require("./lib/context-id-generators.js"));
exports.contextIdGenerators = contextIdGenerators;
const corePlugins = __importStar(require("./core-plugins/index.js"));
exports.corePlugins = corePlugins;
/* ----------------------------------------------------------------- Typedefs */
// These exist here so that consumer can import CASA's internal types
/** @typedef {import("./lib/field").PageField} PageField */
/**
* @typedef {object} ContextEventHandlerOptions
* @property {JourneyContext} journeyContext Context including changes
* @property {JourneyContext} previousContext Context prior to changes
* @property {object} session Request session object
* @property {ContextEventUserInfo} userInfo User-space information pass-through
*/
/**
* @callback ContextEventHandler
* @param {ContextEventHandlerOptions} opts Options
* @returns {void}
*/
/**
* @typedef {object} ContextEventUserInfo
* @property {symbol} [casaRequestPhase] Request phase at which event is
* triggered
*/
/**
* @typedef {object} ContextEvent
* @property {string} waypoint Waypoint to watch for changes
* @property {string} [field] Field to watch for changes
* @property {ContextEventHandler} handler Handler to invoke when change happens
*/
/**
* @typedef {object} Page Page configuration. A Page is the interactive
* representation of a waypoint
* @property {string} waypoint The waypoint with which this page is associated
* @property {string} view Template path
* @property {PageHook[]} [hooks=[]] Page-specific hooks (optional, default []).
* Default is `[]`
* @property {PageField[]} [fields=[]] Fields to be managed on this page
* (optional, default []). Default is `[]`
*/
/**
* @typedef {object} I18nOptions
* @property {string[]} dirs Directories to search for locale dictionaries
* @property {string | false} [fallbackLng=false] Fallback language to use if
* translations aren't available for a given key. Default is `false`
* @property {string[]} [locales=['en', 'cy']] Supported locales. Default is
* `['en', 'cy']`
*/
/**
* @typedef {object} GlobalHook Hook configuration
* @property {string} hook Hook name in format `<router>.<hook>`
* @property {Function} middleware Middleware function to insert at the hook
* point
* @property {string | RegExp} [path=undefined] Only run if route path matches
* this string/regexp. Default is `undefined`
*/
/**
* @typedef {object} PageHook (extends GlobalHook)
* @property {string} hook Hook name (without a scope prefix)
* @property {Function} middleware Middleware function to insert at the hook
* point
*/
/**
* @typedef {object} SessionOptions
* @property {string} [name=casasession] Session name. Default is `casasession`
* @property {string} [secret=secret] Encryption secret. Default is `secret`
* @property {number} [ttl=3600] Session ttl (seconds). Default is `3600`
* @property {boolean} [secure=false] Whether to use secure session cookies.
* Default is `false`
* @property {boolean | string} [cookieSameSite=true] SameSite (true = Strict).
* Default is `true`
* @property {object} [store] Session store (default MemoryStore)
* @property {string} [cookiePath] The URL path on which the session cookie is
* valid (defaults to '/')
*/
/**
* @typedef {object} IPlugin Plugin interface
* @property {PluginConfigureFunction} [configure] Modify the app config
* @property {PluginBootstrapFunction} [bootstrap] Modify post-configuration
* artifacts
*/
/**
* @callback PluginConfigureFunction
* @param {ConfigurationOptions} config Options
*/
/**
* @callback PluginBootstrapFunction
* @param {ConfigureResult} config Options
*/
/**
* @callback HelmetConfigurator
* @param {object} config A default Helmet configuration provided by CASA
* @returns {object} The modified configuration object
*/
/**
* Mounting function.
*
* This will mount all of the routes and middleware in the correct order on the
* given ExpressJS app.
*
* Once this is called, you will not be able to modify any of the routers as
* they will be "sealed".
*
* @callback Mounter
* @param {import("express").Express} app Express application
* @param {object} opts Mounting options
* @param {string} [opts.route='/'] Optional route to attach all
* middleware/routers too. Default is `'/'`
* @returns {import("express").Express} The prepared ExpressJS app instance
*/
/**
* Configure some middleware for use in creating a new CASA app.
*
* @typedef {object} ConfigurationOptions Configuration options
* @property {string} [mountUrl] Prefix for all URLS in browser address bar
* @property {string[]} [views=[]] Template directories. Default is `[]`
* @property {SessionOptions} [session] Session configuration
* @property {Page[]} [pages=[]] Pages the represent waypoints. Default is `[]`
* @property {GlobalHook[]} [hooks=[]] Hooks to apply. Default is `[]`
* @property {IPlugin[]} [plugins=[]] Plugins. Default is `[]`
* @property {I18nOptions} [i18n] I18n configuration
* @property {Plan} [plan] CASA Plan
* @property {ContextEvent[]} [events=[]] Handlers for JourneyContext events.
* Default is `[]`
* @property {HelmetConfigurator} [helmetConfigurator] Helmet configuration
* manipulator function
* @property {number} [formMaxParams=25] Max number of form parameters to
* ingest. Default is `25`
* @property {number | string} [formMaxBytes="50KB"] Max total form payload size
* to ingest. Default is `"50KB"`
* @property {ContextIdGenerator} [contextIdGenerator] Custom context ID
* generator
* @property {symbol | Function} [errorVisibility] Option to keep page errors
* active on GET request
* @property {boolean} [govukRebrand=false] Sets whether you wish to use the
* govuk rebrand. Default is `false`
*/
/**
* @typedef {object} ConfigureResult Result of a call to configure() function
* @property {import("nunjucks").Environment} nunjucksEnv Nunjucks environment
* @property {MutableRouter} staticRouter Router handling all static assets
* @property {MutableRouter} ancillaryRouter Router handling ancillary routes
* @property {MutableRouter} journeyRouter Router handling all waypoint requests
* @property {import("express").RequestHandler[]} preMiddleware Middleware
* mounted before everything
* @property {import("express").RequestHandler[]} postMiddleware Middleware
* mounted after everything
* @property {import("express").RequestHandler[]} csrfMiddleware CSRF get/set
* form middleware
* @property {import("express").RequestHandler} sessionMiddleware Session
* middleware
* @property {import("express").RequestHandler[]} cookieParserMiddleware
* Cookie-parsing middleware
* @property {import("express").RequestHandler[]} i18nMiddleware I18n
* preparation middleware
* @property {import("express").RequestHandler} bodyParserMiddleware Body
* parsing middleware
* @property {Mounter} mount Function used to mount all CASA artifacts onto an
* ExpressJS app
* @property {ConfigurationOptions} config Ingested config supplied to
* `configure()`
*/
/**
* Configuration for generating a ValidationError. i.e. `new
* ValidationError(configObject)` <br/><br/>
*
* The `fieldKeySuffix` is used to differentiate errors attached to the same
* field name. For example, given these fields inputs ...<pre> <input
* name="dateOfBirth[dd]" /> <input name="dateOfBirth[mm]" /> <input
* name="dateOfBirth[yyyy]" /> </pre>
*
* If we wanted to generate an error specifically for the `dd` element, then
* we'd include `{ fieldKeySuffix: '[dd]' }` in this config. <br/><br/>
*
* We can also use `focusSuffix` to control which properties of an object field
* should be highlighted with a red border when in error. Looking again at the
* `dateOfBirth` example above, if we did not specify any `focusSuffix`, then
* all three inputs would be highlighted. However, if we use `{ focusSuffix:
* ['[dd]', '[yyyy]'] }` then only the `[dd]` and `[yyyy]` inputs would be
* highlighted. <br/><br/>
*
* The `fieldHref` and `field` properties are strictly for internal use only and
* public access may be removed at any point.
*
* @typedef {object} ErrorMessageConfigObject
* @property {string} summary Summary message
* @property {string} [inline] Inline message (@deprecated now uses summary
* everywhere)
* @property {string | string[]} [focusSuffix] String(s) to append to URL hash
* for focusing inputs
* @property {string} [fieldKeySuffix] Object fields may use this to show errors
* per sub-property
* @property {object | ErrorMessageVariablesGenerator} [variables]
* Interpolation variables
* @property {string} [validator] Name of the validator
* @property {string} [fieldHref] (internal) URL hash to link to field in UI,
* i.e `#f-..`
* @property {string} [field] (internal) Field name, including any focus suffix
*/
/**
* Function to generate interpolation variables for injecting into the error
* message string.
*
* @callback ErrorMessageVariablesGenerator
* @param {ValidateContext} dataContext Data context
* @returns {object} Variables name:value hash
*/
/**
* @callback ErrorMessageConfigGenerator
* @param {ValidateContext} dataContext Data context
* @returns {string | ErrorMessageConfigObject} Compiled error message config
*/
/**
* @typedef {string
* | ErrorMessageConfigObject
* | ErrorMessageConfigGenerator
* | Error} ErrorMessageConfig
*/
/**
* @typedef {object} ValidateContext Context passed to validate function
* @property {JourneyContext} journeyContext Journey context
* @property {string} waypoint Waypoint
* @property {string} fieldName Name of field being processed
* @property {any} [fieldValue] Current value of the field being validated
* @property {string} [validator] Name of the validator
*/
/**
* @callback ValidateFunction
* @param {any} value
* @param {ValidateContext} context Validation context
* @returns {ValidationError[]}
*/
/**
* @callback FieldProcessorFunction
* @param {any} value Value to be processed
* @returns {any}
*/
/**
* @typedef {object} Validator
* @property {ValidateFunction} validate Validation function
* @property {FieldProcessorFunction} sanitise Sanitise a given value prior to
* validation
* @property {object} config Configuration
* @property {string} name Validator name
*/
/**
* @typedef {object} ValidatorConditionFunctionParams
* @property {string} fieldName Field name
* @property {any} fieldValue Field value
* @property {string} waypoint Waypoint
* @property {JourneyContext} journeyContext Journey Context
*/
/**
* Condition functions are executed unbound.
*
* @callback ValidatorConditionFunction
* @param {ValidatorConditionFunctionParams} context Value to be processed
* @returns {boolean} True if the validators should be run
*/
/**
* @typedef {object} PlanRoute
* @property {string} source Source waypoint
* @property {string} target Target waypoint
* @property {string} name Name
* @property {string} label Label
*/
/**
* @callback PlanRouteCondition
* @param {PlanRoute} route Route metadata
* @param {JourneyContext} context Journey Context
* @returns {boolean} Returns true is route should be followed
*/
/**
* @typedef PlanTraverseOptions
* @property {string} [startWaypoint] Waypoint from which to start (defaults to
* first in list)
* @property {string} routeName Follow routes matching this name (next | prev)
* @property {Map} history Used to detect loops in traversal (INTERNAL USE ONLY)
* @property {Function} [stopCondition] If true, traversal will be stopped
* (useful for performance)
* @property {string | PlanArbiter} [arbiter] Multiple target routes found, this
* decides which to use
*/
/**
* @typedef {object} PlanArbiterParams
* @property {PlanRoute[]} targets Potential target routes that need arbitration
* @property {JourneyContext} journeyContext Journey Context
* @property {PlanTraverseOptions} traverseOptions Original traverse options
* passed to `traverse()`
*/
/**
* @callback PlanArbiter
* @param {PlanArbiterParams} route Route metadata
* @returns {PlanRoute[]} Returns all routes, excluding those that the arbiter
* could eliminate
*/
/**
* @typedef {object} JourneyContextObject Journey Context Object
* @property {Record<string, any>} [data] Data
* @property {any} [validation] Validation state
* @property {any} [nav] Navigation meta
* @property {any} [identity] Identity meta
*/
/**
* @typedef ContextIdGeneratorParams
* @property {object} args Arguments
* @property {import("express").Request} args.req Request
* @property {[string]} args.reservedIds List of IDs already in use in session
* or request
*/
/**
* Generates a GUID for use as a journey context ID. This ID must not clash with
* any other context IDs in the given session.
*
* The resulting ID must match these criteria:
*
* - A string
* - Between 1 and 64 characters
* - Contain only the characters a-z, 0-9, -
*
* @callback ContextIdGenerator
* @param {ContextIdGeneratorParams} params Parameters
* @returns {string} A newly generated GUID
*/
//# sourceMappingURL=casa.js.map