create-payload-app 3.0.0-canary.f6e77b8 → 3.0.0-canary.fb81f02

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) 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/create-project.d.ts.map +1 -1
  7. package/dist/lib/create-project.js +9 -2
  8. package/dist/lib/create-project.js.map +1 -1
  9. package/dist/lib/create-project.spec.js +24 -26
  10. package/dist/lib/create-project.spec.js.map +1 -1
  11. package/dist/lib/generate-secret.js.map +1 -1
  12. package/dist/lib/get-package-manager.d.ts +6 -0
  13. package/dist/lib/get-package-manager.d.ts.map +1 -0
  14. package/dist/lib/get-package-manager.js +38 -0
  15. package/dist/lib/get-package-manager.js.map +1 -0
  16. package/dist/lib/init-next.d.ts +3 -11
  17. package/dist/lib/init-next.d.ts.map +1 -1
  18. package/dist/lib/init-next.js +77 -56
  19. package/dist/lib/init-next.js.map +1 -1
  20. package/dist/lib/install-packages.d.ts +9 -0
  21. package/dist/lib/install-packages.d.ts.map +1 -0
  22. package/dist/lib/install-packages.js +43 -0
  23. package/dist/lib/install-packages.js.map +1 -0
  24. package/dist/lib/parse-project-name.js.map +1 -1
  25. package/dist/lib/parse-template.js.map +1 -1
  26. package/dist/lib/replacements.d.ts +27 -0
  27. package/dist/lib/replacements.d.ts.map +1 -0
  28. package/dist/lib/replacements.js +80 -0
  29. package/dist/lib/replacements.js.map +1 -0
  30. package/dist/lib/select-db.d.ts.map +1 -1
  31. package/dist/lib/select-db.js +11 -11
  32. package/dist/lib/select-db.js.map +1 -1
  33. package/dist/lib/templates.js +5 -24
  34. package/dist/lib/templates.js.map +1 -1
  35. package/dist/lib/update-payload-in-project.d.ts +6 -0
  36. package/dist/lib/update-payload-in-project.d.ts.map +1 -0
  37. package/dist/lib/update-payload-in-project.js +71 -0
  38. package/dist/lib/update-payload-in-project.js.map +1 -0
  39. package/dist/lib/wrap-next-config.d.ts +5 -5
  40. package/dist/lib/wrap-next-config.d.ts.map +1 -1
  41. package/dist/lib/wrap-next-config.js +123 -60
  42. package/dist/lib/wrap-next-config.js.map +1 -1
  43. package/dist/lib/wrap-next-config.spec.js +85 -34
  44. package/dist/lib/wrap-next-config.spec.js.map +1 -1
  45. package/dist/lib/write-env-file.d.ts.map +1 -1
  46. package/dist/lib/write-env-file.js +25 -25
  47. package/dist/lib/write-env-file.js.map +1 -1
  48. package/dist/main.d.ts.map +1 -1
  49. package/dist/main.js +33 -21
  50. package/dist/main.js.map +1 -1
  51. package/dist/scripts/pack-template-files.js.map +1 -1
  52. package/dist/template/src/collections/Media.ts +16 -0
  53. package/dist/template/src/collections/Users.ts +1 -1
  54. package/dist/template/src/payload.config.ts +10 -15
  55. package/dist/types.d.ts +14 -1
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/types.js.map +1 -1
  58. package/dist/utils/copy-recursive-sync.d.ts +2 -0
  59. package/dist/utils/copy-recursive-sync.d.ts.map +1 -1
  60. package/dist/utils/copy-recursive-sync.js +2 -0
  61. package/dist/utils/copy-recursive-sync.js.map +1 -1
  62. package/dist/utils/git.d.ts +4 -0
  63. package/dist/utils/git.d.ts.map +1 -0
  64. package/dist/utils/git.js +46 -0
  65. package/dist/utils/git.js.map +1 -0
  66. package/dist/utils/log.d.ts.map +1 -1
  67. package/dist/utils/log.js +1 -1
  68. package/dist/utils/log.js.map +1 -1
  69. package/dist/utils/messages.d.ts.map +1 -1
  70. package/dist/utils/messages.js.map +1 -1
  71. package/package.json +18 -6
  72. package/dist/lib/packages.d.ts +0 -9
  73. package/dist/lib/packages.d.ts.map +0 -1
  74. package/dist/lib/packages.js +0 -27
  75. 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-3.0',\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;QAEA,oDAAoD;QAEpD,IAAI;QACJ,mBAAmB;QACnB,qBAAqB;QACrB,mCAAmC;QACnC,kEAAkE;QAClE,KAAK;QACL,IAAI;QACJ,qBAAqB;QACrB,qBAAqB;QACrB,qCAAqC;QACrC,oEAAoE;QACpE,KAAK;QACL,IAAI;QACJ,uBAAuB;QACvB,qBAAqB;QACrB,wCAAwC;QACxC,sEAAsE;QACtE,KAAK;QACL;YACEL,MAAM;YACNG,MAAM;YACNC,aAAa;YACbC,KAAK;QACP;KAaD;AACH"}
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 name: 'website',\n type: 'starter',\n description: 'Website Template',\n url: 'https://github.com/payloadcms/payload/templates/website#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: '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"],"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;QACA;YACEL,MAAM;YACNG,MAAM;YACNC,aAAa;YACbC,KAAK;QACP;KAkCD;AACH"}
@@ -0,0 +1,6 @@
1
+ import type { NextAppDetails } from '../types.js';
2
+ export declare function updatePayloadInProject(appDetails: NextAppDetails): Promise<{
3
+ message: string;
4
+ success: boolean;
5
+ }>;
6
+ //# sourceMappingURL=update-payload-in-project.d.ts.map
@@ -0,0 +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,CAyEhD"}
@@ -0,0 +1,71 @@
1
+ import execa from 'execa';
2
+ import fse from 'fs-extra';
3
+ import { fileURLToPath } from 'node:url';
4
+ import path from 'path';
5
+ const filename = fileURLToPath(import.meta.url);
6
+ const dirname = path.dirname(filename);
7
+ import { copyRecursiveSync } from '../utils/copy-recursive-sync.js';
8
+ import { info } from '../utils/log.js';
9
+ import { getPackageManager } from './get-package-manager.js';
10
+ import { installPackages } from './install-packages.js';
11
+ export async function updatePayloadInProject(appDetails) {
12
+ if (!appDetails.nextConfigPath) return {
13
+ message: 'No Next.js config found',
14
+ success: false
15
+ };
16
+ const projectDir = path.dirname(appDetails.nextConfigPath);
17
+ const packageObj = await fse.readJson(path.resolve(projectDir, 'package.json'));
18
+ if (!packageObj?.dependencies) {
19
+ throw new Error('No package.json found in this project');
20
+ }
21
+ const payloadVersion = packageObj.dependencies?.payload;
22
+ if (!payloadVersion) {
23
+ throw new Error('Payload is not installed in this project');
24
+ }
25
+ const packageManager = await getPackageManager({
26
+ projectDir
27
+ });
28
+ // Fetch latest Payload version from npm
29
+ const { exitCode: getLatestVersionExitCode, stdout: latestPayloadVersion } = await execa('npm', [
30
+ 'show',
31
+ 'payload@beta',
32
+ 'version'
33
+ ]);
34
+ if (getLatestVersionExitCode !== 0) {
35
+ throw new Error('Failed to fetch latest Payload version');
36
+ }
37
+ if (payloadVersion === latestPayloadVersion) {
38
+ return {
39
+ message: `Payload v${payloadVersion} is already up to date.`,
40
+ success: true
41
+ };
42
+ }
43
+ // Update all existing Payload packages
44
+ const payloadPackages = Object.keys(packageObj.dependencies).filter((dep)=>dep.startsWith('@payloadcms/'));
45
+ const packageNames = [
46
+ 'payload',
47
+ ...payloadPackages
48
+ ];
49
+ const packagesToUpdate = packageNames.map((pkg)=>`${pkg}@${latestPayloadVersion}`);
50
+ info(`Using ${packageManager}.\n`);
51
+ info(`Updating ${packagesToUpdate.length} Payload packages to v${latestPayloadVersion}...\n\n${packageNames.map((p)=>` - ${p}`).join('\n')}`);
52
+ const { success: updateSuccess } = await installPackages({
53
+ packageManager,
54
+ packagesToInstall: packagesToUpdate,
55
+ projectDir
56
+ });
57
+ if (!updateSuccess) {
58
+ throw new Error('Failed to update Payload packages');
59
+ }
60
+ info('Payload packages updated successfully.');
61
+ info(`Updating Payload Next.js files...`);
62
+ const templateFilesPath = process.env.JEST_WORKER_ID !== undefined ? path.resolve(dirname, '../../../../templates/blank-3.0') : path.resolve(dirname, '../..', 'dist/template');
63
+ const templateSrcDir = path.resolve(templateFilesPath, 'src/app/(payload)');
64
+ copyRecursiveSync(templateSrcDir, path.resolve(projectDir, appDetails.isSrcDir ? 'src/app' : 'app', '(payload)'));
65
+ return {
66
+ message: 'Payload updated successfully.',
67
+ success: true
68
+ };
69
+ }
70
+
71
+ //# sourceMappingURL=update-payload-in-project.js.map
@@ -0,0 +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\n const templateFilesPath =\n process.env.JEST_WORKER_ID !== undefined\n ? path.resolve(dirname, '../../../../templates/blank-3.0')\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,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;IAExC,MAAMoC,oBACJC,QAAQC,GAAG,CAACC,cAAc,KAAKC,YAC3B7C,KAAKgB,OAAO,CAACb,SAAS,qCACtBH,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,CA8H9D"}
@@ -1,16 +1,17 @@
1
+ import swc from '@swc/core';
1
2
  import chalk from 'chalk';
