Skip to content

chore: convert repository to Typescript #109

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

Merged
merged 10 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@babel/eslint-parser": "^7.16.5",
"@babel/eslint-plugin": "^7.16.5",
"@netlify/eslint-config-node": "^5.1.8",
"@types/jest": "^27.4.1",
"babel-preset-gatsby-package": "^2.5.0",
"cross-env": "^7.0.3",
"gatsby": "^4.5.3",
Expand All @@ -51,7 +52,8 @@
"url": "https://github.com/netlify/gatsby-plugin-netlify.git"
},
"scripts": {
"build": "babel src --out-dir . --ignore \"**/__tests__\"",
"build": "tsc && cd src/__tests__ && tsc",
"clean": "tsc --build --clean",
"prepare": "cross-env NODE_ENV=production npm run build",
"prepublishOnly": "npm run prepare",
"format": "npm run format:code && npm run format:other",
Expand All @@ -60,7 +62,7 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"prettier": "prettier \"**/*.{md,css,scss,yaml,yml}\"",
"test": "jest",
"watch": "babel -w src --out-dir . --ignore \"**/__tests__\""
"watch": "tsc --watch"
},
"engines": {
"node": ">=12.13.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,20 @@ const createPluginData = async () => {
],
},
pathPrefix: ``,
publicFolder: (...files) => join(tmpDir, ...files),
publicFolder: (...files: any[]) => join(tmpDir, ...files),
}
}

