create-payload-app 3.0.0-canary.c27a334 → 3.0.0-canary.c96fa61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/lib/configure-payload-config.d.ts +8 -2
  3. package/dist/lib/configure-payload-config.d.ts.map +1 -1
  4. package/dist/lib/configure-payload-config.js +74 -25
  5. package/dist/lib/configure-payload-config.js.map +1 -1
  6. package/dist/lib/constants.d.ts +2 -0
  7. package/dist/lib/constants.d.ts.map +1 -0
  8. package/dist/lib/constants.js +9 -0
  9. package/dist/lib/constants.js.map +1 -0
  10. package/dist/lib/create-project.d.ts.map +1 -1
  11. package/dist/lib/create-project.js +10 -5
  12. package/dist/lib/create-project.js.map +1 -1
  13. package/dist/lib/create-project.spec.js +24 -25
  14. package/dist/lib/create-project.spec.js.map +1 -1
  15. package/dist/lib/download-template.d.ts +10 -0
  16. package/dist/lib/download-template.d.ts.map +1 -0
  17. package/dist/lib/download-template.js +21 -0
  18. package/dist/lib/download-template.js.map +1 -0
  19. package/dist/lib/generate-secret.js.map +1 -1
  20. package/dist/lib/get-package-manager.js +26 -5
  21. package/dist/lib/get-package-manager.js.map +1 -1
  22. package/dist/lib/init-next.d.ts +2 -2
  23. package/dist/lib/init-next.d.ts.map +1 -1
  24. package/dist/lib/init-next.js +54 -12
  25. package/dist/lib/init-next.js.map +1 -1
  26. package/dist/lib/install-packages.js.map +1 -1
  27. package/dist/lib/parse-project-name.d.ts.map +1 -1
  28. package/dist/lib/parse-project-name.js +9 -3
  29. package/dist/lib/parse-project-name.js.map +1 -1
  30. package/dist/lib/parse-template.d.ts.map +1 -1
  31. package/dist/lib/parse-template.js +3 -1
  32. package/dist/lib/parse-template.js.map +1 -1
  33. package/dist/lib/replacements.d.ts +27 -0
  34. package/dist/lib/replacements.d.ts.map +1 -0
  35. package/dist/lib/replacements.js +92 -0
  36. package/dist/lib/replacements.js.map +1 -0
  37. package/dist/lib/select-db.d.ts.map +1 -1
  38. package/dist/lib/select-db.js +23 -14
  39. package/dist/lib/select-db.js.map +1 -1
  40. package/dist/lib/templates.d.ts.map +1 -1
  41. package/dist/lib/templates.js +8 -1
  42. package/dist/lib/templates.js.map +1 -1
  43. package/dist/lib/update-payload-in-project.d.ts.map +1 -1
  44. package/dist/lib/update-payload-in-project.js +7 -5
  45. package/dist/lib/update-payload-in-project.js.map +1 -1
  46. package/dist/lib/wrap-next-config.d.ts +5 -5
  47. package/dist/lib/wrap-next-config.d.ts.map +1 -1
  48. package/dist/lib/wrap-next-config.js +120 -61
  49. package/dist/lib/wrap-next-config.js.map +1 -1
  50. package/dist/lib/wrap-next-config.spec.js +84 -34
  51. package/dist/lib/wrap-next-config.spec.js.map +1 -1
  52. package/dist/lib/write-env-file.d.ts +2 -1
  53. package/dist/lib/write-env-file.d.ts.map +1 -1
  54. package/dist/lib/write-env-file.js +31 -26
  55. package/dist/lib/write-env-file.js.map +1 -1
  56. package/dist/main.d.ts.map +1 -1
  57. package/dist/main.js +18 -5
  58. package/dist/main.js.map +1 -1
  59. package/dist/scripts/pack-template-files.js +3 -3
  60. package/dist/scripts/pack-template-files.js.map +1 -1
  61. package/dist/template/src/app/(payload)/admin/[[...segments]]/not-found.tsx +8 -6
  62. package/dist/template/src/app/(payload)/admin/[[...segments]]/page.tsx +8 -6
  63. package/dist/template/src/app/(payload)/admin/importMap.js +1 -0
  64. package/dist/template/src/app/(payload)/api/[...slug]/route.ts +11 -2
  65. package/dist/template/src/app/(payload)/api/graphql/route.ts +4 -2
  66. package/dist/template/src/app/(payload)/api/graphql-playground/route.ts +2 -1
  67. package/dist/template/src/app/(payload)/layout.tsx +19 -4
  68. package/dist/template/src/collections/Media.ts +16 -0
  69. package/dist/template/src/collections/Users.ts +1 -1
  70. package/dist/template/src/payload-types.ts +127 -0
  71. package/dist/template/src/payload.config.ts +13 -15
  72. package/dist/types.d.ts +6 -2
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/types.js.map +1 -1
  75. package/dist/utils/copy-recursive-sync.d.ts +3 -1
  76. package/dist/utils/copy-recursive-sync.d.ts.map +1 -1
  77. package/dist/utils/copy-recursive-sync.js +3 -1
  78. package/dist/utils/copy-recursive-sync.js.map +1 -1
  79. package/dist/utils/git.js.map +1 -1
  80. package/dist/utils/log.d.ts.map +1 -1
  81. package/dist/utils/log.js +1 -1
  82. package/dist/utils/log.js.map +1 -1
  83. package/dist/utils/messages.d.ts.map +1 -1
  84. package/dist/utils/messages.js +1 -0
  85. package/dist/utils/messages.js.map +1 -1
  86. package/package.json +25 -7
  87. package/dist/lib/packages.d.ts +0 -9
  88. package/dist/lib/packages.d.ts.map +0 -1
  89. package/dist/lib/packages.js +0 -27
  90. package/dist/lib/packages.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/templates.ts"],"sourcesContent":["import type { ProjectTemplate } from '../types.js'\n\nimport { error, info } from '../utils/log.js'\n\nexport function validateTemplate(templateName: string): boolean {\n const validTemplates = getValidTemplates()\n if (!validTemplates.map((t) => t.name).includes(templateName)) {\n error(`'${templateName}' is not a valid template.`)\n info(`Valid templates: ${validTemplates.map((t) => t.name).join(', ')}`)\n return false\n }\n return true\n}\n\nexport function getValidTemplates(): ProjectTemplate[] {\n return [\n {\n name: 'blank',\n type: 'starter',\n description: 'Blank 3.0 Template',\n url: 'https://github.com/payloadcms/payload/templates/blank-3.0#beta',\n },\n\n // Remove these until they have been updated for 3.0\n\n // {\n // name: 'blank',\n // type: 'starter',\n // description: 'Blank Template',\n // url: 'https://github.com/payloadcms/payload/templates/blank',\n // },\n // {\n // name: 'website',\n // type: 'starter',\n // description: 'Website Template',\n // url: 'https://github.com/payloadcms/payload/templates/website',\n // },\n // {\n // name: 'ecommerce',\n // type: 'starter',\n // description: 'E-commerce Template',\n // url: 'https://github.com/payloadcms/payload/templates/ecommerce',\n // },\n // {\n // name: 'plugin',\n // type: 'plugin',\n // description: 'Template for creating a Payload plugin',\n // url: 'https://github.com/payloadcms/payload-plugin-template#beta',\n // },\n // {\n // name: 'payload-demo',\n // type: 'starter',\n // description: 'Payload demo site at https://demo.payloadcms.com',\n // url: 'https://github.com/payloadcms/public-demo',\n // },\n // {\n // name: 'payload-website',\n // type: 'starter',\n // description: 'Payload website CMS at https://payloadcms.com',\n // url: 'https://github.com/payloadcms/website-cms',\n // },\n ]\n}\n"],"names":["error","info","validateTemplate","templateName","validTemplates","getValidTemplates","map","t","name","includes","join","type","description","url"],"rangeMappings":";;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,KAAK,EAAEC,IAAI,QAAQ,kBAAiB;AAE7C,OAAO,SAASC,iBAAiBC,YAAoB;IACnD,MAAMC,iBAAiBC;IACvB,IAAI,CAACD,eAAeE,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,EAAEC,QAAQ,CAACN,eAAe;QAC7DH,MAAM,CAAC,CAAC,EAAEG,aAAa,0BAA0B,CAAC;QAClDF,KAAK,CAAC,iBAAiB,EAAEG,eAAeE,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,EAAEE,IAAI,CAAC,MAAM,CAAC;QACvE,OAAO;IACT;IACA,OAAO;AACT;AAEA,OAAO,SAASL;IACd,OAAO;QACL;YACEG,MAAM;YACNG,MAAM;YACNC,aAAa;YACbC,KAAK;QACP;KAwCD;AACH"}
1
+ {"version":3,"sources":["../../src/lib/templates.ts"],"sourcesContent":["import type { ProjectTemplate } from '../types.js'\n\nimport { error, info } from '../utils/log.js'\nimport { PACKAGE_VERSION } from './constants.js'\n\nexport function validateTemplate(templateName: string): boolean {\n const validTemplates = getValidTemplates()\n if (!validTemplates.map((t) => t.name).includes(templateName)) {\n error(`'${templateName}' is not a valid template.`)\n info(`Valid templates: ${validTemplates.map((t) => t.name).join(', ')}`)\n return false\n }\n return true\n}\n\nexport function getValidTemplates(): ProjectTemplate[] {\n return [\n {\n name: 'blank',\n type: 'starter',\n description: 'Blank 3.0 Template',\n url: `https://github.com/payloadcms/payload/templates/blank#v${PACKAGE_VERSION}`,\n },\n {\n name: 'website',\n type: 'starter',\n description: 'Website Template',\n url: `https://github.com/payloadcms/payload/templates/website#v${PACKAGE_VERSION}`,\n },\n\n // Remove these until they have been updated for 3.0\n\n // {\n // name: 'blank',\n // type: 'starter',\n // description: 'Blank Template',\n // url: 'https://github.com/payloadcms/payload/templates/blank',\n // },\n // {\n // name: 'ecommerce',\n // type: 'starter',\n // description: 'E-commerce Template',\n // url: 'https://github.com/payloadcms/payload/templates/ecommerce',\n // },\n // {\n // name: 'plugin',\n // type: 'plugin',\n // description: 'Template for creating a Payload plugin',\n // url: 'https://github.com/payloadcms/payload-plugin-template#beta',\n // },\n // {\n // name: 'payload-demo',\n // type: 'starter',\n // description: 'Payload demo site at https://demo.payloadcms.com',\n // url: 'https://github.com/payloadcms/public-demo',\n // },\n // {\n // name: 'payload-website',\n // type: 'starter',\n // description: 'Payload website CMS at https://payloadcms.com',\n // url: 'https://github.com/payloadcms/website-cms',\n // },\n ]\n}\n"],"names":["error","info","PACKAGE_VERSION","validateTemplate","templateName","validTemplates","getValidTemplates","map","t","name","includes","join","type","description","url"],"mappings":"AAEA,SAASA,KAAK,EAAEC,IAAI,QAAQ,kBAAiB;AAC7C,SAASC,eAAe,QAAQ,iBAAgB;AAEhD,OAAO,SAASC,iBAAiBC,YAAoB;IACnD,MAAMC,iBAAiBC;IACvB,IAAI,CAACD,eAAeE,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,EAAEC,QAAQ,CAACN,eAAe;QAC7DJ,MAAM,CAAC,CAAC,EAAEI,aAAa,0BAA0B,CAAC;QAClDH,KAAK,CAAC,iBAAiB,EAAEI,eAAeE,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,EAAEE,IAAI,CAAC,MAAM,CAAC;QACvE,OAAO;IACT;IACA,OAAO;AACT;AAEA,OAAO,SAASL;IACd,OAAO;QACL;YACEG,MAAM;YACNG,MAAM;YACNC,aAAa;YACbC,KAAK,CAAC,uDAAuD,EAAEZ,gBAAgB,CAAC;QAClF;QACA;YACEO,MAAM;YACNG,MAAM;YACNC,aAAa;YACbC,KAAK,CAAC,yDAAyD,EAAEZ,gBAAgB,CAAC;QACpF;KAkCD;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"update-payload-in-project.d.ts","sourceRoot":"","sources":["../../src/lib/update-payload-in-project.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAOjD,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAuEhD"}
1
+ {"version":3,"file":"update-payload-in-project.d.ts","sourceRoot":"","sources":["../../src/lib/update-payload-in-project.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAOjD,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA2EhD"}
@@ -9,10 +9,12 @@ import { info } from '../utils/log.js';
9
9
  import { getPackageManager } from './get-package-manager.js';
10
10
  import { installPackages } from './install-packages.js';
11
11
  export async function updatePayloadInProject(appDetails) {
12
- if (!appDetails.nextConfigPath) return {
13
- message: 'No Next.js config found',
14
- success: false
15
- };
12
+ if (!appDetails.nextConfigPath) {
13
+ return {
14
+ message: 'No Next.js config found',
15
+ success: false
16
+ };
17
+ }
16
18
  const projectDir = path.dirname(appDetails.nextConfigPath);
17
19
  const packageObj = await fse.readJson(path.resolve(projectDir, 'package.json'));
18
20
  if (!packageObj?.dependencies) {
@@ -59,7 +61,7 @@ export async function updatePayloadInProject(appDetails) {
59
61
  }
60
62
  info('Payload packages updated successfully.');
61
63
  info(`Updating Payload Next.js files...`);
62
- const templateFilesPath = dirname.endsWith('dist') ? path.resolve(dirname, '../..', 'dist/template') : path.resolve(dirname, '../../../../templates/blank-3.0');
64
+ const templateFilesPath = process.env.JEST_WORKER_ID !== undefined ? path.resolve(dirname, '../../../../templates/blank') : path.resolve(dirname, '../..', 'dist/template');
63
65
  const templateSrcDir = path.resolve(templateFilesPath, 'src/app/(payload)');
64
66
  copyRecursiveSync(templateSrcDir, path.resolve(projectDir, appDetails.isSrcDir ? 'src/app' : 'app', '(payload)'));
65
67
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/update-payload-in-project.ts"],"sourcesContent":["import execa from 'execa'\nimport fse from 'fs-extra'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nimport type { NextAppDetails } from '../types.js'\n\nimport { copyRecursiveSync } from '../utils/copy-recursive-sync.js'\nimport { info } from '../utils/log.js'\nimport { getPackageManager } from './get-package-manager.js'\nimport { installPackages } from './install-packages.js'\n\nexport async function updatePayloadInProject(\n appDetails: NextAppDetails,\n): Promise<{ message: string; success: boolean }> {\n if (!appDetails.nextConfigPath) return { message: 'No Next.js config found', success: false }\n\n const projectDir = path.dirname(appDetails.nextConfigPath)\n\n const packageObj = (await fse.readJson(path.resolve(projectDir, 'package.json'))) as {\n dependencies?: Record<string, string>\n }\n if (!packageObj?.dependencies) {\n throw new Error('No package.json found in this project')\n }\n\n const payloadVersion = packageObj.dependencies?.payload\n if (!payloadVersion) {\n throw new Error('Payload is not installed in this project')\n }\n\n const packageManager = await getPackageManager({ projectDir })\n\n // Fetch latest Payload version from npm\n const { exitCode: getLatestVersionExitCode, stdout: latestPayloadVersion } = await execa('npm', [\n 'show',\n 'payload@beta',\n 'version',\n ])\n if (getLatestVersionExitCode !== 0) {\n throw new Error('Failed to fetch latest Payload version')\n }\n\n if (payloadVersion === latestPayloadVersion) {\n return { message: `Payload v${payloadVersion} is already up to date.`, success: true }\n }\n\n // Update all existing Payload packages\n const payloadPackages = Object.keys(packageObj.dependencies).filter((dep) =>\n dep.startsWith('@payloadcms/'),\n )\n\n const packageNames = ['payload', ...payloadPackages]\n\n const packagesToUpdate = packageNames.map((pkg) => `${pkg}@${latestPayloadVersion}`)\n\n info(`Using ${packageManager}.\\n`)\n info(\n `Updating ${packagesToUpdate.length} Payload packages to v${latestPayloadVersion}...\\n\\n${packageNames.map((p) => ` - ${p}`).join('\\n')}`,\n )\n\n const { success: updateSuccess } = await installPackages({\n packageManager,\n packagesToInstall: packagesToUpdate,\n projectDir,\n })\n\n if (!updateSuccess) {\n throw new Error('Failed to update Payload packages')\n }\n info('Payload packages updated successfully.')\n\n info(`Updating Payload Next.js files...`)\n const templateFilesPath = dirname.endsWith('dist')\n ? path.resolve(dirname, '../..', 'dist/template')\n : path.resolve(dirname, '../../../../templates/blank-3.0')\n\n const templateSrcDir = path.resolve(templateFilesPath, 'src/app/(payload)')\n\n copyRecursiveSync(\n templateSrcDir,\n path.resolve(projectDir, appDetails.isSrcDir ? 'src/app' : 'app', '(payload)'),\n )\n\n return { message: 'Payload updated successfully.', success: true }\n}\n"],"names":["execa","fse","fileURLToPath","path","filename","url","dirname","copyRecursiveSync","info","getPackageManager","installPackages","updatePayloadInProject","appDetails","nextConfigPath","message","success","projectDir","packageObj","readJson","resolve","dependencies","Error","payloadVersion","payload","packageManager","exitCode","getLatestVersionExitCode","stdout","latestPayloadVersion","payloadPackages","Object","keys","filter","dep","startsWith","packageNames","packagesToUpdate","map","pkg","length","p","join","updateSuccess","packagesToInstall","templateFilesPath","endsWith","templateSrcDir","isSrcDir"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,WAAW,QAAO;AACzB,OAAOC,SAAS,WAAU;AAC1B,SAASC,aAAa,QAAQ,WAAU;AACxC,OAAOC,UAAU,OAAM;AAEvB,MAAMC,WAAWF,cAAc,YAAYG,GAAG;AAC9C,MAAMC,UAAUH,KAAKG,OAAO,CAACF;AAI7B,SAASG,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,IAAI,QAAQ,kBAAiB;AACtC,SAASC,iBAAiB,QAAQ,2BAA0B;AAC5D,SAASC,eAAe,QAAQ,wBAAuB;AAEvD,OAAO,eAAeC,uBACpBC,UAA0B;IAE1B,IAAI,CAACA,WAAWC,cAAc,EAAE,OAAO;QAAEC,SAAS;QAA2BC,SAAS;IAAM;IAE5F,MAAMC,aAAab,KAAKG,OAAO,CAACM,WAAWC,cAAc;IAEzD,MAAMI,aAAc,MAAMhB,IAAIiB,QAAQ,CAACf,KAAKgB,OAAO,CAACH,YAAY;IAGhE,IAAI,CAACC,YAAYG,cAAc;QAC7B,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,iBAAiBL,WAAWG,YAAY,EAAEG;IAChD,IAAI,CAACD,gBAAgB;QACnB,MAAM,IAAID,MAAM;IAClB;IAEA,MAAMG,iBAAiB,MAAMf,kBAAkB;QAAEO;IAAW;IAE5D,wCAAwC;IACxC,MAAM,EAAES,UAAUC,wBAAwB,EAAEC,QAAQC,oBAAoB,EAAE,GAAG,MAAM5B,MAAM,OAAO;QAC9F;QACA;QACA;KACD;IACD,IAAI0B,6BAA6B,GAAG;QAClC,MAAM,IAAIL,MAAM;IAClB;IAEA,IAAIC,mBAAmBM,sBAAsB;QAC3C,OAAO;YAAEd,SAAS,CAAC,SAAS,EAAEQ,eAAe,uBAAuB,CAAC;YAAEP,SAAS;QAAK;IACvF;IAEA,uCAAuC;IACvC,MAAMc,kBAAkBC,OAAOC,IAAI,CAACd,WAAWG,YAAY,EAAEY,MAAM,CAAC,CAACC,MACnEA,IAAIC,UAAU,CAAC;IAGjB,MAAMC,eAAe;QAAC;WAAcN;KAAgB;IAEpD,MAAMO,mBAAmBD,aAAaE,GAAG,CAAC,CAACC,MAAQ,CAAC,EAAEA,IAAI,CAAC,EAAEV,qBAAqB,CAAC;IAEnFpB,KAAK,CAAC,MAAM,EAAEgB,eAAe,GAAG,CAAC;IACjChB,KACE,CAAC,SAAS,EAAE4B,iBAAiBG,MAAM,CAAC,sBAAsB,EAAEX,qBAAqB,OAAO,EAAEO,aAAaE,GAAG,CAAC,CAACG,IAAM,CAAC,IAAI,EAAEA,EAAE,CAAC,EAAEC,IAAI,CAAC,MAAM,CAAC;IAG5I,MAAM,EAAE1B,SAAS2B,aAAa,EAAE,GAAG,MAAMhC,gBAAgB;QACvDc;QACAmB,mBAAmBP;QACnBpB;IACF;IAEA,IAAI,CAAC0B,eAAe;QAClB,MAAM,IAAIrB,MAAM;IAClB;IACAb,KAAK;IAELA,KAAK,CAAC,iCAAiC,CAAC;IACxC,MAAMoC,oBAAoBtC,QAAQuC,QAAQ,CAAC,UACvC1C,KAAKgB,OAAO,CAACb,SAAS,SAAS,mBAC/BH,KAAKgB,OAAO,CAACb,SAAS;IAE1B,MAAMwC,iBAAiB3C,KAAKgB,OAAO,CAACyB,mBAAmB;IAEvDrC,kBACEuC,gBACA3C,KAAKgB,OAAO,CAACH,YAAYJ,WAAWmC,QAAQ,GAAG,YAAY,OAAO;IAGpE,OAAO;QAAEjC,SAAS;QAAiCC,SAAS;IAAK;AACnE"}
1
+ {"version":3,"sources":["../../src/lib/update-payload-in-project.ts"],"sourcesContent":["import execa from 'execa'\nimport fse from 'fs-extra'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nimport type { NextAppDetails } from '../types.js'\n\nimport { copyRecursiveSync } from '../utils/copy-recursive-sync.js'\nimport { info } from '../utils/log.js'\nimport { getPackageManager } from './get-package-manager.js'\nimport { installPackages } from './install-packages.js'\n\nexport async function updatePayloadInProject(\n appDetails: NextAppDetails,\n): Promise<{ message: string; success: boolean }> {\n if (!appDetails.nextConfigPath) {\n return { message: 'No Next.js config found', success: false }\n }\n\n const projectDir = path.dirname(appDetails.nextConfigPath)\n\n const packageObj = (await fse.readJson(path.resolve(projectDir, 'package.json'))) as {\n dependencies?: Record<string, string>\n }\n if (!packageObj?.dependencies) {\n throw new Error('No package.json found in this project')\n }\n\n const payloadVersion = packageObj.dependencies?.payload\n if (!payloadVersion) {\n throw new Error('Payload is not installed in this project')\n }\n\n const packageManager = await getPackageManager({ projectDir })\n\n // Fetch latest Payload version from npm\n const { exitCode: getLatestVersionExitCode, stdout: latestPayloadVersion } = await execa('npm', [\n 'show',\n 'payload@beta',\n 'version',\n ])\n if (getLatestVersionExitCode !== 0) {\n throw new Error('Failed to fetch latest Payload version')\n }\n\n if (payloadVersion === latestPayloadVersion) {\n return { message: `Payload v${payloadVersion} is already up to date.`, success: true }\n }\n\n // Update all existing Payload packages\n const payloadPackages = Object.keys(packageObj.dependencies).filter((dep) =>\n dep.startsWith('@payloadcms/'),\n )\n\n const packageNames = ['payload', ...payloadPackages]\n\n const packagesToUpdate = packageNames.map((pkg) => `${pkg}@${latestPayloadVersion}`)\n\n info(`Using ${packageManager}.\\n`)\n info(\n `Updating ${packagesToUpdate.length} Payload packages to v${latestPayloadVersion}...\\n\\n${packageNames.map((p) => ` - ${p}`).join('\\n')}`,\n )\n\n const { success: updateSuccess } = await installPackages({\n packageManager,\n packagesToInstall: packagesToUpdate,\n projectDir,\n })\n\n if (!updateSuccess) {\n throw new Error('Failed to update Payload packages')\n }\n info('Payload packages updated successfully.')\n\n info(`Updating Payload Next.js files...`)\n\n const templateFilesPath =\n process.env.JEST_WORKER_ID !== undefined\n ? path.resolve(dirname, '../../../../templates/blank')\n : path.resolve(dirname, '../..', 'dist/template')\n\n const templateSrcDir = path.resolve(templateFilesPath, 'src/app/(payload)')\n\n copyRecursiveSync(\n templateSrcDir,\n path.resolve(projectDir, appDetails.isSrcDir ? 'src/app' : 'app', '(payload)'),\n )\n\n return { message: 'Payload updated successfully.', success: true }\n}\n"],"names":["execa","fse","fileURLToPath","path","filename","url","dirname","copyRecursiveSync","info","getPackageManager","installPackages","updatePayloadInProject","appDetails","nextConfigPath","message","success","projectDir","packageObj","readJson","resolve","dependencies","Error","payloadVersion","payload","packageManager","exitCode","getLatestVersionExitCode","stdout","latestPayloadVersion","payloadPackages","Object","keys","filter","dep","startsWith","packageNames","packagesToUpdate","map","pkg","length","p","join","updateSuccess","packagesToInstall","templateFilesPath","process","env","JEST_WORKER_ID","undefined","templateSrcDir","isSrcDir"],"mappings":"AAAA,OAAOA,WAAW,QAAO;AACzB,OAAOC,SAAS,WAAU;AAC1B,SAASC,aAAa,QAAQ,WAAU;AACxC,OAAOC,UAAU,OAAM;AAEvB,MAAMC,WAAWF,cAAc,YAAYG,GAAG;AAC9C,MAAMC,UAAUH,KAAKG,OAAO,CAACF;AAI7B,SAASG,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,IAAI,QAAQ,kBAAiB;AACtC,SAASC,iBAAiB,QAAQ,2BAA0B;AAC5D,SAASC,eAAe,QAAQ,wBAAuB;AAEvD,OAAO,eAAeC,uBACpBC,UAA0B;IAE1B,IAAI,CAACA,WAAWC,cAAc,EAAE;QAC9B,OAAO;YAAEC,SAAS;YAA2BC,SAAS;QAAM;IAC9D;IAEA,MAAMC,aAAab,KAAKG,OAAO,CAACM,WAAWC,cAAc;IAEzD,MAAMI,aAAc,MAAMhB,IAAIiB,QAAQ,CAACf,KAAKgB,OAAO,CAACH,YAAY;IAGhE,IAAI,CAACC,YAAYG,cAAc;QAC7B,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,iBAAiBL,WAAWG,YAAY,EAAEG;IAChD,IAAI,CAACD,gBAAgB;QACnB,MAAM,IAAID,MAAM;IAClB;IAEA,MAAMG,iBAAiB,MAAMf,kBAAkB;QAAEO;IAAW;IAE5D,wCAAwC;IACxC,MAAM,EAAES,UAAUC,wBAAwB,EAAEC,QAAQC,oBAAoB,EAAE,GAAG,MAAM5B,MAAM,OAAO;QAC9F;QACA;QACA;KACD;IACD,IAAI0B,6BAA6B,GAAG;QAClC,MAAM,IAAIL,MAAM;IAClB;IAEA,IAAIC,mBAAmBM,sBAAsB;QAC3C,OAAO;YAAEd,SAAS,CAAC,SAAS,EAAEQ,eAAe,uBAAuB,CAAC;YAAEP,SAAS;QAAK;IACvF;IAEA,uCAAuC;IACvC,MAAMc,kBAAkBC,OAAOC,IAAI,CAACd,WAAWG,YAAY,EAAEY,MAAM,CAAC,CAACC,MACnEA,IAAIC,UAAU,CAAC;IAGjB,MAAMC,eAAe;QAAC;WAAcN;KAAgB;IAEpD,MAAMO,mBAAmBD,aAAaE,GAAG,CAAC,CAACC,MAAQ,CAAC,EAAEA,IAAI,CAAC,EAAEV,qBAAqB,CAAC;IAEnFpB,KAAK,CAAC,MAAM,EAAEgB,eAAe,GAAG,CAAC;IACjChB,KACE,CAAC,SAAS,EAAE4B,iBAAiBG,MAAM,CAAC,sBAAsB,EAAEX,qBAAqB,OAAO,EAAEO,aAAaE,GAAG,CAAC,CAACG,IAAM,CAAC,IAAI,EAAEA,EAAE,CAAC,EAAEC,IAAI,CAAC,MAAM,CAAC;IAG5I,MAAM,EAAE1B,SAAS2B,aAAa,EAAE,GAAG,MAAMhC,gBAAgB;QACvDc;QACAmB,mBAAmBP;QACnBpB;IACF;IAEA,IAAI,CAAC0B,eAAe;QAClB,MAAM,IAAIrB,MAAM;IAClB;IACAb,KAAK;IAELA,KAAK,CAAC,iCAAiC,CAAC;IAExC,MAAMoC,oBACJC,QAAQC,GAAG,CAACC,cAAc,KAAKC,YAC3B7C,KAAKgB,OAAO,CAACb,SAAS,iCACtBH,KAAKgB,OAAO,CAACb,SAAS,SAAS;IAErC,MAAM2C,iBAAiB9C,KAAKgB,OAAO,CAACyB,mBAAmB;IAEvDrC,kBACE0C,gBACA9C,KAAKgB,OAAO,CAACH,YAAYJ,WAAWsC,QAAQ,GAAG,YAAY,OAAO;IAGpE,OAAO;QAAEpC,SAAS;QAAiCC,SAAS;IAAK;AACnE"}
@@ -1,18 +1,18 @@
1
+ import type { NextConfigType } from '../types.js';
1
2
  export declare const withPayloadStatement: {
2
3
  cjs: string;
3
4
  esm: string;
5
+ ts: string;
4
6
  };
5
- type NextConfigType = 'cjs' | 'esm';
6
7
  export declare const wrapNextConfig: (args: {
7
8
  nextConfigPath: string;
8
9
  nextConfigType: NextConfigType;
9
- }) => void;
10
+ }) => Promise<void>;
10
11
  /**
11
12
  * Parses config content with AST and wraps it with withPayload function
12
13
  */
13
- export declare function parseAndModifyConfigContent(content: string, configType: NextConfigType): {
14
+ export declare function parseAndModifyConfigContent(content: string, configType: NextConfigType): Promise<{
14
15
  modifiedConfigContent: string;
15
16
  success: boolean;
16
- };
17
- export {};
17
+ }>;
18
18
  //# sourceMappingURL=wrap-next-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-next-config.d.ts","sourceRoot":"","sources":["../../src/lib/wrap-next-config.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,oBAAoB;;;CAGhC,CAAA;AAED,KAAK,cAAc,GAAG,KAAK,GAAG,KAAK,CAAA;AAEnC,eAAO,MAAM,cAAc,SAAU;IACnC,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,cAAc,CAAA;CAC/B,SAaA,CAAA;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,GACzB;IAAE,qBAAqB,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAiGrD"}
1
+ {"version":3,"file":"wrap-next-config.d.ts","sourceRoot":"","sources":["../../src/lib/wrap-next-config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,eAAO,MAAM,oBAAoB;;;;CAIhC,CAAA;AAED,eAAO,MAAM,cAAc,SAAgB;IACzC,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,cAAc,CAAA;CAC/B,kBAaA,CAAA;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC;IAAE,qBAAqB,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA4H9D"}
@@ -1,16 +1,17 @@
1
+ import { parse } from '@swc/core';
1
2
  import chalk from 'chalk';
2
- import { Syntax, parseModule } from 'esprima-next';
3
+ import { parseModule, Syntax } from 'esprima-next';
3
4
  import fs from 'fs';
4
- import { warning } from '../utils/log.js';
5
- import { log } from '../utils/log.js';
5
+ import { log, warning } from '../utils/log.js';
6
6
  export const withPayloadStatement = {
7
- cjs: `const { withPayload } = require('@payloadcms/next/withPayload')\n`,
8
- esm: `import { withPayload } from '@payloadcms/next/withPayload'\n`
7
+ cjs: `const { withPayload } = require("@payloadcms/next/withPayload");`,
8
+ esm: `import { withPayload } from "@payloadcms/next/withPayload";`,
9
+ ts: `import { withPayload } from "@payloadcms/next/withPayload";`
9
10
  };
10
- export const wrapNextConfig = (args)=>{
11
+ export const wrapNextConfig = async (args)=>{
11
12
  const { nextConfigPath, nextConfigType: configType } = args;
12
13
  const configContent = fs.readFileSync(nextConfigPath, 'utf8');
13
- const { modifiedConfigContent: newConfig, success } = parseAndModifyConfigContent(configContent, configType);
14
+ const { modifiedConfigContent: newConfig, success } = await parseAndModifyConfigContent(configContent, configType);
14
15
  if (!success) {
15
16
  return;
16
17
  }
@@ -18,80 +19,99 @@ export const wrapNextConfig = (args)=>{
18
19
  };
19
20
  /**
20
21
  * Parses config content with AST and wraps it with withPayload function
21
- */ export function parseAndModifyConfigContent(content, configType) {
22
- content = withPayloadStatement[configType] + content;
23
- let ast;
24
- try {
25
- ast = parseModule(content, {
26
- loc: true
27
- });
28
- } catch (error) {
29
- if (error instanceof Error) {
30
- warning(`Unable to parse Next config. Error: ${error.message} `);
31
- warnUserWrapNotSuccessful(configType);
32
- }
33
- return {
34
- modifiedConfigContent: content,
35
- success: false
36
- };
37
- }
38
- if (configType === 'esm') {
39
- const exportDefaultDeclaration = ast.body.find((p)=>p.type === Syntax.ExportDefaultDeclaration);
40
- const exportNamedDeclaration = ast.body.find((p)=>p.type === Syntax.ExportNamedDeclaration);
41
- if (!exportDefaultDeclaration && !exportNamedDeclaration) {
42
- throw new Error('Could not find ExportDefaultDeclaration in next.config.js');
43
- }
44
- if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
45
- const modifiedConfigContent = insertBeforeAndAfter(content, exportDefaultDeclaration.declaration.loc);
22
+ */ export async function parseAndModifyConfigContent(content, configType) {
23
+ content = withPayloadStatement[configType] + '\n' + content;
24
+ if (configType === 'cjs' || configType === 'esm') {
25
+ try {
26
+ const ast = parseModule(content, {
27
+ loc: true
28
+ });
29
+ if (configType === 'cjs') {
30
+ // Find `module.exports = X`
31
+ const moduleExports = ast.body.find((p)=>p.type === Syntax.ExpressionStatement && p.expression?.type === Syntax.AssignmentExpression && p.expression.left?.type === Syntax.MemberExpression && p.expression.left.object?.type === Syntax.Identifier && p.expression.left.object.name === 'module' && p.expression.left.property?.type === Syntax.Identifier && p.expression.left.property.name === 'exports');
32
+ if (moduleExports && moduleExports.expression.right?.loc) {
33
+ const modifiedConfigContent = insertBeforeAndAfter(content, moduleExports.expression.right.loc);
34
+ return {
35
+ modifiedConfigContent,
36
+ success: true
37
+ };
38
+ }
39
+ return Promise.resolve({
40
+ modifiedConfigContent: content,
41
+ success: false
42
+ });
43
+ } else if (configType === 'esm') {
44
+ const exportDefaultDeclaration = ast.body.find((p)=>p.type === Syntax.ExportDefaultDeclaration);
45
+ const exportNamedDeclaration = ast.body.find((p)=>p.type === Syntax.ExportNamedDeclaration);
46
+ if (!exportDefaultDeclaration && !exportNamedDeclaration) {
47
+ throw new Error('Could not find ExportDefaultDeclaration in next.config.js');
48
+ }
49
+ if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
50
+ const modifiedConfigContent = insertBeforeAndAfter(content, exportDefaultDeclaration.declaration.loc);
51
+ return {
52
+ modifiedConfigContent,
53
+ success: true
54
+ };
55
+ } else if (exportNamedDeclaration) {
56
+ const exportSpecifier = exportNamedDeclaration.specifiers.find((s)=>s.type === 'ExportSpecifier' && s.exported?.name === 'default' && s.local?.type === 'Identifier' && s.local?.name);
57
+ if (exportSpecifier) {
58
+ warning('Could not automatically wrap next.config.js with withPayload.');
59
+ warning('Automatic wrapping of named exports as default not supported yet.');
60
+ warnUserWrapNotSuccessful(configType);
61
+ return {
62
+ modifiedConfigContent: content,
63
+ success: false
64
+ };
65
+ }
66
+ }
67
+ warning('Could not automatically wrap Next config with withPayload.');
68
+ warnUserWrapNotSuccessful(configType);
69
+ return Promise.resolve({
70
+ modifiedConfigContent: content,
71
+ success: false
72
+ });
73
+ }
74
+ } catch (error) {
75
+ if (error instanceof Error) {
76
+ warning(`Unable to parse Next config. Error: ${error.message} `);
77
+ warnUserWrapNotSuccessful(configType);
78
+ }
46
79
  return {
47
- modifiedConfigContent,
48
- success: true
80
+ modifiedConfigContent: content,
81
+ success: false
49
82
  };
50
- } else if (exportNamedDeclaration) {
51
- const exportSpecifier = exportNamedDeclaration.specifiers.find((s)=>s.type === 'ExportSpecifier' && s.exported?.name === 'default' && s.local?.type === 'Identifier' && s.local?.name);
52
- if (exportSpecifier) {
53
- warning('Could not automatically wrap next.config.js with withPayload.');
54
- warning('Automatic wrapping of named exports as default not supported yet.');
83
+ }
84
+ } else if (configType === 'ts') {
85
+ const { moduleItems, parseOffset } = await compileTypeScriptFileToAST(content);
86
+ const exportDefaultDeclaration = moduleItems.find((m)=>m.type === 'ExportDefaultExpression' && (m.expression.type === 'Identifier' || m.expression.type === 'CallExpression'));
87
+ if (exportDefaultDeclaration) {
88
+ if (!('span' in exportDefaultDeclaration.expression)) {
89
+ warning('Could not automatically wrap Next config with withPayload.');
55
90
  warnUserWrapNotSuccessful(configType);
56
- return {
91
+ return Promise.resolve({
57
92
  modifiedConfigContent: content,
58
93
  success: false
59
- };
94
+ });
60
95
  }
61
- }
62
- warning('Could not automatically wrap Next config with withPayload.');
63
- warnUserWrapNotSuccessful(configType);
64
- return {
65
- modifiedConfigContent: content,
66
- success: false
67
- };
68
- } else if (configType === 'cjs') {
69
- // Find `module.exports = X`
70
- const moduleExports = ast.body.find((p)=>p.type === Syntax.ExpressionStatement && p.expression?.type === Syntax.AssignmentExpression && p.expression.left?.type === Syntax.MemberExpression && p.expression.left.object?.type === Syntax.Identifier && p.expression.left.object.name === 'module' && p.expression.left.property?.type === Syntax.Identifier && p.expression.left.property.name === 'exports');
71
- if (moduleExports && moduleExports.expression.right?.loc) {
72
- const modifiedConfigContent = insertBeforeAndAfter(content, moduleExports.expression.right.loc);
96
+ const modifiedConfigContent = insertBeforeAndAfterSWC(content, exportDefaultDeclaration.expression.span, parseOffset);
73
97
  return {
74
98
  modifiedConfigContent,
75
99
  success: true
76
100
  };
77
101
  }
78
- return {
79
- modifiedConfigContent: content,
80
- success: false
81
- };
82
102
  }
83
103
  warning('Could not automatically wrap Next config with withPayload.');
84
104
  warnUserWrapNotSuccessful(configType);
85
- return {
105
+ return Promise.resolve({
86
106
  modifiedConfigContent: content,
87
107
  success: false
88
- };
108
+ });
89
109
  }
90
110
  function warnUserWrapNotSuccessful(configType) {
91
111
  // Output directions for user to update next.config.js
92
112
  const withPayloadMessage = `
93
113
 
94
- ${chalk.bold(`Please manually wrap your existing next.config.js with the withPayload function. Here is an example:`)}
114
+ ${chalk.bold(`Please manually wrap your existing Next config with the withPayload function. Here is an example:`)}
95
115
 
96
116
  ${withPayloadStatement[configType]}
97
117
 
@@ -99,7 +119,7 @@ function warnUserWrapNotSuccessful(configType) {
99
119
  // Your Next.js config here
100
120
  }
101
121
 
102
- ${configType === 'esm' ? 'export default withPayload(nextConfig)' : 'module.exports = withPayload(nextConfig)'}
122
+ ${configType === 'cjs' ? 'module.exports = withPayload(nextConfig)' : 'export default withPayload(nextConfig)'}
103
123
 
104
124
  `;
105
125
  log(withPayloadMessage);
@@ -120,5 +140,44 @@ function insertBeforeAndAfter(content, loc) {
120
140
  }
121
141
  return lines.join('\n');
122
142
  }
143
+ function insertBeforeAndAfterSWC(content, span, /**
144
+ * WARNING: This is ONLY for unit tests. Defaults to 0 otherwise.
145
+ *
146
+ * @see compileTypeScriptFileToAST
147
+ */ parseOffset) {
148
+ const { end: preOffsetEnd, start: preOffsetStart } = span;
149
+ const start = preOffsetStart - parseOffset;
150
+ const end = preOffsetEnd - parseOffset;
151
+ const insert = (pos, text)=>{
152
+ return content.slice(0, pos) + text + content.slice(pos);
153
+ };
154
+ // insert ) after end
155
+ content = insert(end - 1, ')');
156
+ // insert withPayload before start
157
+ content = insert(start - 1, 'withPayload(');
158
+ return content;
159
+ }
160
+ /**
161
+ * Compile typescript to AST using the swc compiler
162
+ */ async function compileTypeScriptFileToAST(fileContent) {
163
+ let parseOffset = 0;
164
+ /**
165
+ * WARNING: This is ONLY for unit tests.
166
+ *
167
+ * Multiple instances of swc DO NOT reset the .span.end value.
168
+ * During unit tests, the .spawn.end value is read and accounted for.
169
+ *
170
+ * https://github.com/swc-project/swc/issues/1366
171
+ */ if (process.env.NODE_ENV === 'test') {
172
+ parseOffset = (await parse('')).span.end;
173
+ }
174
+ const module = await parse(fileContent, {
175
+ syntax: 'typescript'
176
+ });
177
+ return {
178
+ moduleItems: module.body,
179
+ parseOffset
180
+ };
181
+ }
123
182
 
124
183
  //# sourceMappingURL=wrap-next-config.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/wrap-next-config.ts"],"sourcesContent":["import type { Program } from 'esprima-next'\n\nimport chalk from 'chalk'\nimport { Syntax, parseModule } from 'esprima-next'\nimport fs from 'fs'\n\nimport { warning } from '../utils/log.js'\nimport { log } from '../utils/log.js'\n\nexport const withPayloadStatement = {\n cjs: `const { withPayload } = require('@payloadcms/next/withPayload')\\n`,\n esm: `import { withPayload } from '@payloadcms/next/withPayload'\\n`,\n}\n\ntype NextConfigType = 'cjs' | 'esm'\n\nexport const wrapNextConfig = (args: {\n nextConfigPath: string\n nextConfigType: NextConfigType\n}) => {\n const { nextConfigPath, nextConfigType: configType } = args\n const configContent = fs.readFileSync(nextConfigPath, 'utf8')\n const { modifiedConfigContent: newConfig, success } = parseAndModifyConfigContent(\n configContent,\n configType,\n )\n\n if (!success) {\n return\n }\n\n fs.writeFileSync(nextConfigPath, newConfig)\n}\n\n/**\n * Parses config content with AST and wraps it with withPayload function\n */\nexport function parseAndModifyConfigContent(\n content: string,\n configType: NextConfigType,\n): { modifiedConfigContent: string; success: boolean } {\n content = withPayloadStatement[configType] + content\n\n let ast: Program | undefined\n try {\n ast = parseModule(content, { loc: true })\n } catch (error: unknown) {\n if (error instanceof Error) {\n warning(`Unable to parse Next config. Error: ${error.message} `)\n warnUserWrapNotSuccessful(configType)\n }\n return {\n modifiedConfigContent: content,\n success: false,\n }\n }\n\n if (configType === 'esm') {\n const exportDefaultDeclaration = ast.body.find(\n (p) => p.type === Syntax.ExportDefaultDeclaration,\n ) as Directive | undefined\n\n const exportNamedDeclaration = ast.body.find(\n (p) => p.type === Syntax.ExportNamedDeclaration,\n ) as ExportNamedDeclaration | undefined\n\n if (!exportDefaultDeclaration && !exportNamedDeclaration) {\n throw new Error('Could not find ExportDefaultDeclaration in next.config.js')\n }\n\n if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {\n const modifiedConfigContent = insertBeforeAndAfter(\n content,\n exportDefaultDeclaration.declaration.loc,\n )\n return { modifiedConfigContent, success: true }\n } else if (exportNamedDeclaration) {\n const exportSpecifier = exportNamedDeclaration.specifiers.find(\n (s) =>\n s.type === 'ExportSpecifier' &&\n s.exported?.name === 'default' &&\n s.local?.type === 'Identifier' &&\n s.local?.name,\n )\n\n if (exportSpecifier) {\n warning('Could not automatically wrap next.config.js with withPayload.')\n warning('Automatic wrapping of named exports as default not supported yet.')\n\n warnUserWrapNotSuccessful(configType)\n return {\n modifiedConfigContent: content,\n success: false,\n }\n }\n }\n\n warning('Could not automatically wrap Next config with withPayload.')\n warnUserWrapNotSuccessful(configType)\n return {\n modifiedConfigContent: content,\n success: false,\n }\n } else if (configType === 'cjs') {\n // Find `module.exports = X`\n const moduleExports = ast.body.find(\n (p) =>\n p.type === Syntax.ExpressionStatement &&\n p.expression?.type === Syntax.AssignmentExpression &&\n p.expression.left?.type === Syntax.MemberExpression &&\n p.expression.left.object?.type === Syntax.Identifier &&\n p.expression.left.object.name === 'module' &&\n p.expression.left.property?.type === Syntax.Identifier &&\n p.expression.left.property.name === 'exports',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ) as any\n\n if (moduleExports && moduleExports.expression.right?.loc) {\n const modifiedConfigContent = insertBeforeAndAfter(\n content,\n moduleExports.expression.right.loc,\n )\n return { modifiedConfigContent, success: true }\n }\n\n return {\n modifiedConfigContent: content,\n success: false,\n }\n }\n\n warning('Could not automatically wrap Next config with withPayload.')\n warnUserWrapNotSuccessful(configType)\n return {\n modifiedConfigContent: content,\n success: false,\n }\n}\n\nfunction warnUserWrapNotSuccessful(configType: NextConfigType) {\n // Output directions for user to update next.config.js\n const withPayloadMessage = `\n\n ${chalk.bold(`Please manually wrap your existing next.config.js with the withPayload function. Here is an example:`)}\n\n ${withPayloadStatement[configType]}\n\n const nextConfig = {\n // Your Next.js config here\n }\n\n ${configType === 'esm' ? 'export default withPayload(nextConfig)' : 'module.exports = withPayload(nextConfig)'}\n\n`\n\n log(withPayloadMessage)\n}\n\ntype Directive = {\n declaration?: {\n loc: Loc\n }\n}\n\ntype ExportNamedDeclaration = {\n declaration: null\n loc: Loc\n specifiers: {\n exported: {\n loc: Loc\n name: string\n type: string\n }\n loc: Loc\n local: {\n loc: Loc\n name: string\n type: string\n }\n type: string\n }[]\n type: string\n}\n\ntype Loc = {\n end: { column: number; line: number }\n start: { column: number; line: number }\n}\n\nfunction insertBeforeAndAfter(content: string, loc: Loc) {\n const { end, start } = loc\n const lines = content.split('\\n')\n\n const insert = (line: string, column: number, text: string) => {\n return line.slice(0, column) + text + line.slice(column)\n }\n\n // insert ) after end\n lines[end.line - 1] = insert(lines[end.line - 1], end.column, ')')\n // insert withPayload before start\n if (start.line === end.line) {\n lines[end.line - 1] = insert(lines[end.line - 1], start.column, 'withPayload(')\n } else {\n lines[start.line - 1] = insert(lines[start.line - 1], start.column, 'withPayload(')\n }\n\n return lines.join('\\n')\n}\n"],"names":["chalk","Syntax","parseModule","fs","warning","log","withPayloadStatement","cjs","esm","wrapNextConfig","args","nextConfigPath","nextConfigType","configType","configContent","readFileSync","modifiedConfigContent","newConfig","success","parseAndModifyConfigContent","writeFileSync","content","ast","loc","error","Error","message","warnUserWrapNotSuccessful","exportDefaultDeclaration","body","find","p","type","ExportDefaultDeclaration","exportNamedDeclaration","ExportNamedDeclaration","declaration","insertBeforeAndAfter","exportSpecifier","specifiers","s","exported","name","local","moduleExports","ExpressionStatement","expression","AssignmentExpression","left","MemberExpression","object","Identifier","property","right","withPayloadMessage","bold","end","start","lines","split","insert","line","column","text","slice","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/wrap-next-config.ts"],"sourcesContent":["import type { ExportDefaultExpression, ModuleItem } from '@swc/core'\n\nimport { parse } from '@swc/core'\nimport chalk from 'chalk'\nimport { parseModule, Syntax } from 'esprima-next'\nimport fs from 'fs'\n\nimport type { NextConfigType } from '../types.js'\n\nimport { log, warning } from '../utils/log.js'\n\nexport const withPayloadStatement = {\n cjs: `const { withPayload } = require(\"@payloadcms/next/withPayload\");`,\n esm: `import { withPayload } from \"@payloadcms/next/withPayload\";`,\n ts: `import { withPayload } from \"@payloadcms/next/withPayload\";`,\n}\n\nexport const wrapNextConfig = async (args: {\n nextConfigPath: string\n nextConfigType: NextConfigType\n}) => {\n const { nextConfigPath, nextConfigType: configType } = args\n const configContent = fs.readFileSync(nextConfigPath, 'utf8')\n const { modifiedConfigContent: newConfig, success } = await parseAndModifyConfigContent(\n configContent,\n configType,\n )\n\n if (!success) {\n return\n }\n\n fs.writeFileSync(nextConfigPath, newConfig)\n}\n\n/**\n * Parses config content with AST and wraps it with withPayload function\n */\nexport async function parseAndModifyConfigContent(\n content: string,\n configType: NextConfigType,\n): Promise<{ modifiedConfigContent: string; success: boolean }> {\n content = withPayloadStatement[configType] + '\\n' + content\n\n if (configType === 'cjs' || configType === 'esm') {\n try {\n const ast = parseModule(content, { loc: true })\n\n if (configType === 'cjs') {\n // Find `module.exports = X`\n const moduleExports = ast.body.find(\n (p) =>\n p.type === Syntax.ExpressionStatement &&\n p.expression?.type === Syntax.AssignmentExpression &&\n p.expression.left?.type === Syntax.MemberExpression &&\n p.expression.left.object?.type === Syntax.Identifier &&\n p.expression.left.object.name === 'module' &&\n p.expression.left.property?.type === Syntax.Identifier &&\n p.expression.left.property.name === 'exports',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ) as any\n\n if (moduleExports && moduleExports.expression.right?.loc) {\n const modifiedConfigContent = insertBeforeAndAfter(\n content,\n moduleExports.expression.right.loc,\n )\n return { modifiedConfigContent, success: true }\n }\n\n return Promise.resolve({\n modifiedConfigContent: content,\n success: false,\n })\n } else if (configType === 'esm') {\n const exportDefaultDeclaration = ast.body.find(\n (p) => p.type === Syntax.ExportDefaultDeclaration,\n ) as Directive | undefined\n\n const exportNamedDeclaration = ast.body.find(\n (p) => p.type === Syntax.ExportNamedDeclaration,\n ) as ExportNamedDeclaration | undefined\n\n if (!exportDefaultDeclaration && !exportNamedDeclaration) {\n throw new Error('Could not find ExportDefaultDeclaration in next.config.js')\n }\n\n if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {\n const modifiedConfigContent = insertBeforeAndAfter(\n content,\n exportDefaultDeclaration.declaration.loc,\n )\n return { modifiedConfigContent, success: true }\n } else if (exportNamedDeclaration) {\n const exportSpecifier = exportNamedDeclaration.specifiers.find(\n (s) =>\n s.type === 'ExportSpecifier' &&\n s.exported?.name === 'default' &&\n s.local?.type === 'Identifier' &&\n s.local?.name,\n )\n\n if (exportSpecifier) {\n warning('Could not automatically wrap next.config.js with withPayload.')\n warning('Automatic wrapping of named exports as default not supported yet.')\n\n warnUserWrapNotSuccessful(configType)\n return {\n modifiedConfigContent: content,\n success: false,\n }\n }\n }\n\n warning('Could not automatically wrap Next config with withPayload.')\n warnUserWrapNotSuccessful(configType)\n return Promise.resolve({\n modifiedConfigContent: content,\n success: false,\n })\n }\n } catch (error: unknown) {\n if (error instanceof Error) {\n warning(`Unable to parse Next config. Error: ${error.message} `)\n warnUserWrapNotSuccessful(configType)\n }\n return {\n modifiedConfigContent: content,\n success: false,\n }\n }\n } else if (configType === 'ts') {\n const { moduleItems, parseOffset } = await compileTypeScriptFileToAST(content)\n\n const exportDefaultDeclaration = moduleItems.find(\n (m) =>\n m.type === 'ExportDefaultExpression' &&\n (m.expression.type === 'Identifier' || m.expression.type === 'CallExpression'),\n ) as ExportDefaultExpression | undefined\n\n if (exportDefaultDeclaration) {\n if (!('span' in exportDefaultDeclaration.expression)) {\n warning('Could not automatically wrap Next config with withPayload.')\n warnUserWrapNotSuccessful(configType)\n return Promise.resolve({\n modifiedConfigContent: content,\n success: false,\n })\n }\n\n const modifiedConfigContent = insertBeforeAndAfterSWC(\n content,\n exportDefaultDeclaration.expression.span,\n parseOffset,\n )\n return { modifiedConfigContent, success: true }\n }\n }\n\n warning('Could not automatically wrap Next config with withPayload.')\n warnUserWrapNotSuccessful(configType)\n return Promise.resolve({\n modifiedConfigContent: content,\n success: false,\n })\n}\n\nfunction warnUserWrapNotSuccessful(configType: NextConfigType) {\n // Output directions for user to update next.config.js\n const withPayloadMessage = `\n\n ${chalk.bold(`Please manually wrap your existing Next config with the withPayload function. Here is an example:`)}\n\n ${withPayloadStatement[configType]}\n\n const nextConfig = {\n // Your Next.js config here\n }\n\n ${configType === 'cjs' ? 'module.exports = withPayload(nextConfig)' : 'export default withPayload(nextConfig)'}\n\n`\n\n log(withPayloadMessage)\n}\n\ntype Directive = {\n declaration?: {\n loc: Loc\n }\n}\n\ntype ExportNamedDeclaration = {\n declaration: null\n loc: Loc\n specifiers: {\n exported: {\n loc: Loc\n name: string\n type: string\n }\n loc: Loc\n local: {\n loc: Loc\n name: string\n type: string\n }\n type: string\n }[]\n type: string\n}\n\ntype Loc = {\n end: { column: number; line: number }\n start: { column: number; line: number }\n}\n\nfunction insertBeforeAndAfter(content: string, loc: Loc): string {\n const { end, start } = loc\n const lines = content.split('\\n')\n\n const insert = (line: string, column: number, text: string) => {\n return line.slice(0, column) + text + line.slice(column)\n }\n\n // insert ) after end\n lines[end.line - 1] = insert(lines[end.line - 1], end.column, ')')\n // insert withPayload before start\n if (start.line === end.line) {\n lines[end.line - 1] = insert(lines[end.line - 1], start.column, 'withPayload(')\n } else {\n lines[start.line - 1] = insert(lines[start.line - 1], start.column, 'withPayload(')\n }\n\n return lines.join('\\n')\n}\n\nfunction insertBeforeAndAfterSWC(\n content: string,\n span: ModuleItem['span'],\n /**\n * WARNING: This is ONLY for unit tests. Defaults to 0 otherwise.\n *\n * @see compileTypeScriptFileToAST\n */\n parseOffset: number,\n): string {\n const { end: preOffsetEnd, start: preOffsetStart } = span\n\n const start = preOffsetStart - parseOffset\n const end = preOffsetEnd - parseOffset\n\n const insert = (pos: number, text: string): string => {\n return content.slice(0, pos) + text + content.slice(pos)\n }\n\n // insert ) after end\n content = insert(end - 1, ')')\n // insert withPayload before start\n content = insert(start - 1, 'withPayload(')\n\n return content\n}\n\n/**\n * Compile typescript to AST using the swc compiler\n */\nasync function compileTypeScriptFileToAST(\n fileContent: string,\n): Promise<{ moduleItems: ModuleItem[]; parseOffset: number }> {\n let parseOffset = 0\n\n /**\n * WARNING: This is ONLY for unit tests.\n *\n * Multiple instances of swc DO NOT reset the .span.end value.\n * During unit tests, the .spawn.end value is read and accounted for.\n *\n * https://github.com/swc-project/swc/issues/1366\n */\n if (process.env.NODE_ENV === 'test') {\n parseOffset = (await parse('')).span.end\n }\n\n const module = await parse(fileContent, {\n syntax: 'typescript',\n })\n\n return { moduleItems: module.body, parseOffset }\n}\n"],"names":["parse","chalk","parseModule","Syntax","fs","log","warning","withPayloadStatement","cjs","esm","ts","wrapNextConfig","args","nextConfigPath","nextConfigType","configType","configContent","readFileSync","modifiedConfigContent","newConfig","success","parseAndModifyConfigContent","writeFileSync","content","ast","loc","moduleExports","body","find","p","type","ExpressionStatement","expression","AssignmentExpression","left","MemberExpression","object","Identifier","name","property","right","insertBeforeAndAfter","Promise","resolve","exportDefaultDeclaration","ExportDefaultDeclaration","exportNamedDeclaration","ExportNamedDeclaration","Error","declaration","exportSpecifier","specifiers","s","exported","local","warnUserWrapNotSuccessful","error","message","moduleItems","parseOffset","compileTypeScriptFileToAST","m","insertBeforeAndAfterSWC","span","withPayloadMessage","bold","end","start","lines","split","insert","line","column","text","slice","join","preOffsetEnd","preOffsetStart","pos","fileContent","process","env","NODE_ENV","module","syntax"],"mappings":"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"}
@@ -1,10 +1,41 @@
1
- import { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js';
2
1
  import * as p from '@clack/prompts';
3
2
  import { jest } from '@jest/globals';
3
+ import { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js';
4
+ const tsConfigs = {
5
+ defaultNextConfig: `import type { NextConfig } from "next";
6
+
7
+ const nextConfig: NextConfig = {};
8
+ export default nextConfig;`,
9
+ nextConfigExportNamedDefault: `import type { NextConfig } from "next";
10
+ const nextConfig: NextConfig = {};
11
+ const wrapped = someFunc(asdf);
12
+ export { wrapped as default };
13
+ `,
14
+ nextConfigWithFunc: `import type { NextConfig } from "next";
15
+ const nextConfig: NextConfig = {};
16
+ export default someFunc(nextConfig);
17
+ `,
18
+ nextConfigWithFuncMultiline: `import type { NextConfig } from "next";
19
+ const nextConfig: NextConfig = {};
20
+ export default someFunc(
21
+ nextConfig
22
+ );
23
+ `,
24
+ nextConfigWithSpread: `import type { NextConfig } from "next";
25
+ const nextConfig: NextConfig = {
26
+ ...someConfig,
27
+ };
28
+ export default nextConfig;
29
+ `
30
+ };
4
31
  const esmConfigs = {
5
32
  defaultNextConfig: `/** @type {import('next').NextConfig} */
6
33
  const nextConfig = {};
7
34
  export default nextConfig;
35
+ `,
36
+ nextConfigExportNamedDefault: `const nextConfig = {};
37
+ const wrapped = someFunc(asdf);
38
+ export { wrapped as default };
8
39
  `,
9
40
  nextConfigWithFunc: `const nextConfig = {};
10
41
  export default someFunc(nextConfig);
@@ -13,10 +44,6 @@ export default someFunc(nextConfig);
13
44
  export default someFunc(
14
45
  nextConfig
15
46
  );
16
- `,
17
- nextConfigExportNamedDefault: `const nextConfig = {};
18
- const wrapped = someFunc(asdf);
19
- export { wrapped as default };
20
47
  `,
21
48
  nextConfigWithSpread: `const nextConfig = {
22
49
  ...someConfig,
@@ -25,12 +52,16 @@ export default nextConfig;
25
52
  `
26
53
  };
27
54
  const cjsConfigs = {
55
+ anonConfig: `module.exports = {};`,
28
56
  defaultNextConfig: `
29
57
  /** @type {import('next').NextConfig} */
30
58
  const nextConfig = {};
31
59
  module.exports = nextConfig;
32
60
  `,
33
- anonConfig: `module.exports = {};`,
61
+ nextConfigExportNamedDefault: `const nextConfig = {};
62
+ const wrapped = someFunc(asdf);
63
+ module.exports = wrapped;
64
+ `,
34
65
  nextConfigWithFunc: `const nextConfig = {};
35
66
  module.exports = someFunc(nextConfig);
36
67
  `,
@@ -38,42 +69,61 @@ module.exports = someFunc(nextConfig);
38
69
  module.exports = someFunc(
39
70
  nextConfig
40
71
  );
41
- `,
42
- nextConfigExportNamedDefault: `const nextConfig = {};
43
- const wrapped = someFunc(asdf);
44
- module.exports = wrapped;
45
72
  `,
46
73
  nextConfigWithSpread: `const nextConfig = { ...someConfig };
47
74
  module.exports = nextConfig;
48
75
  `
49
76
  };
50
77
  describe('parseAndInsertWithPayload', ()=>{
78
+ describe('ts', ()=>{
79
+ const configType = 'ts';
80
+ const importStatement = withPayloadStatement[configType];
81
+ it('should parse the default next config', async ()=>{
82
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(tsConfigs.defaultNextConfig, configType);
83
+ expect(modifiedConfigContent).toContain(importStatement);
84
+ expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
85
+ });
86
+ it('should parse the config with a function', async ()=>{
87
+ const { modifiedConfigContent: modifiedConfigContent2 } = await parseAndModifyConfigContent(tsConfigs.nextConfigWithFunc, configType);
88
+ expect(modifiedConfigContent2).toContain('withPayload(someFunc(nextConfig))');
89
+ });
90
+ it('should parse the config with a multi-lined function', async ()=>{
91
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(tsConfigs.nextConfigWithFuncMultiline, configType);
92
+ expect(modifiedConfigContent).toContain(importStatement);
93
+ expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/);
94
+ });
95
+ it('should parse the config with a spread', async ()=>{
96
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(tsConfigs.nextConfigWithSpread, configType);
97
+ expect(modifiedConfigContent).toContain(importStatement);
98
+ expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
99
+ });
100
+ });
51
101
  describe('esm', ()=>{
52
102
  const configType = 'esm';
53
103
  const importStatement = withPayloadStatement[configType];
54
- it('should parse the default next config', ()=>{
55
- const { modifiedConfigContent } = parseAndModifyConfigContent(esmConfigs.defaultNextConfig, configType);
104
+ it('should parse the default next config', async ()=>{
105
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(esmConfigs.defaultNextConfig, configType);
56
106
  expect(modifiedConfigContent).toContain(importStatement);
57
107
  expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
58
108
  });
59
- it('should parse the config with a function', ()=>{
60
- const { modifiedConfigContent } = parseAndModifyConfigContent(esmConfigs.nextConfigWithFunc, configType);
109
+ it('should parse the config with a function', async ()=>{
110
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(esmConfigs.nextConfigWithFunc, configType);
61
111
  expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))');
62
112
  });
63
- it('should parse the config with a function on a new line', ()=>{
64
- const { modifiedConfigContent } = parseAndModifyConfigContent(esmConfigs.nextConfigWithFuncMultiline, configType);
113
+ it('should parse the config with a multi-lined function', async ()=>{
114
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(esmConfigs.nextConfigWithFuncMultiline, configType);
65
115
  expect(modifiedConfigContent).toContain(importStatement);
66
- expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n nextConfig\n\)\)/);
116
+ expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/);
67
117
  });
68
- it('should parse the config with a spread', ()=>{
69
- const { modifiedConfigContent } = parseAndModifyConfigContent(esmConfigs.nextConfigWithSpread, configType);
118
+ it('should parse the config with a spread', async ()=>{
119
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(esmConfigs.nextConfigWithSpread, configType);
70
120
  expect(modifiedConfigContent).toContain(importStatement);
71
121
  expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
72
122
  });
73
123
  // Unsupported: export { wrapped as default }
74
- it('should give warning with a named export as default', ()=>{
124
+ it('should give warning with a named export as default', async ()=>{
75
125
  const warnLogSpy = jest.spyOn(p.log, 'warn').mockImplementation(()=>{});
76
- const { modifiedConfigContent, success } = parseAndModifyConfigContent(esmConfigs.nextConfigExportNamedDefault, configType);
126
+ const { modifiedConfigContent, success } = await parseAndModifyConfigContent(esmConfigs.nextConfigExportNamedDefault, configType);
77
127
  expect(modifiedConfigContent).toContain(importStatement);
78
128
  expect(success).toBe(false);
79
129
  expect(warnLogSpy).toHaveBeenCalledWith(expect.stringContaining('Could not automatically wrap'));
@@ -82,32 +132,32 @@ describe('parseAndInsertWithPayload', ()=>{
82
132
  describe('cjs', ()=>{
83
133
  const configType = 'cjs';
84
134
  const requireStatement = withPayloadStatement[configType];
85
- it('should parse the default next config', ()=>{
86
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.defaultNextConfig, configType);
135
+ it('should parse the default next config', async ()=>{
136
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.defaultNextConfig, configType);
87
137
  expect(modifiedConfigContent).toContain(requireStatement);
88
138
  expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
89
139
  });
90
- it('should parse anonymous default config', ()=>{
91
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.anonConfig, configType);
140
+ it('should parse anonymous default config', async ()=>{
141
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.anonConfig, configType);
92
142
  expect(modifiedConfigContent).toContain(requireStatement);
93
143
  expect(modifiedConfigContent).toContain('withPayload({})');
94
144
  });
95
- it('should parse the config with a function', ()=>{
96
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.nextConfigWithFunc, configType);
145
+ it('should parse the config with a function', async ()=>{
146
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.nextConfigWithFunc, configType);
97
147
  expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))');
98
148
  });
99
- it('should parse the config with a function on a new line', ()=>{
100
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.nextConfigWithFuncMultiline, configType);
149
+ it('should parse the config with a multi-lined function', async ()=>{
150
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.nextConfigWithFuncMultiline, configType);
101
151
  expect(modifiedConfigContent).toContain(requireStatement);
102
- expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n nextConfig\n\)\)/);
152
+ expect(modifiedConfigContent).toMatch(/withPayload\(someFunc\(\n {2}nextConfig\n\)\)/);
103
153
  });
104
- it('should parse the config with a named export as default', ()=>{
105
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.nextConfigExportNamedDefault, configType);
154
+ it('should parse the config with a named export as default', async ()=>{
155
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.nextConfigExportNamedDefault, configType);
106
156
  expect(modifiedConfigContent).toContain(requireStatement);
107
157
  expect(modifiedConfigContent).toContain('withPayload(wrapped)');
108
158
  });
109
- it('should parse the config with a spread', ()=>{
110
- const { modifiedConfigContent } = parseAndModifyConfigContent(cjsConfigs.nextConfigWithSpread, configType);
159
+ it('should parse the config with a spread', async ()=>{
160
+ const { modifiedConfigContent } = await parseAndModifyConfigContent(cjsConfigs.nextConfigWithSpread, configType);
111
161
  expect(modifiedConfigContent).toContain(requireStatement);
112
162
  expect(modifiedConfigContent).toContain('withPayload(nextConfig)');
113
163
  });