2
3
  import { Syntax, parseModule } 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,103 @@ 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
+ console.log({
25
+ configType,
26
+ content
27
+ });
28
+ if (configType === 'cjs' || configType === 'esm') {
29
+ try {
30
+ const ast = parseModule(content, {
31
+ loc: true
32
+ });
33
+ if (configType === 'cjs') {
34
+ // Find `module.exports = X`
35
+ 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');
36
+ if (moduleExports && moduleExports.expression.right?.loc) {
37
+ const modifiedConfigContent = insertBeforeAndAfter(content, moduleExports.expression.right.loc);
38
+ return {
39
+ modifiedConfigContent,
40
+ success: true
41
+ };
42
+ }
43
+ return Promise.resolve({
44
+ modifiedConfigContent: content,
45
+ success: false
46
+ });
47
+ } else if (configType === 'esm') {
48
+ const exportDefaultDeclaration = ast.body.find((p)=>p.type === Syntax.ExportDefaultDeclaration);
49
+ const exportNamedDeclaration = ast.body.find((p)=>p.type === Syntax.ExportNamedDeclaration);
50
+ if (!exportDefaultDeclaration && !exportNamedDeclaration) {
51
+ throw new Error('Could not find ExportDefaultDeclaration in next.config.js');
52
+ }
53
+ if (exportDefaultDeclaration && exportDefaultDeclaration.declaration?.loc) {
54
+ const modifiedConfigContent = insertBeforeAndAfter(content, exportDefaultDeclaration.declaration.loc);
55
+ return {
56
+ modifiedConfigContent,
57
+ success: true
58
+ };
59
+ } else if (exportNamedDeclaration) {
60
+ const exportSpecifier = exportNamedDeclaration.specifiers.find((s)=>s.type === 'ExportSpecifier' && s.exported?.name === 'default' && s.local?.type === 'Identifier' && s.local?.name);
61
+ if (exportSpecifier) {
62
+ warning('Could not automatically wrap next.config.js with withPayload.');
63
+ warning('Automatic wrapping of named exports as default not supported yet.');
64
+ warnUserWrapNotSuccessful(configType);
65
+ return {
66
+ modifiedConfigContent: content,
67
+ success: false
68
+ };
69
+ }
70
+ }
71
+ warning('Could not automatically wrap Next config with withPayload.');
72
+ warnUserWrapNotSuccessful(configType);
73
+ return Promise.resolve({
74
+ modifiedConfigContent: content,
75
+ success: false
76
+ });
77
+ }
78
+ } catch (error) {
79
+ if (error instanceof Error) {
80
+ warning(`Unable to parse Next config. Error: ${error.message} `);
81
+ warnUserWrapNotSuccessful(configType);
82
+ }
46
83
  return {
47
- modifiedConfigContent,
48
- success: true
84
+ modifiedConfigContent: content,
85
+ success: false
49
86
  };
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.');
87
+ }
88
+ } else if (configType === 'ts') {
89
+ const { moduleItems, parseOffset } = await compileTypeScriptFileToAST(content);
90
+ const exportDefaultDeclaration = moduleItems.find((m)=>m.type === 'ExportDefaultExpression' && (m.expression.type === 'Identifier' || m.expression.type === 'CallExpression'));
91
+ if (exportDefaultDeclaration) {
92
+ if (!('span' in exportDefaultDeclaration.expression)) {
93
+ warning('Could not automatically wrap Next config with withPayload.');
55
94
  warnUserWrapNotSuccessful(configType);
56
- return {
95
+ return Promise.resolve({
57
96
  modifiedConfigContent: content,
58
97
  success: false
59
- };
98
+ });
60
99
  }
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);
100
+ const modifiedConfigContent = insertBeforeAndAfterSWC(content, exportDefaultDeclaration.expression.span, parseOffset);
73
101
  return {
74
102
  modifiedConfigContent,
75
103
  success: true
76
104
  };
77
105
  }
