chore: return error messages from parse

This commit is contained in:
Elliot DeNolf
2024-03-26 10:03:12 -04:00
parent ff65f10c2f
commit df0bf28d57
2 changed files with 28 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
import { parseAndInsertWithPayload } from './wrap-next-config'
import { parseAndInsertWithPayload, withPayloadImportStatement } from './wrap-next-config'
const defaultNextConfig = `/** @type {import('next').NextConfig} */
const nextConfig = {};
@@ -30,22 +30,25 @@ export { wrapped as default }
describe('parseAndInsertWithPayload', () => {
it('should parse the default next config', () => {
const modifiedConfig = parseAndInsertWithPayload(defaultNextConfig)
expect(modifiedConfig).toMatch(/withPayload\(nextConfig\)/)
const { modifiedConfigContent } = parseAndInsertWithPayload(defaultNextConfig)
expect(modifiedConfigContent).toContain(withPayloadImportStatement)
expect(modifiedConfigContent).toContain('withPayload(nextConfig)')
})
it('should parse the config with a function', () => {
const modifiedConfig = parseAndInsertWithPayload(nextConfigWithFunc)
expect(modifiedConfig).toMatch(/withPayload\(someFunc\(nextConfig\)\)/)
const { modifiedConfigContent } = parseAndInsertWithPayload(nextConfigWithFunc)
expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')
})
it('should parse the config with a function on a new line', () => {
const modifiedConfig = parseAndInsertWithPayload(nextConfigWithFuncMultiline)
expect(modifiedConfig).toMatch(/withPayload\(someFunc\(\n nextConfig\n\)\)/)
const { modifiedConfigContent } = parseAndInsertWithPayload(nextConfigWithFuncMultiline)
expect(modifiedConfigContent).toContain(withPayloadImportStatement)
expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n nextConfig\n\)\)/)
})
// Unsupported: export { wrapped as default }
it('should give warning with a named export as default', () => {
const modifiedConfig = parseAndInsertWithPayload(nextConfigExportNamedDefault)
expect(modifiedConfig).toHaveProperty('error')
const { modifiedConfigContent, error } = parseAndInsertWithPayload(nextConfigExportNamedDefault)
expect(modifiedConfigContent).toContain(withPayloadImportStatement)
expect(error).toBeTruthy()
})
})

View File

@@ -3,6 +3,8 @@ import fs from 'fs'
import globby from 'globby'
import path from 'path'
export const withPayloadImportStatement = `import { withPayload } from '@payloadcms/next/withPayload'\n`
export const wrapNextConfig = async (args: { projectDir: string }): Promise<void> => {
const foundConfig = (await globby('next.config.*js', { cwd: args.projectDir }))?.[0]
@@ -11,14 +13,18 @@ export const wrapNextConfig = async (args: { projectDir: string }): Promise<void
}
const configPath = path.resolve(args.projectDir, foundConfig)
const configContent = fs.readFileSync(configPath, 'utf8')
const newConfig = parseAndInsertWithPayload(configContent)
if (typeof newConfig === 'object') {
throw new Error(newConfig.error)
const { error, modifiedConfigContent: newConfig } = parseAndInsertWithPayload(configContent)
if (error) {
console.warn(error)
}
fs.writeFileSync(configPath, newConfig)
}
export function parseAndInsertWithPayload(content: string): { error: string } | string {
export function parseAndInsertWithPayload(content: string): {
error?: string
modifiedConfigContent: string
} {
content = withPayloadImportStatement + content
const ast = parseModule(content, { loc: true })
const exportDefaultDeclaration = ast.body.find((p) => p.type === 'ExportDefaultDeclaration') as
| Directive
@@ -33,7 +39,11 @@ export function parseAndInsertWithPayload(content: string): { error: string } |
}
if (exportDefaultDeclaration) {
return insertBeforeAndAfter(content, exportDefaultDeclaration.declaration?.loc)
const modifiedConfigContent = insertBeforeAndAfter(
content,
exportDefaultDeclaration.declaration?.loc,
)
return { modifiedConfigContent }
} else if (exportNamedDeclaration) {
const exportSpecifier = exportNamedDeclaration.specifiers.find(
(s) =>
@@ -48,13 +58,12 @@ export function parseAndInsertWithPayload(content: string): { error: string } |
return {
error: `Automatic wrapping of named exports as default not supported yet.
Please manually wrap your Next config with the withPayload function`,
modifiedConfigContent: content,
}
}
} else {
throw new Error('Could not automatically wrap next.config.js with withPayload')
}
return insertBeforeAndAfter(content, exportDefaultDeclaration.declaration?.loc)
}
type Directive = {