Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error server /manage-prototype/dependencies #2333

Merged
merged 7 commits into from
Sep 14, 2023
2 changes: 0 additions & 2 deletions lib/assets/sass/manage-prototype.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
$govuk-assets-path: '/manage-prototype/dependencies/govuk-frontend/govuk/assets/';

// Import GOV.UK Frontend within the kit dependency
@import ".tmp/sass/kit-frontend-dependency";

Expand Down
1 change: 0 additions & 1 deletion lib/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const allowedPathsWhenUnauthenticated = [
'/manage-prototype/password',
'/public/stylesheets/unbranded.css',
'/plugin-assets/govuk-prototype-kit/lib/assets/images/unbranded.ico',
'/plugin-assets/govuk-frontend/govuk/all.js',
// Keep /extension-assets path for backwards compatibility
// TODO: remove in v14
'/extension-assets/govuk-prototype-kit/lib/assets/images/unbranded.ico']
Expand Down
49 changes: 36 additions & 13 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,18 @@ function sassInclude (filePath) {

function sassKitFrontendDependency () {
const timer = startPerformanceTimer()

const internalGovUkFrontendDir = getInternalGovukFrontendDir()
const internalGovUkFrontendConfig = fse.readJsonSync(path.join(internalGovUkFrontendDir, 'govuk-prototype-kit.config.json'))
const fileContents = internalGovUkFrontendConfig.sass

const govukFrontendSass = internalGovUkFrontendConfig.sass
.map(sassPath => path.join(internalGovUkFrontendDir, sassPath))
.map(sassInclude)
.join('\n')

const fileContents = sassVariables('/manage-prototype/dependencies') +
govukFrontendSass
.map(sassInclude)
.join('\n')

ensureTempDirExists(tmpSassDir)
fse.writeFileSync(path.join(tmpSassDir, '_kit-frontend-dependency.scss'), fileContents)
endPerformanceTimer('sassKitFrontendDependency', timer)
Expand All @@ -116,37 +122,53 @@ function sassLegacyPatterns () {
.join('\n')
} else {
fileContents = `
/* Legacy patterns not included as govuk-frontend plugin not installed */
/* Legacy patterns not included as govuk-frontend plugin not installed */
`
}
fse.writeFileSync(path.join(tmpSassDir, '_legacy-patterns.scss'), fileContents)
endPerformanceTimer('sassLegacyPatterns', timer)
}

function sassPlugins () {
const timer = startPerformanceTimer()
function sassVariables (contextPath = '', isLegacyGovukFrontend = false) {
let fileContents = ''

// Keep $govuk-extensions-url-context for backwards compatibility
// TODO: remove in v14
fileContents += '$govuk-extensions-url-context: "/plugin-assets";\n'
fileContents += '$govuk-plugins-url-context: "/plugin-assets";\n'
fileContents += `$govuk-extensions-url-context: "${contextPath}";\n`
fileContents += `$govuk-plugins-url-context: "${contextPath}";\n`
fileContents += '$govuk-prototype-kit-major-version: 13;\n'
if (plugins.legacyGovukFrontendFixesNeeded()) {

// Patch missing 'init.scss' before GOV.UK Frontend v4.4.0
// in plugin versions, but will default to false for internal
if (isLegacyGovukFrontend) {
fileContents += '$govuk-assets-path: $govuk-extensions-url-context + "/govuk-frontend/govuk/assets/";\n'
fileContents += '$govuk-global-styles: true !default;\n'
fileContents += '$govuk-new-link-styles: true !default;\n'
}
fileContents += plugins.getFileSystemPaths('sass')
.map(sassInclude)
.join('\n')

return fileContents
}

function sassPlugins () {
const timer = startPerformanceTimer()

const fileContents = sassVariables('/plugin-assets', plugins.legacyGovukFrontendFixesNeeded()) +
plugins.getFileSystemPaths('sass')
.map(sassInclude)
.join('\n')

ensureTempDirExists(tmpSassDir)
fse.writeFileSync(path.join(tmpSassDir, '_plugins.scss'), fileContents)
endPerformanceTimer('sassPlugins', timer)
}

function sassErrorPage () {
const timer = startPerformanceTimer()

const fileContents = sassVariables('/manage-prototype/dependencies') +
sassInclude(path.join(libSassDir, 'includes', '_error-page.scss'))

ensureTempDirExists(tmpSassDir)
const fileContents = sassInclude(path.join(libSassDir, 'includes', '_error-page.scss'))
fse.writeFileSync(path.join(tmpSassDir, 'error-page.scss'), fileContents)
endPerformanceTimer('sassErrorPage', timer)
}
Expand Down Expand Up @@ -176,6 +198,7 @@ function _generateCssSync (sassPath, cssPath, options = {}) {
quietDeps: true,
loadPaths: [projectDir],
sourceMap: true,
sourceMapIncludeSources: true,
style: 'expanded'
})

Expand Down
46 changes: 33 additions & 13 deletions lib/errorServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,27 @@ function runErrorServer (error) {
const proxyPort = port - 50
const http = require('http')
const fileExtensionsToMimeTypes = {
js: 'application/javascript',
css: 'text/css'
css: 'text/css',
ico: 'image/x-icon',
js: 'text/javascript',
map: 'application/json',
mjs: 'text/javascript',
png: 'image/png',
svg: 'image/svg+xml',
woff: 'application/font-woff',
woff2: 'application/font-woff2'
}

const knownPaths = {
'/public/stylesheets/application.css': {
'/public/stylesheets/manage-prototype.css': {
type: 'text/css',
contents: fs.readFileSync(path.join(process.cwd(), '.tmp', 'public', 'stylesheets', 'manage-prototype.css'))
}
}

/**
* @type {http.RequestListener}
*/
const requestListener = function (req, res) {
if (req.url.startsWith('/browser-sync')) {
return
Expand All @@ -51,25 +61,35 @@ function runErrorServer (error) {
res.end(knownPaths[req.url].contents)
return
}
if (req.url.startsWith('/plugin-assets')) {
res.setHeader('Content-Type', fileExtensionsToMimeTypes[req.url.split('.').at(-1)] || 'text/plain')
const urlParts = req.url.split('/').slice(2)
const pluginName = urlParts.shift()
let filePath
if (pluginName === 'govuk-frontend') {
filePath = path.join(getInternalGovukFrontendDir(), ...urlParts)
} else {
filePath = path.join(process.cwd(), 'node_modules', pluginName, ...urlParts)

for (const knownRoute of [
'/manage-prototype/dependencies/',
'/plugin-assets/'
]) {
if (!req.url.startsWith(knownRoute)) {
continue
}

const filePath = req.url.split(knownRoute).at(-1)
const fileExtension = filePath.split('.').at(-1)

res.setHeader('Content-Type', fileExtensionsToMimeTypes[fileExtension] || 'text/plain')

// Route GOV.UK Frontend to internal package
const modulesDir = filePath.startsWith('govuk-frontend/') && knownRoute.startsWith('/manage-prototype/')
? path.dirname(getInternalGovukFrontendDir())
: path.join(process.cwd(), 'node_modules')

try {
const contents = fs.readFileSync(filePath)
const contents = fs.readFileSync(path.join(modulesDir, filePath))
res.writeHead(200)
res.end(contents)
} catch (e) {
console.log('Couldn\'t load url in error server: ', req.url)
res.writeHead(500)
res.end('500 Server Error')
}

return
}

Expand Down
2 changes: 1 addition & 1 deletion lib/nunjucks/views/error-handling/server-error.njk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "govuk-prototype-kit/layouts/govuk-branded.njk" %}
{% extends "views/manage-prototype/layout.njk" %}

{% block pageTitle %}
Error {% if serviceName %}– {{ serviceName }}{% endif %} – GOV.UK Prototype Kit
Expand Down