78
- return {
79
- modifiedConfigContent: content,
80
- success: false
81
- };
82
106
  }
83
107
  warning('Could not automatically wrap Next config with withPayload.');
84
108
  warnUserWrapNotSuccessful(configType);
85
- return {
109
+ return Promise.resolve({
86
110
  modifiedConfigContent: content,
87
111
  success: false
88
- };
112
+ });
89
113
  }
90
114
  function warnUserWrapNotSuccessful(configType) {
91
115
  // Output directions for user to update next.config.js
92
116
  const withPayloadMessage = `
93
117
 
94
- ${chalk.bold(`Please manually wrap your existing next.config.js with the withPayload function. Here is an example:`)}
118
+ ${chalk.bold(`Please manually wrap your existing Next config with the withPayload function. Here is an example:`)}
95
119
 
96
120
  ${withPayloadStatement[configType]}
97
121
 
@@ -99,7 +123,7 @@ function warnUserWrapNotSuccessful(configType) {
99
123
  // Your Next.js config here
100
124
  }
101
125
 
102
- ${configType === 'esm' ? 'export default withPayload(nextConfig)' : 'module.exports = withPayload(nextConfig)'}
126
+ ${configType === 'cjs' ? 'module.exports = withPayload(nextConfig)' : 'export default withPayload(nextConfig)'}
103
127
 
104
128
  `;
105
129
  log(withPayloadMessage);
@@ -120,5 +144,44 @@ function insertBeforeAndAfter(content, loc) {
120
144
  }
121
145
  return lines.join('\n');
122
146
  }
