Skip to content

Commit b4bdc92

Browse files
Use the new beta nhsuk-prototype-kit (#535)
This updates the prototype to use the beta prerelease of the NHS Prototype Kit package.
1 parent 2801d96 commit b4bdc92

30 files changed

+8545
-16220
lines changed

app.js

Lines changed: 18 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -1,270 +1,37 @@
1-
// Core dependencies
2-
const {
3-
createReadStream,
4-
createWriteStream,
5-
existsSync,
6-
mkdirSync
7-
} = require('node:fs')
81
const { join } = require('node:path')
9-
const { format: urlFormat } = require('node:url')
102

11-
// External dependencies
12-
const bodyParser = require('body-parser')
13-
const sessionInCookie = require('client-sessions')
14-
const cookieParser = require('cookie-parser')
15-
const dotenv = require('dotenv')
16-
const express = require('express')
17-
const sessionInMemory = require('express-session')
18-
const nunjucks = require('nunjucks')
19-
20-
// Run before other code to make sure variables from .env are available
21-
dotenv.config({
22-
quiet: true
23-
})
3+
const NHSPrototypeKit = require('nhsuk-prototype-kit')
244

255
// Local dependencies
266
const config = require('./app/config')
7+
const sessionDataDefaults = require('./app/data/session-data-defaults')
8+
const filters = require('./app/filters')
279
const locals = require('./app/locals')
2810
const routes = require('./app/routes')
29-
const exampleTemplatesRoutes = require('./lib/example_templates_routes')
30-
const authentication = require('./lib/middleware/authentication')
31-
const automaticRouting = require('./lib/middleware/auto-routing')
32-
const production = require('./lib/middleware/production')
33-
const prototypeAdminRoutes = require('./lib/middleware/prototype-admin-routes')
34-
const utils = require('./lib/utils')
35-
const packageInfo = require('./package.json')
36-
37-
// Set configuration variables
38-
const port = parseInt(process.env.PORT || config.port, 10) || 2000
3911

40-
// Initialise applications
41-
const app = express()
42-
const exampleTemplatesApp = express()
12+
const SERVICE_NAME = config.serviceName
4313

44-
// Set up configuration variables
45-
const useAutoStoreData =
46-
process.env.USE_AUTO_STORE_DATA || config.useAutoStoreData
47-
const useCookieSessionStore =
48-
process.env.USE_COOKIE_SESSION_STORE || config.useCookieSessionStore
49-
50-
// Add variables that are available in all views
51-
app.locals.asset_path = '/public/'
52-
app.locals.useAutoStoreData = useAutoStoreData === 'true'
53-
app.locals.useCookieSessionStore = useCookieSessionStore === 'true'
54-
app.locals.serviceName = config.serviceName
55-
56-
// Use cookie middleware to parse cookies
57-
app.use(cookieParser())
14+
// Set configuration variables
15+
const port = parseInt(process.env.PORT, 10) || 2000
5816

59-
// Nunjucks configuration for application
60-
const appViews = [
17+
const viewsPath = [
6118
join(__dirname, 'app/views/'),
62-
join(__dirname, 'lib/example-templates/'),
63-
join(__dirname, 'lib/prototype-admin/'),
64-
join(__dirname, 'lib/templates/'),
65-
join(__dirname, 'node_modules/nhsuk-frontend/dist/nhsuk/components'),
66-
join(__dirname, 'node_modules/nhsuk-frontend/dist/nhsuk/macros'),
67-
join(__dirname, 'node_modules/nhsuk-frontend/dist/nhsuk'),
68-
join(__dirname, 'node_modules/nhsuk-frontend/dist'),
6919
join(__dirname, 'app/components/')
7020
]
7121

72-
/**
73-
* @type {ConfigureOptions}
74-
*/
75-
const nunjucksConfig = {
76-
autoescape: true,
77-
noCache: true
78-
}
79-
80-
nunjucksConfig.express = app
81-
82-
let nunjucksAppEnv = nunjucks.configure(appViews, nunjucksConfig)
83-
nunjucksAppEnv.addGlobal('version', packageInfo.version)
84-
85-
// Add Nunjucks filters
86-
utils.addNunjucksFilters(nunjucksAppEnv)
87-
88-
// Session uses service name to avoid clashes with other prototypes
89-
const sessionName = `nhsuk-prototype-kit-${Buffer.from(config.serviceName, 'utf8').toString('hex')}`
90-
const sessionOptions = {
91-
secret: sessionName,
92-
cookie: {
93-
maxAge: 1000 * 60 * 60 * 4 // 4 hours
94-
}
95-
}
96-
97-
if (process.env.NODE_ENV === 'production') {
98-
app.use(production)
99-
app.use(authentication)
100-
}
101-
102-
// Support session data in cookie or memory
103-
if (useCookieSessionStore === 'true') {
104-
app.use(
105-
sessionInCookie({
106-
...sessionOptions,
107-
cookieName: sessionName,
108-
proxy: true,
109-
requestKey: 'session'
110-
})
111-
)
112-
} else {
113-
app.use(
114-
sessionInMemory({
115-
...sessionOptions,
116-
name: sessionName,
117-
resave: false,
118-
saveUninitialized: false
119-
})
120-
)
121-
}
122-
123-
// Support for parsing data in POSTs
124-
app.use(bodyParser.json())
125-
app.use(
126-
bodyParser.urlencoded({
127-
extended: true
128-
})
129-
)
130-
131-
// Automatically store all data users enter
132-
if (useAutoStoreData === 'true') {
133-
app.use(utils.autoStoreData)
134-
utils.addCheckedFunction(nunjucksAppEnv)
135-
}
136-
137-
app.use(utils.setLocals)
138-
139-
// Warn if node_modules folder doesn't exist
140-
function checkFiles() {
141-
const nodeModulesExists = existsSync(join(__dirname, '/node_modules'))
142-
if (!nodeModulesExists) {
143-
throw new Error(
144-
'ERROR: Node module folder missing. Try running `npm install`'
145-
)
146-
}
147-
148-
// Create template .env file if it doesn't exist
149-
const envExists = existsSync(join(__dirname, '/.env'))
150-
if (!envExists) {
151-
createReadStream(join(__dirname, '/lib/template.env')).pipe(
152-
createWriteStream(join(__dirname, '/.env'))
153-
)
22+
const prototype = NHSPrototypeKit.init({
23+
serviceName: SERVICE_NAME,
24+
routes: routes,
25+
locals: locals,
26+
sessionDataDefaults: sessionDataDefaults,
27+
viewsPath: viewsPath,
28+
buildOptions: {
29+
entryPoints: ['app/assets/sass/main.scss']
15430
}
155-
}
156-
157-
// initial checks
158-
checkFiles()
159-
160-
// Create template session data defaults file if it doesn't exist
161-
const dataDirectory = join(__dirname, '/app/data')
162-
const sessionDataDefaultsFile = join(dataDirectory, '/session-data-defaults.js')
163-
const sessionDataDefaultsFileExists = existsSync(sessionDataDefaultsFile)
164-
165-
if (!sessionDataDefaultsFileExists) {
166-
console.log('Creating session data defaults file')
167-
if (!existsSync(dataDirectory)) {
168-
mkdirSync(dataDirectory)
169-
}
170-
171-
createReadStream(
172-
join(__dirname, '/lib/template.session-data-defaults.js')
173-
).pipe(createWriteStream(sessionDataDefaultsFile))
174-
}
175-
176-
// Local variables
177-
app.use(locals(config))
178-
179-
// View engine
180-
app.set('view engine', 'html')
181-
exampleTemplatesApp.set('view engine', 'html')
182-
183-
// This setting trusts the X-Forwarded headers set by
184-
// a proxy and uses them to set the standard header in
185-
// req. This is needed for hosts like Heroku.
186-
// See https://expressjs.com/en/guide/behind-proxies.html
187-
app.set('trust proxy', 1)
188-
189-
// Use public folder for static assets
190-
app.use(express.static(join(__dirname, 'public')))
191-
192-
// Use assets from NHS frontend
193-
app.use(
194-
'/nhsuk-frontend',
195-
express.static(join(__dirname, 'node_modules/nhsuk-frontend/dist/nhsuk'))
196-
)
197-
198-
// Use custom application routes
199-
app.use('/', routes)
200-
201-
// Automatically route pages
202-
app.get(/^([^.]+)$/, (req, res, next) => {
203-
automaticRouting.matchRoutes(req, res, next)
204-
})
205-
206-
// Example template routes
207-
app.use('/example-templates', exampleTemplatesApp)
208-
209-
nunjucksAppEnv = nunjucks.configure(appViews, {
210-
autoescape: true,
211-
express: exampleTemplatesApp
21231
})
213-
nunjucksAppEnv.addGlobal('version', packageInfo.version)
21432

215-
// Add Nunjucks filters
216-
utils.addNunjucksFilters(nunjucksAppEnv)
217-
218-
exampleTemplatesApp.use('/', exampleTemplatesRoutes)
219-
220-
// Automatically route example template pages
221-
exampleTemplatesApp.get(/^([^.]+)$/, (req, res, next) => {
222-
automaticRouting.matchRoutes(req, res, next)
223-
})
224-
225-
app.use('/prototype-admin', prototypeAdminRoutes)
226-
227-
// Redirect all POSTs to GETs - this allows users to use POST for autoStoreData
228-
app.post(/^\/([^.]+)$/, (req, res) => {
229-
res.redirect(
230-
urlFormat({
231-
pathname: `/${req.params[0]}`,
232-
query: req.query
233-
})
234-
)
235-
})
236-
237-
// Catch 404 and forward to error handler
238-
app.use((req, res, next) => {
239-
const err = new Error(`Page not found: ${req.path}`)
240-
err.status = 404
241-
next(err)
242-
})
243-
244-
// Display error
245-
app.use((err, req, res) => {
246-
console.error(err.message)
247-
res.status(err.status || 500)
248-
res.send(err.message)
249-
})
250-
251-
// Run the application
252-
app.listen(port)
253-
254-
if (
255-
process.env.WATCH !== 'true' && // If the user isn’t running watch
256-
process.env.NODE_ENV !== 'production' // and it’s not in production mode
257-
) {
258-
console.info(`Running at http://localhost:${port}/`)
259-
console.info('')
260-
console.warn(
261-
'Warning: It looks like you may have run the command `npm start` locally.'
262-
)
263-
console.warn('Press `Ctrl+C` and then run `npm run watch` instead')
33+
for (const [name, filter] of Object.entries(filters())) {
34+
prototype.nunjucks.addFilter(name, filter)
26435
}
26536

266-
module.exports = app
267-
268-
/**
269-
* @import { ConfigureOptions } from 'nunjucks'
270-
*/
37+
prototype.start(port)

app/assets/javascript/auto-store-data.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

app/config.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ module.exports = {
44
// Service name
55
serviceName: 'Record a vaccination',
66

7-
// Port to run nodemon on locally
8-
port: 2000,
9-
10-
// Automatically stores form data, and send to all views
11-
useAutoStoreData: 'true',
12-
13-
// Enable cookie-based session store (persists on restart)
14-
// Please note 4KB cookie limit per domain, cookies too large will silently be ignored
15-
useCookieSessionStore: 'false',
16-
17-
// Enable or disable built-in docs and examples.
18-
useDocumentation: true,
19-
};
7+
// Port to run the prototype on locally
8+
port: 2000
9+
}

app/locals.js

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,21 @@
1-
/**
2-
* @param {typeof config} config
3-
*/
4-
module.exports =
5-
(config) =>
6-
/**
7-
* @param {Request} req
8-
* @param {Response} res
9-
* @param {NextFunction} next
10-
*/
11-
(req, res, next) => {
12-
res.locals.serviceName = config.serviceName
1+
module.exports = function(req, res, next) {
132

143
// Set currentUser for convenience
154
if (req.session.data.currentUserId) {
165
res.locals.currentUser = req.session.data.users.find((user) => user.id === req.session.data.currentUserId)
176
} else {
187
res.locals.currentUser = null
198
}
20-
219
// Set currentOrganisation for convenience
2210
if (req.session.data.currentOrganisationId) {
2311
res.locals.currentOrganisation = req.session.data.organisations.find((organisation) => organisation.id === req.session.data.currentOrganisationId)
2412
} else {
2513
res.locals.currentOrganisation = null
2614
}
2715

28-
next()
29-
}
16+
// set current logged in region
17+
// res.locals.currentRegion = req.session.data.regions.find((region) => region.id === req.session.data.currentRegionId);
18+
19+
next()
20+
}
3021

31-
/**
32-
* @import { NextFunction, Request, Response } from 'express'
33-
* @import config from './config.js'
34-
*/

app/routes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// External dependencies
2+
3+
/* eslint n/no-extraneous-require: "off" */
24
const express = require('express');
35

46
const router = express.Router();

0 commit comments

Comments
 (0)