jest.mock(`fs-extra`, () => ({
...jest.requireActual(`fs-extra`),
existsSync: jest.fn(),
}))
jest.mock(`fs-extra`, () => {
const actualFsExtra = jest.requireActual(`fs-extra`)
return {
...actualFsExtra,
existsSync: jest.fn(),
}
})
// eslint-disable-next-line max-lines-per-function
describe(`build-headers-program`, () => {
let reporter
let reporter: any

beforeEach(() => {
reporter = {
Expand Down Expand Up @@ -213,7 +216,7 @@ describe(`build-headers-program`, () => {
it(`with manifest['pages-manifest']`, async () => {
const pluginData = await createPluginData()

existsSync.mockImplementation((path) => !path.includes(`page-data.json`) && !path.includes(`app-data.json`))
existsSync.mockImplementation((path: any) => !path.includes(`page-data.json`) && !path.includes(`app-data.json`))

// gatsby < 2.9 uses page-manifest
pluginData.manifest[`pages-manifest`] = [`pages-manifest-ab11f09e0ca7ecd3b43e.js`]
Expand Down Expand Up @@ -244,7 +247,7 @@ describe(`build-headers-program`, () => {
...DEFAULT_OPTIONS,
mergeCachingHeaders: true,
}
existsSync.mockImplementation((path) => !path.includes(`app-data.json`))
existsSync.mockImplementation((path: any) => !path.includes(`app-data.json`))

await buildHeadersProgram(pluginData, pluginOptions, reporter)

Expand Down
File renamed without changes.
6 changes: 6 additions & 0 deletions src/__tests__/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"noEmit": true,
}
}
144 changes: 80 additions & 64 deletions src/build-headers-program.js → src/build-headers-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import {
PAGE_DATA_DIR,
} from './constants'

const getHeaderName = (header) => {
const getHeaderName = (header: any) => {
const matches = header.match(/^([^:]+):/)
return matches && matches[1]
}

const validHeaders = (headers, reporter) => {
const validHeaders = (headers: any, reporter: any) => {
if (!headers || !_.isObject(headers)) {
return false
}
Expand All @@ -40,20 +40,20 @@ const validHeaders = (headers, reporter) => {
)
}

const linkTemplate = (assetPath, type = `script`) =>
const linkTemplate = (assetPath: any, type = `script`) =>
`Link: <${assetPath}>; rel=preload; as=${type}${type === `fetch` ? `; crossorigin` : ``}`

const pathChunkName = (path) => {
const pathChunkName = (path: any) => {
const name = path === `/` ? `index` : kebabHash(path)
return `path---${name}`
}

const getPageDataPath = (path) => {
const getPageDataPath = (path: any) => {
const fixedPagePath = path === `/` ? `index` : path
return posix.join(`page-data`, fixedPagePath, `page-data.json`)
}

const getScriptPath = (file, manifest) => {
const getScriptPath = (file: any, manifest: any) => {
const chunk = manifest[file]

if (!chunk) {
Expand All @@ -71,14 +71,19 @@ const getScriptPath = (file, manifest) => {
})
}

const getLinkHeaders = (filesByType, pathPrefix) =>
Object.entries(filesByType).flatMap(([type, files]) =>
const getLinkHeaders = (filesByType: any, pathPrefix: any) =>
Object.entries(filesByType).flatMap(([type, files]: [string, Array<string>]) =>
files.map((file) => linkTemplate(`${pathPrefix}/${file}`, type)),
)

const headersPath = (pathPrefix, path) => `${pathPrefix}${path}`
const headersPath = (pathPrefix: any, path: any) => `${pathPrefix}${path}`

const preloadHeadersByPage = ({ pages, manifest, pathPrefix, publicFolder }) => {
const preloadHeadersByPage = ({
pages,
manifest,
pathPrefix,
publicFolder
}: any) => {
const linksByPage = {}

const appDataPath = publicFolder(PAGE_DATA_DIR, `app-data.json`)
Expand All @@ -91,7 +96,7 @@ const preloadHeadersByPage = ({ pages, manifest, pathPrefix, publicFolder }) =>
hasPageData = existsSync(pageDataPath)
}

pages.forEach((page) => {
pages.forEach((page: any) => {
const scripts = _.flatMap(COMMON_BUNDLES, (file) => getScriptPath(file, manifest))
scripts.push(
...getScriptPath(pathChunkName(page.path), manifest),
Expand Down Expand Up @@ -119,8 +124,8 @@ const preloadHeadersByPage = ({ pages, manifest, pathPrefix, publicFolder }) =>
return linksByPage
}

const defaultMerge = (...headers) => {
const unionMerge = (objValue, srcValue) => {
const defaultMerge = (...headers: any[]) => {
const unionMerge = (objValue: any, srcValue: any) => {
if (Array.isArray(objValue)) {
return _.union(objValue, srcValue)
}
Expand All @@ -130,18 +135,18 @@ const defaultMerge = (...headers) => {
return _.mergeWith({}, ...headers, unionMerge)
}

const headersMerge = (userHeaders, defaultHeaders) => {
const headersMerge = (userHeaders: any, defaultHeaders: any) => {
const merged = {}
Object.keys(defaultHeaders).forEach((path) => {
if (!userHeaders[path]) {
merged[path] = defaultHeaders[path]
return
}
const headersMap = {}
defaultHeaders[path].forEach((header) => {
defaultHeaders[path].forEach((header: any) => {
headersMap[getHeaderName(header)] = header
})
userHeaders[path].forEach((header) => {
userHeaders[path].forEach((header: any) => {
// override if exists
headersMap[getHeaderName(header)] = header
})
Expand All @@ -155,34 +160,32 @@ const headersMerge = (userHeaders, defaultHeaders) => {
return merged
}

const transformLink = (manifest, publicFolder, pathPrefix) => (header) =>
header.replace(LINK_REGEX, (__, prefix, file, suffix) => {
const hashed = manifest[file]
if (hashed) {
return `${prefix}${pathPrefix}${hashed}${suffix}`
}
if (existsSync(publicFolder(file))) {
return `${prefix}${pathPrefix}${file}${suffix}`
}
throw new Error(
`Could not find the file specified in the Link header \`${header}\`.` +
`The gatsby-plugin-netlify is looking for a matching file (with or without a ` +
`webpack hash). Check the public folder and your gatsby-config.js to ensure you are ` +
`pointing to a public file.`,
)
})
const transformLink = (manifest: any, publicFolder: any, pathPrefix: any) => (header: any) => header.replace(LINK_REGEX, (__: any, prefix: any, file: any, suffix: any) => {
const hashed = manifest[file]
if (hashed) {
return `${prefix}${pathPrefix}${hashed}${suffix}`
}
if (existsSync(publicFolder(file))) {
return `${prefix}${pathPrefix}${file}${suffix}`
}
throw new Error(
`Could not find the file specified in the Link header \`${header}\`.` +
`The gatsby-plugin-netlify is looking for a matching file (with or without a ` +
`webpack hash). Check the public folder and your gatsby-config.js to ensure you are ` +
`pointing to a public file.`,
)
})

// Writes out headers file format, with two spaces for indentation
// https://www.netlify.com/docs/headers-and-basic-auth/
const stringifyHeaders = (headers) =>
Object.entries(headers).reduce((text, [path, headerList]) => {
const headersString = headerList.reduce((accum, header) => `${accum} ${header}\n`, ``)
return `${text}${path}\n${headersString}`
}, ``)
const stringifyHeaders = (headers: any) => Object.entries(headers).reduce((text, [path, headerList]: [string, Array<string>]) => {
const headersString = headerList.reduce((accum, header) => `${accum} ${header}\n`, ``)
return `${text}${path}\n${headersString}`
}, ``)

// program methods

const validateUserOptions = (pluginOptions, reporter) => (headers) => {
const validateUserOptions = (pluginOptions: any, reporter: any) => (headers: any) => {
if (!validHeaders(headers, reporter)) {
throw new Error(
`The "headers" option to gatsby-plugin-netlify is in the wrong shape. ` +
Expand All @@ -192,7 +195,7 @@ const validateUserOptions = (pluginOptions, reporter) => (headers) => {
)
}

;[`mergeSecurityHeaders`, `mergeLinkHeaders`, `mergeCachingHeaders`].forEach((mergeOption) => {
[`mergeSecurityHeaders`, `mergeLinkHeaders`, `mergeCachingHeaders`].forEach((mergeOption) => {
if (!_.isBoolean(pluginOptions[mergeOption])) {
throw new TypeError(
`The "${mergeOption}" option to gatsby-plugin-netlify must be a boolean. Check your gatsby-config.js.`,
Expand All @@ -212,18 +215,23 @@ const validateUserOptions = (pluginOptions, reporter) => (headers) => {
}

const mapUserLinkHeaders =
({ manifest, pathPrefix, publicFolder }) =>
(headers) =>
Object.fromEntries(
Object.entries(headers).map(([path, headerList]) => [
path,
headerList.map(transformLink(manifest, publicFolder, pathPrefix)),
]),
)
({
manifest,
pathPrefix,
publicFolder
}: any) =>
(headers: any) => Object.fromEntries(
Object.entries(headers).map(([path, headerList]: [string, Array<string>]) => [
path,
headerList.map(transformLink(manifest, publicFolder, pathPrefix)),
]),
)

const mapUserLinkAllPageHeaders =
(pluginData, { allPageHeaders }) =>
(headers) => {
(pluginData: any, {
allPageHeaders
}: any) =>
(headers: any) => {
if (!allPageHeaders) {
return headers
}
Expand All @@ -233,7 +241,7 @@ const mapUserLinkAllPageHeaders =
const headersList = allPageHeaders.map(transformLink(manifest, publicFolder, pathPrefix))

const duplicateHeadersByPage = {}
pages.forEach((page) => {
pages.forEach((page: any) => {
const pathKey = headersPath(pathPrefix, page.path)
duplicateHeadersByPage[pathKey] = headersList
})
Expand All @@ -242,8 +250,10 @@ const mapUserLinkAllPageHeaders =
}

const applyLinkHeaders =
(pluginData, { mergeLinkHeaders }) =>
(headers) => {
(pluginData: any, {
mergeLinkHeaders
}: any) =>
(headers: any) => {
if (!mergeLinkHeaders) {
return headers
}
Expand All @@ -260,8 +270,10 @@ const applyLinkHeaders =
}

const applySecurityHeaders =
({ mergeSecurityHeaders }) =>
(headers) => {
({
mergeSecurityHeaders
}: any) =>
(headers: any) => {
if (!mergeSecurityHeaders) {
return headers
}
Expand All @@ -270,8 +282,10 @@ const applySecurityHeaders =
}

const applyCachingHeaders =
(pluginData, { mergeCachingHeaders }) =>
(headers) => {
(pluginData: any, {
mergeCachingHeaders
}: any) =>
(headers: any) => {
if (!mergeCachingHeaders) {
return headers
}
Expand Down Expand Up @@ -301,18 +315,20 @@ const applyCachingHeaders =
}

const applyTransfromHeaders =
({ transformHeaders }) =>
(headers) =>
_.mapValues(headers, transformHeaders)
({
transformHeaders
}: any) =>
(headers: any) => _.mapValues(headers, transformHeaders)

const transformToString = (headers) => `${HEADER_COMMENT}\n\n${stringifyHeaders(headers)}`
const transformToString = (headers: any) => `${HEADER_COMMENT}\n\n${stringifyHeaders(headers)}`

const writeHeadersFile =
({ publicFolder }) =>
(contents) =>
writeFile(publicFolder(NETLIFY_HEADERS_FILENAME), contents)
({
publicFolder
}: any) =>
(contents: any) => writeFile(publicFolder(NETLIFY_HEADERS_FILENAME), contents)

const buildHeadersProgram = (pluginData, pluginOptions, reporter) =>
const buildHeadersProgram = (pluginData: any, pluginOptions: any, reporter: any) =>
_.flow(
validateUserOptions(pluginOptions, reporter),
mapUserLinkHeaders(pluginData),
Expand Down
File renamed without changes.
9 changes: 6 additions & 3 deletions src/create-redirects.js → src/create-redirects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { existsSync, readFile, writeFile } from 'fs-extra'
import { HEADER_COMMENT } from './constants'

// eslint-disable-next-line max-statements
export default async function writeRedirectsFile(pluginData, redirects, rewrites) {
export default async function writeRedirectsFile(pluginData: any, redirects: any, rewrites: any) {
const { publicFolder } = pluginData

if (redirects.length === 0 && rewrites.length === 0) return null
Expand All @@ -22,7 +22,7 @@ export default async function writeRedirectsFile(pluginData, redirects, rewrites
])

// Map redirect data to the format Netlify expects
redirects = redirects.map((redirect) => {
redirects = redirects.map((redirect: any) => {
const { fromPath, isPermanent, redirectInBrowser, force, toPath, statusCode, ...rest } = redirect

let status = isPermanent ? `301` : `302`
Expand All @@ -49,7 +49,10 @@ export default async function writeRedirectsFile(pluginData, redirects, rewrites
return pieces.join(` `)
})

rewrites = rewrites.map(({ fromPath, toPath }) => `${fromPath} ${toPath} 200`)
rewrites = rewrites.map(({
fromPath,
toPath
}: any) => `${fromPath} ${toPath} 200`)

let commentFound = false

Expand Down
Loading