147
+ function insertBeforeAndAfterSWC(content, span, /**
148
+ * WARNING: This is ONLY for unit tests. Defaults to 0 otherwise.
149
+ *
150
+ * @see compileTypeScriptFileToAST
151
+ */ parseOffset) {
152
+ const { end: preOffsetEnd, start: preOffsetStart } = span;
153
+ const start = preOffsetStart - parseOffset;
154
+ const end = preOffsetEnd - parseOffset;
155
+ const insert = (pos, text)=>{
156
+ return content.slice(0, pos) + text + content.slice(pos);
157
+ };
158
+ // insert ) after end
159
+ content = insert(end - 1, ')');
160
+ // insert withPayload before start
161
+ content = insert(start - 1, 'withPayload(');
162
+ return content;
163
+ }
164
+ /**
165
+ * Compile typescript to AST using the swc compiler
166
+ */ async function compileTypeScriptFileToAST(fileContent) {
167
+ let parseOffset = 0;
168
+ /**
169
+ * WARNING: This is ONLY for unit tests.
170
+ *
171
+ * Multiple instances of swc DO NOT reset the .span.end value.
172
+ * During unit tests, the .spawn.end value is read and accounted for.
173
+ *
174
+ * https://github.com/swc-project/swc/issues/1366
175
+ */ if (process.env.NODE_ENV === 'test') {
176
+ parseOffset = (await swc.parse('')).span.end;
177
+ }
178
+ const module = await swc.parse(fileContent, {
179
+ syntax: 'typescript'
180
+ });
181
+ return {
182
+ moduleItems: module.body,
183
+ parseOffset
184
+ };
185
+ }
123
186
 
124
187
  //# 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":"AAEA,OAAOA,WAAW,QAAO;AACzB,SAASC,MAAM,EAAEC,WAAW,QAAQ,eAAc;AAClD,OAAOC,QAAQ,KAAI;AAEnB,SAASC,OAAO,QAAQ,kBAAiB;AACzC,SAASC,GAAG,QAAQ,kBAAiB;AAErC,OAAO,MAAMC,uBAAuB;IAClCC,KAAK,CAAC,iEAAiE,CAAC;IACxEC,KAAK,CAAC,4DAA4D,CAAC;AACrE,EAAC;AAID,OAAO,MAAMC,iBAAiB,CAACC;IAI7B,MAAM,EAAEC,cAAc,EAAEC,gBAAgBC,UAAU,EAAE,GAAGH;IACvD,MAAMI,gBAAgBX,GAAGY,YAAY,CAACJ,gBAAgB;IACtD,MAAM,EAAEK,uBAAuBC,SAAS,EAAEC,OAAO,EAAE,GAAGC,4BACpDL,eACAD;IAGF,IAAI,CAACK,SAAS;QACZ;IACF;IAEAf,GAAGiB,aAAa,CAACT,gBAAgBM;AACnC,EAAC;AAED;;CAEC,GACD,OAAO,SAASE,4BACdE,OAAe,EACfR,UAA0B;IAE1BQ,UAAUf,oBAAoB,CAACO,WAAW,GAAGQ;IAE7C,IAAIC;IACJ,IAAI;QACFA,MAAMpB,YAAYmB,SAAS;YAAEE,KAAK;QAAK;IACzC,EAAE,OAAOC,OAAgB;QACvB,IAAIA,iBAAiBC,OAAO;YAC1BrB,QAAQ,CAAC,oCAAoC,EAAEoB,MAAME,OAAO,CAAC,CAAC,CAAC;YAC/DC,0BAA0Bd;QAC5B;QACA,OAAO;YACLG,uBAAuBK;YACvBH,SAAS;QACX;IACF;IAEA,IAAIL,eAAe,OAAO;QACxB,MAAMe,2BAA2BN,IAAIO,IAAI,CAACC,IAAI,CAC5C,CAACC,IAAMA,EAAEC,IAAI,KAAK/B,OAAOgC,wBAAwB;QAGnD,MAAMC,yBAAyBZ,IAAIO,IAAI,CAACC,IAAI,CAC1C,CAACC,IAAMA,EAAEC,IAAI,KAAK/B,OAAOkC,sBAAsB;QAGjD,IAAI,CAACP,4BAA4B,CAACM,wBAAwB;YACxD,MAAM,IAAIT,MAAM;QAClB;QAEA,IAAIG,4BAA4BA,yBAAyBQ,WAAW,EAAEb,KAAK;YACzE,MAAMP,wBAAwBqB,qBAC5BhB,SACAO,yBAAyBQ,WAAW,CAACb,GAAG;YAE1C,OAAO;gBAAEP;gBAAuBE,SAAS;YAAK;QAChD,OAAO,IAAIgB,wBAAwB;YACjC,MAAMI,kBAAkBJ,uBAAuBK,UAAU,CAACT,IAAI,CAC5D,CAACU,IACCA,EAAER,IAAI,KAAK,qBACXQ,EAAEC,QAAQ,EAAEC,SAAS,aACrBF,EAAEG,KAAK,EAAEX,SAAS,gBAClBQ,EAAEG,KAAK,EAAED;YAGb,IAAIJ,iBAAiB;gBACnBlC,QAAQ;gBACRA,QAAQ;gBAERuB,0BAA0Bd;gBAC1B,OAAO;oBACLG,uBAAuBK;oBACvBH,SAAS;gBACX;YACF;QACF;QAEAd,QAAQ;QACRuB,0BAA0Bd;QAC1B,OAAO;YACLG,uBAAuBK;YACvBH,SAAS;QACX;IACF,OAAO,IAAIL,eAAe,OAAO;QAC/B,4BAA4B;QAC5B,MAAM+B,gBAAgBtB,IAAIO,IAAI,CAACC,IAAI,CACjC,CAACC,IACCA,EAAEC,IAAI,KAAK/B,OAAO4C,mBAAmB,IACrCd,EAAEe,UAAU,EAAEd,SAAS/B,OAAO8C,oBAAoB,IAClDhB,EAAEe,UAAU,CAACE,IAAI,EAAEhB,SAAS/B,OAAOgD,gBAAgB,IACnDlB,EAAEe,UAAU,CAACE,IAAI,CAACE,MAAM,EAAElB,SAAS/B,OAAOkD,UAAU,IACpDpB,EAAEe,UAAU,CAACE,IAAI,CAACE,MAAM,CAACR,IAAI,KAAK,YAClCX,EAAEe,UAAU,CAACE,IAAI,CAACI,QAAQ,EAAEpB,SAAS/B,OAAOkD,UAAU,IACtDpB,EAAEe,UAAU,CAACE,IAAI,CAACI,QAAQ,CAACV,IAAI,KAAK;QAIxC,IAAIE,iBAAiBA,cAAcE,UAAU,CAACO,KAAK,EAAE9B,KAAK;YACxD,MAAMP,wBAAwBqB,qBAC5BhB,SACAuB,cAAcE,UAAU,CAACO,KAAK,CAAC9B,GAAG;YAEpC,OAAO;gBAAEP;gBAAuBE,SAAS;YAAK;QAChD;QAEA,OAAO;YACLF,uBAAuBK;YACvBH,SAAS;QACX;IACF;IAEAd,QAAQ;IACRuB,0BAA0Bd;IAC1B,OAAO;QACLG,uBAAuBK;QACvBH,SAAS;IACX;AACF;AAEA,SAASS,0BAA0Bd,UAA0B;IAC3D,sDAAsD;IACtD,MAAMyC,qBAAqB,CAAC;;EAE5B,EAAEtD,MAAMuD,IAAI,CAAC,CAAC,oGAAoG,CAAC,EAAE;;EAErH,EAAEjD,oBAAoB,CAACO,WAAW,CAAC;;;;;;EAMnC,EAAEA,eAAe,QAAQ,2CAA2C,2CAA2C;;AAEjH,CAAC;IAECR,IAAIiD;AACN;AAiCA,SAASjB,qBAAqBhB,OAAe,EAAEE,GAAQ;IACrD,MAAM,EAAEiC,GAAG,EAAEC,KAAK,EAAE,GAAGlC;IACvB,MAAMmC,QAAQrC,QAAQsC,KAAK,CAAC;IAE5B,MAAMC,SAAS,CAACC,MAAcC,QAAgBC;QAC5C,OAAOF,KAAKG,KAAK,CAAC,GAAGF,UAAUC,OAAOF,KAAKG,KAAK,CAACF;IACnD;IAEA,qBAAqB;IACrBJ,KAAK,CAACF,IAAIK,IAAI,GAAG,EAAE,GAAGD,OAAOF,KAAK,CAACF,IAAIK,IAAI,GAAG,EAAE,EAAEL,IAAIM,MAAM,EAAE;IAC9D,kCAAkC;IAClC,IAAIL,MAAMI,IAAI,KAAKL,IAAIK,IAAI,EAAE;QAC3BH,KAAK,CAACF,IAAIK,IAAI,GAAG,EAAE,GAAGD,OAAOF,KAAK,CAACF,IAAIK,IAAI,GAAG,EAAE,EAAEJ,MAAMK,MAAM,EAAE;IAClE,OAAO;QACLJ,KAAK,CAACD,MAAMI,IAAI,GAAG,EAAE,GAAGD,OAAOF,KAAK,CAACD,MAAMI,IAAI,GAAG,EAAE,EAAEJ,MAAMK,MAAM,EAAE;IACtE;IAEA,OAAOJ,MAAMO,IAAI,CAAC;AACpB"}
1
+ {"version":3,"sources":["../../src/lib/wrap-next-config.ts"],"sourcesContent":["import type { ExportDefaultExpression, ModuleItem } from '@swc/core'\n\nimport swc from '@swc/core'\nimport chalk from 'chalk'\nimport { Syntax, parseModule } 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 console.log({ configType, 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 swc.parse('')).span.end\n }\n\n const module = await swc.parse(fileContent, {\n syntax: 'typescript',\n })\n\n return { moduleItems: module.body, parseOffset }\n}\n"],"names":["swc","chalk","Syntax","parseModule","fs","log","warning","withPayloadStatement","cjs","esm","ts","wrapNextConfig","args","nextConfigPath","nextConfigType","configType","configContent","readFileSync","modifiedConfigContent","newConfig","success","parseAndModifyConfigContent","writeFileSync","content","console","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","parse","module","syntax"],"mappings":"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"}