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
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Main } from './main.js'\nimport { error } from './utils/log.js'\n\nexport async function main(): Promise<void> {\n try {\n await new Main().init()\n } catch (e) {\n if (e instanceof Error) {\n error(e.message)\n }\n }\n}\n"],"names":["Main","error","main","init","e","Error","message"],"rangeMappings":";;;;;;;;;;","mappings":"AAAA,SAASA,IAAI,QAAQ,YAAW;AAChC,SAASC,KAAK,QAAQ,iBAAgB;AAEtC,OAAO,eAAeC;IACpB,IAAI;QACF,MAAM,IAAIF,OAAOG,IAAI;IACvB,EAAE,OAAOC,GAAG;QACV,IAAIA,aAAaC,OAAO;YACtBJ,MAAMG,EAAEE,OAAO;QACjB;IACF;AACF"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Main } from './main.js'\nimport { error } from './utils/log.js'\n\nexport async function main(): Promise<void> {\n try {\n await new Main().init()\n } catch (e) {\n if (e instanceof Error) {\n error(e.message)\n }\n }\n}\n"],"names":["Main","error","main","init","e","Error","message"],"mappings":"AAAA,SAASA,IAAI,QAAQ,YAAW;AAChC,SAASC,KAAK,QAAQ,iBAAgB;AAEtC,OAAO,eAAeC;IACpB,IAAI;QACF,MAAM,IAAIF,OAAOG,IAAI;IACvB,EAAE,OAAOC,GAAG;QACV,IAAIA,aAAaC,OAAO;YACtBJ,MAAMG,EAAEE,OAAO;QACjB;IACF;AACF"}
@@ -1,11 +1,17 @@
1
- import type { DbDetails } from '../types.js';
1
+ import type { DbType, StorageAdapterType } from '../types.js';
2
2
  /** Update payload config with necessary imports and adapters */
3
3
  export declare function configurePayloadConfig(args: {
4
- dbDetails: DbDetails | undefined;
4
+ dbType?: DbType;
5
+ envNames?: {
6
+ dbUri: string;
7
+ };
8
+ packageJsonName?: string;
5
9
  projectDirOrConfigPath: {
6
10
  payloadConfigPath: string;
7
11
  } | {
8
12
  projectDir: string;
9
13
  };
14
+ sharp?: boolean;
15
+ storageAdapter?: StorageAdapterType;
10
16
  }): Promise<void>;
11
17
  //# sourceMappingURL=configure-payload-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure-payload-config.d.ts","sourceRoot":"","sources":["../../src/lib/configure-payload-config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAK5C,gEAAgE;AAChE,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,SAAS,EAAE,SAAS,GAAG,SAAS,CAAA;IAChC,sBAAsB,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAC/E,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFhB"}
1
+ {"version":3,"file":"configure-payload-config.d.ts","sourceRoot":"","sources":["../../src/lib/configure-payload-config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAK7D,gEAAgE;AAChE,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,sBAAsB,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,cAAc,CAAC,EAAE,kBAAkB,CAAA;CACpC,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HhB"}
@@ -1,13 +1,10 @@
1
1
  import fse from 'fs-extra';
2
2
  import globby from 'globby';
3
- import { fileURLToPath } from 'node:url';
4
3
  import path from 'path';
5
- const filename = fileURLToPath(import.meta.url);
6
- const dirname = path.dirname(filename);
7
4
  import { warning } from '../utils/log.js';
8
- import { dbReplacements } from './packages.js';
5
+ import { dbReplacements, storageReplacements } from './replacements.js';
9
6
  /** Update payload config with necessary imports and adapters */ export async function configurePayloadConfig(args) {
10
- if (!args.dbDetails) {
7
+ if (!args.dbType) {
11
8
  return;
12
9
  }
13
10
  // Update package.json
@@ -15,7 +12,7 @@ import { dbReplacements } from './packages.js';
15
12
  if (packageJsonPath && fse.existsSync(packageJsonPath)) {
16
13
  try {
17
14
  const packageObj = await fse.readJson(packageJsonPath);
18
- const dbPackage = dbReplacements[args.dbDetails.type];
15
+ const dbPackage = dbReplacements[args.dbType];
19
16
  // Delete all other db adapters
20
17
  Object.values(dbReplacements).forEach((p)=>{
21
18
  if (p.packageName !== dbPackage.packageName) {
@@ -24,6 +21,20 @@ import { dbReplacements } from './packages.js';
24
21
  });
25
22
  // Set version of db adapter to match payload version
26
23
  packageObj.dependencies[dbPackage.packageName] = packageObj.dependencies['payload'];
24
+ if (args.storageAdapter) {
25
+ const storagePackage = storageReplacements[args.storageAdapter];
26
+ if (storagePackage?.packageName) {
27
+ // Set version of storage adapter to match payload version
28
+ packageObj.dependencies[storagePackage.packageName] = packageObj.dependencies['payload'];
29
+ }
30
+ }
31
+ // Sharp provided by default, only remove if explicitly set to false
32
+ if (args.sharp === false) {
33
+ delete packageObj.dependencies['sharp'];
34
+ }
35
+ if (args.packageJsonName) {
36
+ packageObj.name = args.packageJsonName;
37
+ }
27
38
  await fse.writeJson(packageJsonPath, packageObj, {
28
39
  spaces: 2
29
40
  });
@@ -47,31 +58,69 @@ import { dbReplacements } from './packages.js';
47
58
  return;
48
59
  }
49
60
  const configContent = fse.readFileSync(payloadConfigPath, 'utf-8');
50
- const configLines = configContent.split('\n');
51
- const dbReplacement = dbReplacements[args.dbDetails.type];
52
- let dbConfigStartLineIndex;
53
- let dbConfigEndLineIndex;
54
- configLines.forEach((l, i)=>{
55
- if (l.includes('// database-adapter-import')) {
56
- configLines[i] = dbReplacement.importReplacement;
57
- }
58
- if (l.includes('// database-adapter-config-start')) {
59
- dbConfigStartLineIndex = i;
60
- }
61
- if (l.includes('// database-adapter-config-end')) {
62
- dbConfigEndLineIndex = i;
63
- }
61
+ let configLines = configContent.split('\n');
62
+ // DB Replacement
63
+ const dbReplacement = dbReplacements[args.dbType];
64
+ configLines = replaceInConfigLines({
65
+ endMatch: `// database-adapter-config-end`,
66
+ lines: configLines,
67
+ replacement: dbReplacement.configReplacement(args.envNames?.dbUri),
68
+ startMatch: `// database-adapter-config-start`
64
69
  });
65
- if (!dbConfigStartLineIndex || !dbConfigEndLineIndex) {
66
- warning('Unable to update payload.config.ts with database adapter import');
67
- } else {
68
- // Replaces lines between `// database-adapter-config-start` and `// database-adapter-config-end`
69
- configLines.splice(dbConfigStartLineIndex, dbConfigEndLineIndex - dbConfigStartLineIndex + 1, ...dbReplacement.configReplacement);
70
+ configLines = replaceInConfigLines({
71
+ lines: configLines,
72
+ replacement: [
73
+ dbReplacement.importReplacement
74
+ ],
75
+ startMatch: '// database-adapter-import'
76
+ });
77
+ // Storage Adapter Replacement
78
+ if (args.storageAdapter) {
79
+ const replacement = storageReplacements[args.storageAdapter];
80
+ configLines = replaceInConfigLines({
81
+ lines: configLines,
82
+ replacement: replacement.configReplacement,
83
+ startMatch: '// storage-adapter-placeholder'
84
+ });
85
+ if (replacement?.importReplacement !== undefined) {
86
+ configLines = replaceInConfigLines({
87
+ lines: configLines,
88
+ replacement: [
89
+ replacement.importReplacement
90
+ ],
91
+ startMatch: '// storage-adapter-import-placeholder'
92
+ });
93
+ }
94
+ }
95
+ // Sharp Replacement (provided by default, only remove if explicitly set to false)
96
+ if (args.sharp === false) {
97
+ configLines = replaceInConfigLines({
98
+ lines: configLines,
99
+ replacement: [],
100
+ startMatch: 'sharp,'
101
+ });
102
+ configLines = replaceInConfigLines({
103
+ lines: configLines,
104
+ replacement: [],
105
+ startMatch: "import sharp from 'sharp'"
106
+ });
70
107
  }
71
108
  fse.writeFileSync(payloadConfigPath, configLines.join('\n'));
72
109
  } catch (err) {
73
110
  warning(`Unable to update payload.config.ts with plugins: ${err instanceof Error ? err.message : ''}`);
74
111
  }
75
112
  }
113
+ function replaceInConfigLines({ endMatch, lines, replacement, startMatch }) {
114
+ if (!replacement) {
115
+ return lines;
116
+ }
117
+ const startIndex = lines.findIndex((l)=>l.includes(startMatch));
118
+ const endIndex = endMatch ? lines.findIndex((l)=>l.includes(endMatch)) : startIndex;
119
+ if (startIndex === -1 || endIndex === -1) {
120
+ return lines;
121
+ }
122
+ lines.splice(startIndex, endIndex - startIndex + 1, ...replacement);
123
+ return lines;
124
+ }
76
125
 
77
126
  //# sourceMappingURL=configure-payload-config.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/configure-payload-config.ts"],"sourcesContent":["import fse from 'fs-extra'\nimport globby from 'globby'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nimport type { DbDetails } from '../types.js'\n\nimport { warning } from '../utils/log.js'\nimport { dbReplacements } from './packages.js'\n\n/** Update payload config with necessary imports and adapters */\nexport async function configurePayloadConfig(args: {\n dbDetails: DbDetails | undefined\n projectDirOrConfigPath: { payloadConfigPath: string } | { projectDir: string }\n}): Promise<void> {\n if (!args.dbDetails) {\n return\n }\n\n // Update package.json\n const packageJsonPath =\n 'projectDir' in args.projectDirOrConfigPath &&\n path.resolve(args.projectDirOrConfigPath.projectDir, 'package.json')\n\n if (packageJsonPath && fse.existsSync(packageJsonPath)) {\n try {\n const packageObj = await fse.readJson(packageJsonPath)\n\n const dbPackage = dbReplacements[args.dbDetails.type]\n\n // Delete all other db adapters\n Object.values(dbReplacements).forEach((p) => {\n if (p.packageName !== dbPackage.packageName) {\n delete packageObj.dependencies[p.packageName]\n }\n })\n\n // Set version of db adapter to match payload version\n packageObj.dependencies[dbPackage.packageName] = packageObj.dependencies['payload']\n\n await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })\n } catch (err: unknown) {\n warning(`Unable to configure Payload in package.json`)\n warning(err instanceof Error ? err.message : '')\n }\n }\n\n try {\n let payloadConfigPath: string | undefined\n if (!('payloadConfigPath' in args.projectDirOrConfigPath)) {\n payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: args.projectDirOrConfigPath.projectDir,\n })\n )?.[0]\n } else {\n payloadConfigPath = args.projectDirOrConfigPath.payloadConfigPath\n }\n\n if (!payloadConfigPath) {\n warning('Unable to update payload.config.ts with plugins. Could not find payload.config.ts.')\n return\n }\n\n const configContent = fse.readFileSync(payloadConfigPath, 'utf-8')\n const configLines = configContent.split('\\n')\n\n const dbReplacement = dbReplacements[args.dbDetails.type]\n\n let dbConfigStartLineIndex: number | undefined\n let dbConfigEndLineIndex: number | undefined\n\n configLines.forEach((l, i) => {\n if (l.includes('// database-adapter-import')) {\n configLines[i] = dbReplacement.importReplacement\n }\n\n if (l.includes('// database-adapter-config-start')) {\n dbConfigStartLineIndex = i\n }\n if (l.includes('// database-adapter-config-end')) {\n dbConfigEndLineIndex = i\n }\n })\n\n if (!dbConfigStartLineIndex || !dbConfigEndLineIndex) {\n warning('Unable to update payload.config.ts with database adapter import')\n } else {\n // Replaces lines between `// database-adapter-config-start` and `// database-adapter-config-end`\n configLines.splice(\n dbConfigStartLineIndex,\n dbConfigEndLineIndex - dbConfigStartLineIndex + 1,\n ...dbReplacement.configReplacement,\n )\n }\n\n fse.writeFileSync(payloadConfigPath, configLines.join('\\n'))\n } catch (err: unknown) {\n warning(\n `Unable to update payload.config.ts with plugins: ${err instanceof Error ? err.message : ''}`,\n )\n }\n}\n"],"names":["fse","globby","fileURLToPath","path","filename","url","dirname","warning","dbReplacements","configurePayloadConfig","args","dbDetails","packageJsonPath","projectDirOrConfigPath","resolve","projectDir","existsSync","packageObj","readJson","dbPackage","type","Object","values","forEach","p","packageName","dependencies","writeJson","spaces","err","Error","message","payloadConfigPath","absolute","cwd","configContent","readFileSync","configLines","split","dbReplacement","dbConfigStartLineIndex","dbConfigEndLineIndex","l","i","includes","importReplacement","splice","configReplacement","writeFileSync","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,SAAS,WAAU;AAC1B,OAAOC,YAAY,SAAQ;AAC3B,SAASC,aAAa,QAAQ,WAAU;AACxC,OAAOC,UAAU,OAAM;AACvB,MAAMC,WAAWF,cAAc,YAAYG,GAAG;AAC9C,MAAMC,UAAUH,KAAKG,OAAO,CAACF;AAI7B,SAASG,OAAO,QAAQ,kBAAiB;AACzC,SAASC,cAAc,QAAQ,gBAAe;AAE9C,8DAA8D,GAC9D,OAAO,eAAeC,uBAAuBC,IAG5C;IACC,IAAI,CAACA,KAAKC,SAAS,EAAE;QACnB;IACF;IAEA,sBAAsB;IACtB,MAAMC,kBACJ,gBAAgBF,KAAKG,sBAAsB,IAC3CV,KAAKW,OAAO,CAACJ,KAAKG,sBAAsB,CAACE,UAAU,EAAE;IAEvD,IAAIH,mBAAmBZ,IAAIgB,UAAU,CAACJ,kBAAkB;QACtD,IAAI;YACF,MAAMK,aAAa,MAAMjB,IAAIkB,QAAQ,CAACN;YAEtC,MAAMO,YAAYX,cAAc,CAACE,KAAKC,SAAS,CAACS,IAAI,CAAC;YAErD,+BAA+B;YAC/BC,OAAOC,MAAM,CAACd,gBAAgBe,OAAO,CAAC,CAACC;gBACrC,IAAIA,EAAEC,WAAW,KAAKN,UAAUM,WAAW,EAAE;oBAC3C,OAAOR,WAAWS,YAAY,CAACF,EAAEC,WAAW,CAAC;gBAC/C;YACF;YAEA,qDAAqD;YACrDR,WAAWS,YAAY,CAACP,UAAUM,WAAW,CAAC,GAAGR,WAAWS,YAAY,CAAC,UAAU;YAEnF,MAAM1B,IAAI2B,SAAS,CAACf,iBAAiBK,YAAY;gBAAEW,QAAQ;YAAE;QAC/D,EAAE,OAAOC,KAAc;YACrBtB,QAAQ,CAAC,2CAA2C,CAAC;YACrDA,QAAQsB,eAAeC,QAAQD,IAAIE,OAAO,GAAG;QAC/C;IACF;IAEA,IAAI;QACF,IAAIC;QACJ,IAAI,CAAE,CAAA,uBAAuBtB,KAAKG,sBAAsB,AAAD,GAAI;YACzDmB,oBACE,CAAA,MAAM/B,OAAO,wBAAwB;gBACnCgC,UAAU;gBACVC,KAAKxB,KAAKG,sBAAsB,CAACE,UAAU;YAC7C,EAAC,GACA,CAAC,EAAE;QACR,OAAO;YACLiB,oBAAoBtB,KAAKG,sBAAsB,CAACmB,iBAAiB;QACnE;QAEA,IAAI,CAACA,mBAAmB;YACtBzB,QAAQ;YACR;QACF;QAEA,MAAM4B,gBAAgBnC,IAAIoC,YAAY,CAACJ,mBAAmB;QAC1D,MAAMK,cAAcF,cAAcG,KAAK,CAAC;QAExC,MAAMC,gBAAgB/B,cAAc,CAACE,KAAKC,SAAS,CAACS,IAAI,CAAC;QAEzD,IAAIoB;QACJ,IAAIC;QAEJJ,YAAYd,OAAO,CAAC,CAACmB,GAAGC;YACtB,IAAID,EAAEE,QAAQ,CAAC,+BAA+B;gBAC5CP,WAAW,CAACM,EAAE,GAAGJ,cAAcM,iBAAiB;YAClD;YAEA,IAAIH,EAAEE,QAAQ,CAAC,qCAAqC;gBAClDJ,yBAAyBG;YAC3B;YACA,IAAID,EAAEE,QAAQ,CAAC,mCAAmC;gBAChDH,uBAAuBE;YACzB;QACF;QAEA,IAAI,CAACH,0BAA0B,CAACC,sBAAsB;YACpDlC,QAAQ;QACV,OAAO;YACL,iGAAiG;YACjG8B,YAAYS,MAAM,CAChBN,wBACAC,uBAAuBD,yBAAyB,MAC7CD,cAAcQ,iBAAiB;QAEtC;QAEA/C,IAAIgD,aAAa,CAAChB,mBAAmBK,YAAYY,IAAI,CAAC;IACxD,EAAE,OAAOpB,KAAc;QACrBtB,QACE,CAAC,iDAAiD,EAAEsB,eAAeC,QAAQD,IAAIE,OAAO,GAAG,GAAG,CAAC;IAEjG;AACF"}
1
+ {"version":3,"sources":["../../src/lib/configure-payload-config.ts"],"sourcesContent":["import fse from 'fs-extra'\nimport globby from 'globby'\nimport path from 'path'\n\nimport type { DbType, StorageAdapterType } from '../types.js'\n\nimport { warning } from '../utils/log.js'\nimport { dbReplacements, storageReplacements } from './replacements.js'\n\n/** Update payload config with necessary imports and adapters */\nexport async function configurePayloadConfig(args: {\n dbType?: DbType\n envNames?: {\n dbUri: string\n }\n packageJsonName?: string\n projectDirOrConfigPath: { payloadConfigPath: string } | { projectDir: string }\n sharp?: boolean\n storageAdapter?: StorageAdapterType\n}): Promise<void> {\n if (!args.dbType) {\n return\n }\n\n // Update package.json\n const packageJsonPath =\n 'projectDir' in args.projectDirOrConfigPath &&\n path.resolve(args.projectDirOrConfigPath.projectDir, 'package.json')\n\n if (packageJsonPath && fse.existsSync(packageJsonPath)) {\n try {\n const packageObj = await fse.readJson(packageJsonPath)\n\n const dbPackage = dbReplacements[args.dbType]\n\n // Delete all other db adapters\n Object.values(dbReplacements).forEach((p) => {\n if (p.packageName !== dbPackage.packageName) {\n delete packageObj.dependencies[p.packageName]\n }\n })\n\n // Set version of db adapter to match payload version\n packageObj.dependencies[dbPackage.packageName] = packageObj.dependencies['payload']\n\n if (args.storageAdapter) {\n const storagePackage = storageReplacements[args.storageAdapter]\n\n if (storagePackage?.packageName) {\n // Set version of storage adapter to match payload version\n packageObj.dependencies[storagePackage.packageName] = packageObj.dependencies['payload']\n }\n }\n\n // Sharp provided by default, only remove if explicitly set to false\n if (args.sharp === false) {\n delete packageObj.dependencies['sharp']\n }\n\n if (args.packageJsonName) {\n packageObj.name = args.packageJsonName\n }\n\n await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })\n } catch (err: unknown) {\n warning(`Unable to configure Payload in package.json`)\n warning(err instanceof Error ? err.message : '')\n }\n }\n\n try {\n let payloadConfigPath: string | undefined\n if (!('payloadConfigPath' in args.projectDirOrConfigPath)) {\n payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: args.projectDirOrConfigPath.projectDir,\n })\n )?.[0]\n } else {\n payloadConfigPath = args.projectDirOrConfigPath.payloadConfigPath\n }\n\n if (!payloadConfigPath) {\n warning('Unable to update payload.config.ts with plugins. Could not find payload.config.ts.')\n return\n }\n\n const configContent = fse.readFileSync(payloadConfigPath, 'utf-8')\n let configLines = configContent.split('\\n')\n\n // DB Replacement\n const dbReplacement = dbReplacements[args.dbType]\n\n configLines = replaceInConfigLines({\n endMatch: `// database-adapter-config-end`,\n lines: configLines,\n replacement: dbReplacement.configReplacement(args.envNames?.dbUri),\n startMatch: `// database-adapter-config-start`,\n })\n\n configLines = replaceInConfigLines({\n lines: configLines,\n replacement: [dbReplacement.importReplacement],\n startMatch: '// database-adapter-import',\n })\n\n // Storage Adapter Replacement\n if (args.storageAdapter) {\n const replacement = storageReplacements[args.storageAdapter]\n configLines = replaceInConfigLines({\n lines: configLines,\n replacement: replacement.configReplacement,\n startMatch: '// storage-adapter-placeholder',\n })\n\n if (replacement?.importReplacement !== undefined) {\n configLines = replaceInConfigLines({\n lines: configLines,\n replacement: [replacement.importReplacement],\n startMatch: '// storage-adapter-import-placeholder',\n })\n }\n }\n\n // Sharp Replacement (provided by default, only remove if explicitly set to false)\n if (args.sharp === false) {\n configLines = replaceInConfigLines({\n lines: configLines,\n replacement: [],\n startMatch: 'sharp,',\n })\n configLines = replaceInConfigLines({\n lines: configLines,\n replacement: [],\n startMatch: \"import sharp from 'sharp'\",\n })\n }\n\n fse.writeFileSync(payloadConfigPath, configLines.join('\\n'))\n } catch (err: unknown) {\n warning(\n `Unable to update payload.config.ts with plugins: ${err instanceof Error ? err.message : ''}`,\n )\n }\n}\n\nfunction replaceInConfigLines({\n endMatch,\n lines,\n replacement,\n startMatch,\n}: {\n /** Optional endMatch to replace multiple lines */\n endMatch?: string\n lines: string[]\n replacement: string[]\n startMatch: string\n}) {\n if (!replacement) {\n return lines\n }\n\n const startIndex = lines.findIndex((l) => l.includes(startMatch))\n const endIndex = endMatch ? lines.findIndex((l) => l.includes(endMatch)) : startIndex\n\n if (startIndex === -1 || endIndex === -1) {\n return lines\n }\n\n lines.splice(startIndex, endIndex - startIndex + 1, ...replacement)\n return lines\n}\n"],"names":["fse","globby","path","warning","dbReplacements","storageReplacements","configurePayloadConfig","args","dbType","packageJsonPath","projectDirOrConfigPath","resolve","projectDir","existsSync","packageObj","readJson","dbPackage","Object","values","forEach","p","packageName","dependencies","storageAdapter","storagePackage","sharp","packageJsonName","name","writeJson","spaces","err","Error","message","payloadConfigPath","absolute","cwd","configContent","readFileSync","configLines","split","dbReplacement","replaceInConfigLines","endMatch","lines","replacement","configReplacement","envNames","dbUri","startMatch","importReplacement","undefined","writeFileSync","join","startIndex","findIndex","l","includes","endIndex","splice"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const PACKAGE_VERSION: any;
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe,KAAsB,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { readFileSync } from 'fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'path';
4
+ const filename = fileURLToPath(import.meta.url);
5
+ const dirname = path.dirname(filename);
6
+ const packageJson = JSON.parse(readFileSync(path.resolve(dirname, '../../package.json'), 'utf-8'));
7
+ export const PACKAGE_VERSION = packageJson.version;
8
+
9
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/constants.ts"],"sourcesContent":["import { readFileSync } from 'fs'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nconst packageJson = JSON.parse(readFileSync(path.resolve(dirname, '../../package.json'), 'utf-8'))\nexport const PACKAGE_VERSION = packageJson.version\n"],"names":["readFileSync","fileURLToPath","path","filename","url","dirname","packageJson","JSON","parse","resolve","PACKAGE_VERSION","version"],"mappings":"AAAA,SAASA,YAAY,QAAQ,KAAI;AACjC,SAASC,aAAa,QAAQ,WAAU;AACxC,OAAOC,UAAU,OAAM;AACvB,MAAMC,WAAWF,cAAc,YAAYG,GAAG;AAC9C,MAAMC,UAAUH,KAAKG,OAAO,CAACF;AAE7B,MAAMG,cAAcC,KAAKC,KAAK,CAACR,aAAaE,KAAKO,OAAO,CAACJ,SAAS,uBAAuB;AACzF,OAAO,MAAMK,kBAAkBJ,YAAYK,OAAO,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../src/lib/create-project.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AA4CtF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,eAAe,CAAA;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB"}
1
+ {"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../../src/lib/create-project.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AA+CtF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,eAAe,CAAA;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB"}
@@ -1,6 +1,5 @@
1
1
  import * as p from '@clack/prompts';
2
2
  import chalk from 'chalk';
3
- import degit from 'degit';
4
3
  import execa from 'execa';
5
4
  import fse from 'fs-extra';
6
5
  import { fileURLToPath } from 'node:url';
@@ -8,6 +7,7 @@ import path from 'path';
8
7
  import { tryInitRepoAndCommit } from '../utils/git.js';
9
8
  import { debug, error, info, warning } from '../utils/log.js';
10
9
  import { configurePayloadConfig } from './configure-payload-config.js';
10
+ import { downloadTemplate } from './download-template.js';
11
11
  const filename = fileURLToPath(import.meta.url);
12
12
  const dirname = path.dirname(filename);
13
13
  async function createOrFindProjectDir(projectDir) {
@@ -26,6 +26,8 @@ async function installDeps(args) {
26
26
  installCmd = 'yarn';
27
27
  } else if (packageManager === 'pnpm') {
28
28
  installCmd = 'pnpm install';
29
+ } else if (packageManager === 'bun') {
30
+ installCmd = 'bun install';
29
31
  }
30
32
  try {
31
33
  await execa.command(installCmd, {
@@ -54,8 +56,11 @@ export async function createProject(args) {
54
56
  templateUrl = `${template.url}#${cliArgs['--template-branch']}`;
55
57
  debug(`Using template url: ${templateUrl}`);
56
58
  }
57
- const emitter = degit(templateUrl);
58
- await emitter.clone(projectDir);
59
+ await downloadTemplate({
60
+ name: template.name,
61
+ branch: 'beta',
62
+ projectDir
63
+ });
59
64
  }
60
65
  const spinner = p.spinner();
61
66
  spinner.start('Checking latest Payload version...');
@@ -65,13 +70,13 @@ export async function createProject(args) {
65
70
  });
66
71
  spinner.message('Configuring Payload...');
67
72
  await configurePayloadConfig({
68
- dbDetails,
73
+ dbType: dbDetails?.type,
69
74
  projectDirOrConfigPath: {
70
75
  projectDir
71
76
  }
72
77
  });
73
78
  // Remove yarn.lock file. This is only desired in Payload Cloud.
74
- const lockPath = path.resolve(projectDir, 'yarn.lock');
79
+ const lockPath = path.resolve(projectDir, 'pnpm-lock.yaml');
75
80
  if (fse.existsSync(lockPath)) {
76
81
  await fse.remove(lockPath);
77
82
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/create-project.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport chalk from 'chalk'\nimport degit from 'degit'\nimport execa from 'execa'\nimport fse from 'fs-extra'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nimport type { CliArgs, DbDetails, PackageManager, ProjectTemplate } from '../types.js'\n\nimport { tryInitRepoAndCommit } from '../utils/git.js'\nimport { debug, error, info, warning } from '../utils/log.js'\nimport { configurePayloadConfig } from './configure-payload-config.js'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nasync function createOrFindProjectDir(projectDir: string): Promise<void> {\n const pathExists = await fse.pathExists(projectDir)\n if (!pathExists) {\n await fse.mkdir(projectDir)\n }\n}\n\nasync function installDeps(args: {\n cliArgs: CliArgs\n packageManager: PackageManager\n projectDir: string\n}): Promise<boolean> {\n const { cliArgs, packageManager, projectDir } = args\n if (cliArgs['--no-deps']) {\n return true\n }\n let installCmd = 'npm install --legacy-peer-deps'\n\n if (packageManager === 'yarn') {\n installCmd = 'yarn'\n } else if (packageManager === 'pnpm') {\n installCmd = 'pnpm install'\n }\n\n try {\n await execa.command(installCmd, {\n cwd: path.resolve(projectDir),\n })\n return true\n } catch (err: unknown) {\n error(`Error installing dependencies${err instanceof Error ? `: ${err.message}` : ''}.`)\n return false\n }\n}\n\nexport async function createProject(args: {\n cliArgs: CliArgs\n dbDetails?: DbDetails\n packageManager: PackageManager\n projectDir: string\n projectName: string\n template: ProjectTemplate\n}): Promise<void> {\n const { cliArgs, dbDetails, packageManager, projectDir, projectName, template } = args\n\n if (cliArgs['--dry-run']) {\n debug(`Dry run: Creating project in ${chalk.green(projectDir)}`)\n return\n }\n\n await createOrFindProjectDir(projectDir)\n\n if (cliArgs['--local-template']) {\n // Copy template from local path. For development purposes.\n const localTemplate = path.resolve(\n dirname,\n '../../../../templates/',\n cliArgs['--local-template'],\n )\n await fse.copy(localTemplate, projectDir)\n } else if ('url' in template) {\n let templateUrl = template.url\n if (cliArgs['--template-branch']) {\n templateUrl = `${template.url}#${cliArgs['--template-branch']}`\n debug(`Using template url: ${templateUrl}`)\n }\n const emitter = degit(templateUrl)\n await emitter.clone(projectDir)\n }\n\n const spinner = p.spinner()\n spinner.start('Checking latest Payload version...')\n\n await updatePackageJSON({ projectDir, projectName })\n spinner.message('Configuring Payload...')\n await configurePayloadConfig({ dbDetails, projectDirOrConfigPath: { projectDir } })\n\n // Remove yarn.lock file. This is only desired in Payload Cloud.\n const lockPath = path.resolve(projectDir, 'yarn.lock')\n if (fse.existsSync(lockPath)) {\n await fse.remove(lockPath)\n }\n\n if (!cliArgs['--no-deps']) {\n info(`Using ${packageManager}.\\n`)\n spinner.message('Installing dependencies...')\n const result = await installDeps({ cliArgs, packageManager, projectDir })\n if (result) {\n spinner.stop('Successfully installed Payload and dependencies')\n } else {\n spinner.stop('Error installing dependencies', 1)\n }\n } else {\n spinner.stop('Dependency installation skipped')\n }\n\n if (!cliArgs['--no-git']) {\n tryInitRepoAndCommit({ cwd: projectDir })\n }\n}\n\nexport async function updatePackageJSON(args: {\n projectDir: string\n projectName: string\n}): Promise<void> {\n const { projectDir, projectName } = args\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n try {\n const packageObj = await fse.readJson(packageJsonPath)\n packageObj.name = projectName\n await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })\n } catch (err: unknown) {\n warning(`Unable to update name in package.json. ${err instanceof Error ? err.message : ''}`)\n }\n}\n"],"names":["p","chalk","degit","execa","fse","fileURLToPath","path","tryInitRepoAndCommit","debug","error","info","warning","configurePayloadConfig","filename","url","dirname","createOrFindProjectDir","projectDir","pathExists","mkdir","installDeps","args","cliArgs","packageManager","installCmd","command","cwd","resolve","err","Error","message","createProject","dbDetails","projectName","template","green","localTemplate","copy","templateUrl","emitter","clone","spinner","start","updatePackageJSON","projectDirOrConfigPath","lockPath","existsSync","remove","result","stop","packageJsonPath","packageObj","readJson","name","writeJson","spaces"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,WAAW,QAAO;AACzB,OAAOC,WAAW,QAAO;AACzB,OAAOC,WAAW,QAAO;AACzB,OAAOC,SAAS,WAAU;AAC1B,SAASC,aAAa,QAAQ,WAAU;AACxC,OAAOC,UAAU,OAAM;AAIvB,SAASC,oBAAoB,QAAQ,kBAAiB;AACtD,SAASC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,OAAO,QAAQ,kBAAiB;AAC7D,SAASC,sBAAsB,QAAQ,gCAA+B;AAEtE,MAAMC,WAAWR,cAAc,YAAYS,GAAG;AAC9C,MAAMC,UAAUT,KAAKS,OAAO,CAACF;AAE7B,eAAeG,uBAAuBC,UAAkB;IACtD,MAAMC,aAAa,MAAMd,IAAIc,UAAU,CAACD;IACxC,IAAI,CAACC,YAAY;QACf,MAAMd,IAAIe,KAAK,CAACF;IAClB;AACF;AAEA,eAAeG,YAAYC,IAI1B;IACC,MAAM,EAAEC,OAAO,EAAEC,cAAc,EAAEN,UAAU,EAAE,GAAGI;IAChD,IAAIC,OAAO,CAAC,YAAY,EAAE;QACxB,OAAO;IACT;IACA,IAAIE,aAAa;IAEjB,IAAID,mBAAmB,QAAQ;QAC7BC,aAAa;IACf,OAAO,IAAID,mBAAmB,QAAQ;QACpCC,aAAa;IACf;IAEA,IAAI;QACF,MAAMrB,MAAMsB,OAAO,CAACD,YAAY;YAC9BE,KAAKpB,KAAKqB,OAAO,CAACV;QACpB;QACA,OAAO;IACT,EAAE,OAAOW,KAAc;QACrBnB,MAAM,CAAC,6BAA6B,EAAEmB,eAAeC,QAAQ,CAAC,EAAE,EAAED,IAAIE,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QACvF,OAAO;IACT;AACF;AAEA,OAAO,eAAeC,cAAcV,IAOnC;IACC,MAAM,EAAEC,OAAO,EAAEU,SAAS,EAAET,cAAc,EAAEN,UAAU,EAAEgB,WAAW,EAAEC,QAAQ,EAAE,GAAGb;IAElF,IAAIC,OAAO,CAAC,YAAY,EAAE;QACxBd,MAAM,CAAC,6BAA6B,EAAEP,MAAMkC,KAAK,CAAClB,YAAY,CAAC;QAC/D;IACF;IAEA,MAAMD,uBAAuBC;IAE7B,IAAIK,OAAO,CAAC,mBAAmB,EAAE;QAC/B,2DAA2D;QAC3D,MAAMc,gBAAgB9B,KAAKqB,OAAO,CAChCZ,SACA,0BACAO,OAAO,CAAC,mBAAmB;QAE7B,MAAMlB,IAAIiC,IAAI,CAACD,eAAenB;IAChC,OAAO,IAAI,SAASiB,UAAU;QAC5B,IAAII,cAAcJ,SAASpB,GAAG;QAC9B,IAAIQ,OAAO,CAAC,oBAAoB,EAAE;YAChCgB,cAAc,CAAC,EAAEJ,SAASpB,GAAG,CAAC,CAAC,EAAEQ,OAAO,CAAC,oBAAoB,CAAC,CAAC;YAC/Dd,MAAM,CAAC,oBAAoB,EAAE8B,YAAY,CAAC;QAC5C;QACA,MAAMC,UAAUrC,MAAMoC;QACtB,MAAMC,QAAQC,KAAK,CAACvB;IACtB;IAEA,MAAMwB,UAAUzC,EAAEyC,OAAO;IACzBA,QAAQC,KAAK,CAAC;IAEd,MAAMC,kBAAkB;QAAE1B;QAAYgB;IAAY;IAClDQ,QAAQX,OAAO,CAAC;IAChB,MAAMlB,uBAAuB;QAAEoB;QAAWY,wBAAwB;YAAE3B;QAAW;IAAE;IAEjF,gEAAgE;IAChE,MAAM4B,WAAWvC,KAAKqB,OAAO,CAACV,YAAY;IAC1C,IAAIb,IAAI0C,UAAU,CAACD,WAAW;QAC5B,MAAMzC,IAAI2C,MAAM,CAACF;IACnB;IAEA,IAAI,CAACvB,OAAO,CAAC,YAAY,EAAE;QACzBZ,KAAK,CAAC,MAAM,EAAEa,eAAe,GAAG,CAAC;QACjCkB,QAAQX,OAAO,CAAC;QAChB,MAAMkB,SAAS,MAAM5B,YAAY;YAAEE;YAASC;YAAgBN;QAAW;QACvE,IAAI+B,QAAQ;YACVP,QAAQQ,IAAI,CAAC;QACf,OAAO;YACLR,QAAQQ,IAAI,CAAC,iCAAiC;QAChD;IACF,OAAO;QACLR,QAAQQ,IAAI,CAAC;IACf;IAEA,IAAI,CAAC3B,OAAO,CAAC,WAAW,EAAE;QACxBf,qBAAqB;YAAEmB,KAAKT;QAAW;IACzC;AACF;AAEA,OAAO,eAAe0B,kBAAkBtB,IAGvC;IACC,MAAM,EAAEJ,UAAU,EAAEgB,WAAW,EAAE,GAAGZ;IACpC,MAAM6B,kBAAkB5C,KAAKqB,OAAO,CAACV,YAAY;IACjD,IAAI;QACF,MAAMkC,aAAa,MAAM/C,IAAIgD,QAAQ,CAACF;QACtCC,WAAWE,IAAI,GAAGpB;QAClB,MAAM7B,IAAIkD,SAAS,CAACJ,iBAAiBC,YAAY;YAAEI,QAAQ;QAAE;IAC/D,EAAE,OAAO3B,KAAc;QACrBjB,QAAQ,CAAC,uCAAuC,EAAEiB,eAAeC,QAAQD,IAAIE,OAAO,GAAG,GAAG,CAAC;IAC7F;AACF"}
1
+ {"version":3,"sources":["../../src/lib/create-project.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport chalk from 'chalk'\nimport execa from 'execa'\nimport fse from 'fs-extra'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nimport type { CliArgs, DbDetails, PackageManager, ProjectTemplate } from '../types.js'\n\nimport { tryInitRepoAndCommit } from '../utils/git.js'\nimport { debug, error, info, warning } from '../utils/log.js'\nimport { configurePayloadConfig } from './configure-payload-config.js'\nimport { downloadTemplate } from './download-template.js'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\nasync function createOrFindProjectDir(projectDir: string): Promise<void> {\n const pathExists = await fse.pathExists(projectDir)\n if (!pathExists) {\n await fse.mkdir(projectDir)\n }\n}\n\nasync function installDeps(args: {\n cliArgs: CliArgs\n packageManager: PackageManager\n projectDir: string\n}): Promise<boolean> {\n const { cliArgs, packageManager, projectDir } = args\n if (cliArgs['--no-deps']) {\n return true\n }\n let installCmd = 'npm install --legacy-peer-deps'\n\n if (packageManager === 'yarn') {\n installCmd = 'yarn'\n } else if (packageManager === 'pnpm') {\n installCmd = 'pnpm install'\n } else if (packageManager === 'bun') {\n installCmd = 'bun install'\n }\n\n try {\n await execa.command(installCmd, {\n cwd: path.resolve(projectDir),\n })\n return true\n } catch (err: unknown) {\n error(`Error installing dependencies${err instanceof Error ? `: ${err.message}` : ''}.`)\n return false\n }\n}\n\nexport async function createProject(args: {\n cliArgs: CliArgs\n dbDetails?: DbDetails\n packageManager: PackageManager\n projectDir: string\n projectName: string\n template: ProjectTemplate\n}): Promise<void> {\n const { cliArgs, dbDetails, packageManager, projectDir, projectName, template } = args\n\n if (cliArgs['--dry-run']) {\n debug(`Dry run: Creating project in ${chalk.green(projectDir)}`)\n return\n }\n\n await createOrFindProjectDir(projectDir)\n\n if (cliArgs['--local-template']) {\n // Copy template from local path. For development purposes.\n const localTemplate = path.resolve(\n dirname,\n '../../../../templates/',\n cliArgs['--local-template'],\n )\n await fse.copy(localTemplate, projectDir)\n } else if ('url' in template) {\n let templateUrl = template.url\n if (cliArgs['--template-branch']) {\n templateUrl = `${template.url}#${cliArgs['--template-branch']}`\n debug(`Using template url: ${templateUrl}`)\n }\n await downloadTemplate({\n name: template.name,\n branch: 'beta',\n projectDir,\n })\n }\n\n const spinner = p.spinner()\n spinner.start('Checking latest Payload version...')\n\n await updatePackageJSON({ projectDir, projectName })\n spinner.message('Configuring Payload...')\n await configurePayloadConfig({\n dbType: dbDetails?.type,\n projectDirOrConfigPath: { projectDir },\n })\n\n // Remove yarn.lock file. This is only desired in Payload Cloud.\n const lockPath = path.resolve(projectDir, 'pnpm-lock.yaml')\n if (fse.existsSync(lockPath)) {\n await fse.remove(lockPath)\n }\n\n if (!cliArgs['--no-deps']) {\n info(`Using ${packageManager}.\\n`)\n spinner.message('Installing dependencies...')\n const result = await installDeps({ cliArgs, packageManager, projectDir })\n if (result) {\n spinner.stop('Successfully installed Payload and dependencies')\n } else {\n spinner.stop('Error installing dependencies', 1)\n }\n } else {\n spinner.stop('Dependency installation skipped')\n }\n\n if (!cliArgs['--no-git']) {\n tryInitRepoAndCommit({ cwd: projectDir })\n }\n}\n\nexport async function updatePackageJSON(args: {\n projectDir: string\n projectName: string\n}): Promise<void> {\n const { projectDir, projectName } = args\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n try {\n const packageObj = await fse.readJson(packageJsonPath)\n packageObj.name = projectName\n await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })\n } catch (err: unknown) {\n warning(`Unable to update name in package.json. ${err instanceof Error ? err.message : ''}`)\n }\n}\n"],"names":["p","chalk","execa","fse","fileURLToPath","path","tryInitRepoAndCommit","debug","error","info","warning","configurePayloadConfig","downloadTemplate","filename","url","dirname","createOrFindProjectDir","projectDir","pathExists","mkdir","installDeps","args","cliArgs","packageManager","installCmd","command","cwd","resolve","err","Error","message","createProject","dbDetails","projectName","template","green","localTemplate","copy","templateUrl","name","branch","spinner","start","updatePackageJSON","dbType","type","projectDirOrConfigPath","lockPath","existsSync","remove","result","stop","packageJsonPath","packageObj","readJson","writeJson","spaces"],"mappings":"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"}
@@ -1,17 +1,20 @@
1
+ import { jest } from '@jest/globals';
2
+ import fs from 'fs';
1
3
  import fse from 'fs-extra';
4
+ import globby from 'globby';
5
+ import * as os from 'node:os';
2
6
  import path from 'path';
3
7
  import { createProject } from './create-project.js';
4
- import { dbReplacements } from './packages.js';
8
+ import { dbReplacements } from './replacements.js';
5
9
  import { getValidTemplates } from './templates.js';
6
- import globby from 'globby';
7
- import { jest } from '@jest/globals';
8
- import tempDirectory from 'temp-dir';
9
10
  describe('createProject', ()=>{
10
11
  let projectDir;
11
12
  beforeAll(()=>{
13
+ // eslint-disable-next-line no-console
12
14
  console.log = jest.fn();
13
15
  });
14
16
  beforeEach(()=>{
17
+ const tempDirectory = fs.realpathSync(os.tmpdir());
15
18
  projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`;
16
19
  });
17
20
  afterEach(()=>{
@@ -22,13 +25,12 @@ describe('createProject', ()=>{
22
25
  }
23
26
  });
24
27
  describe('#createProject', ()=>{
25
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
26
28
  const args = {
27
29
  _: [
28
30
  'project-name'
29
31
  ],
30
32
  '--db': 'mongodb',
31
- '--local-template': 'blank-3.0',
33
+ '--local-template': 'blank',
32
34
  '--no-deps': true
33
35
  };
34
36
  const packageManager = 'yarn';
@@ -37,30 +39,30 @@ describe('createProject', ()=>{
37
39
  const template = {
38
40
  name: 'plugin',
39
41
  type: 'plugin',
40
- url: 'https://github.com/payloadcms/payload-plugin-template',
41
- description: 'Template for creating a Payload plugin'
42
+ description: 'Template for creating a Payload plugin',
43
+ url: 'https://github.com/payloadcms/payload-plugin-template'
42
44
  };
43
45
  await createProject({
44
46
  cliArgs: args,
45
- projectName,
47
+ packageManager,
46
48
  projectDir,
47
- template,
48
- packageManager
49
+ projectName,
50
+ template
49
51
  });
50
52
  const packageJsonPath = path.resolve(projectDir, 'package.json');
51
53
  const packageJson = fse.readJsonSync(packageJsonPath);
52
54
  // Check package name and description
53
- expect(packageJson.name).toEqual(projectName);
55
+ expect(packageJson.name).toStrictEqual(projectName);
54
56
  });
55
57
  describe('creates project from template', ()=>{
56
58
  const templates = getValidTemplates();
57
59
  it.each([
58
60
  [
59
- 'blank-3.0',
61
+ 'blank',
60
62
  'mongodb'
61
63
  ],
62
64
  [
63
- 'blank-3.0',
65
+ 'blank',
64
66
  'postgres'
65
67
  ]
66
68
  ])('update config and deps: %s, %s', async (templateName, db)=>{
@@ -73,14 +75,14 @@ describe('createProject', ()=>{
73
75
  };
74
76
  await createProject({
75
77
  cliArgs,
76
- projectName,
77
- projectDir,
78
- template: template,
79
- packageManager,
80
78
  dbDetails: {
81
- dbUri: `${db}://localhost:27017/create-project-test`,
82
- type: db
83
- }
79
+ type: db,
80
+ dbUri: `${db}://localhost:27017/create-project-test`
81
+ },
82
+ packageManager,
83
+ projectDir,
84
+ projectName,
85
+ template: template
84
86
  });
85
87
  const dbReplacement = dbReplacements[db];
86
88
  const packageJsonPath = path.resolve(projectDir, 'package.json');
@@ -93,16 +95,13 @@ describe('createProject', ()=>{
93
95
  absolute: true,
94
96
  cwd: projectDir
95
97
  }))?.[0];
96
- if (!payloadConfigPath) {
97
- throw new Error(`Could not find payload.config.ts inside ${projectDir}`);
98
- }
99
98
  const content = fse.readFileSync(payloadConfigPath, 'utf-8');
100
99
  // Check payload.config.ts
101
100
  expect(content).not.toContain('// database-adapter-import');
102
101
  expect(content).toContain(dbReplacement.importReplacement);
103
102
  expect(content).not.toContain('// database-adapter-config-start');
104
103
  expect(content).not.toContain('// database-adapter-config-end');
105
- expect(content).toContain(dbReplacement.configReplacement.join('\n'));
104
+ expect(content).toContain(dbReplacement.configReplacement().join('\n'));
106
105
  });
107
106
  });
108
107
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/create-project.spec.ts"],"sourcesContent":["import fse from 'fs-extra'\nimport path from 'path'\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\nimport { createProject } from './create-project.js'\nimport { dbReplacements } from './packages.js'\nimport { getValidTemplates } from './templates.js'\nimport globby from 'globby'\nimport { jest } from '@jest/globals'\n\nimport tempDirectory from 'temp-dir'\n\ndescribe('createProject', () => {\n let projectDir: string\n beforeAll(() => {\n console.log = jest.fn()\n })\n\n beforeEach(() => {\n projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`\n })\n\n afterEach(() => {\n if (fse.existsSync(projectDir)) {\n fse.rmSync(projectDir, { recursive: true })\n }\n })\n\n describe('#createProject', () => {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const args = {\n _: ['project-name'],\n '--db': 'mongodb',\n '--local-template': 'blank-3.0',\n '--no-deps': true,\n } as CliArgs\n const packageManager = 'yarn'\n\n it('creates plugin template', async () => {\n const projectName = 'plugin'\n const template: ProjectTemplate = {\n name: 'plugin',\n type: 'plugin',\n url: 'https://github.com/payloadcms/payload-plugin-template',\n description: 'Template for creating a Payload plugin',\n }\n await createProject({\n cliArgs: args,\n projectName,\n projectDir,\n template,\n packageManager,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toEqual(projectName)\n })\n\n describe('creates project from template', () => {\n const templates = getValidTemplates()\n\n it.each([\n ['blank-3.0', 'mongodb'],\n ['blank-3.0', 'postgres'],\n\n // TODO: Re-enable these once 3.0 is stable and templates updated\n // ['website', 'mongodb'],\n // ['website', 'postgres'],\n // ['ecommerce', 'mongodb'],\n // ['ecommerce', 'postgres'],\n ])('update config and deps: %s, %s', async (templateName, db) => {\n const projectName = 'starter-project'\n\n const template = templates.find((t) => t.name === templateName)\n\n const cliArgs = {\n ...args,\n '--db': db,\n '--local-template': templateName,\n } as CliArgs\n\n await createProject({\n cliArgs,\n projectName,\n projectDir,\n template: template as ProjectTemplate,\n packageManager,\n dbDetails: {\n dbUri: `${db}://localhost:27017/create-project-test`,\n type: db as DbType,\n },\n })\n\n const dbReplacement = dbReplacements[db as DbType]\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Verify git was initialized\n expect(fse.existsSync(path.resolve(projectDir, '.git'))).toBe(true)\n\n // Should only have one db adapter\n expect(\n Object.keys(packageJson.dependencies).filter((n) => n.startsWith('@payloadcms/db-')),\n ).toHaveLength(1)\n\n const payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: projectDir,\n })\n )?.[0]\n\n if (!payloadConfigPath) {\n throw new Error(`Could not find payload.config.ts inside ${projectDir}`)\n }\n\n const content = fse.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check payload.config.ts\n expect(content).not.toContain('// database-adapter-import')\n expect(content).toContain(dbReplacement.importReplacement)\n\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n expect(content).toContain(dbReplacement.configReplacement.join('\\n'))\n })\n })\n })\n})\n"],"names":["fse","path","createProject","dbReplacements","getValidTemplates","globby","jest","tempDirectory","describe","projectDir","beforeAll","console","log","fn","beforeEach","Math","random","toString","substring","afterEach","existsSync","rmSync","recursive","args","_","packageManager","it","projectName","template","name","type","url","description","cliArgs","packageJsonPath","resolve","packageJson","readJsonSync","expect","toEqual","templates","each","templateName","db","find","t","dbDetails","dbUri","dbReplacement","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","Error","content","readFileSync","not","toContain","importReplacement","configReplacement","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/create-project.spec.ts"],"sourcesContent":["import { jest } from '@jest/globals'\nimport fs from 'fs'\nimport fse from 'fs-extra'\nimport globby from 'globby'\nimport * as os from 'node:os'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\n\nimport { createProject } from './create-project.js'\nimport { dbReplacements } from './replacements.js'\nimport { getValidTemplates } from './templates.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n beforeAll(() => {\n // eslint-disable-next-line no-console\n console.log = jest.fn()\n })\n\n beforeEach(() => {\n const tempDirectory = fs.realpathSync(os.tmpdir())\n projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`\n })\n\n afterEach(() => {\n if (fse.existsSync(projectDir)) {\n fse.rmSync(projectDir, { recursive: true })\n }\n })\n\n describe('#createProject', () => {\n const args = {\n _: ['project-name'],\n '--db': 'mongodb',\n '--local-template': 'blank',\n '--no-deps': true,\n } as CliArgs\n const packageManager = 'yarn'\n\n it('creates plugin template', async () => {\n const projectName = 'plugin'\n const template: ProjectTemplate = {\n name: 'plugin',\n type: 'plugin',\n description: 'Template for creating a Payload plugin',\n url: 'https://github.com/payloadcms/payload-plugin-template',\n }\n await createProject({\n cliArgs: args,\n packageManager,\n projectDir,\n projectName,\n template,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toStrictEqual(projectName)\n })\n\n describe('creates project from template', () => {\n const templates = getValidTemplates()\n\n it.each([\n ['blank', 'mongodb'],\n ['blank', 'postgres'],\n\n // TODO: Re-enable these once 3.0 is stable and templates updated\n // ['website', 'mongodb'],\n // ['website', 'postgres'],\n // ['ecommerce', 'mongodb'],\n // ['ecommerce', 'postgres'],\n ])('update config and deps: %s, %s', async (templateName, db) => {\n const projectName = 'starter-project'\n\n const template = templates.find((t) => t.name === templateName)\n\n const cliArgs = {\n ...args,\n '--db': db,\n '--local-template': templateName,\n } as CliArgs\n\n await createProject({\n cliArgs,\n dbDetails: {\n type: db as DbType,\n dbUri: `${db}://localhost:27017/create-project-test`,\n },\n packageManager,\n projectDir,\n projectName,\n template: template as ProjectTemplate,\n })\n\n const dbReplacement = dbReplacements[db as DbType]\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Verify git was initialized\n expect(fse.existsSync(path.resolve(projectDir, '.git'))).toBe(true)\n\n // Should only have one db adapter\n expect(\n Object.keys(packageJson.dependencies).filter((n) => n.startsWith('@payloadcms/db-')),\n ).toHaveLength(1)\n\n const payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: projectDir,\n })\n )?.[0]\n\n const content = fse.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check payload.config.ts\n expect(content).not.toContain('// database-adapter-import')\n expect(content).toContain(dbReplacement.importReplacement)\n\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n expect(content).toContain(dbReplacement.configReplacement().join('\\n'))\n })\n })\n })\n})\n"],"names":["jest","fs","fse","globby","os","path","createProject","dbReplacements","getValidTemplates","describe","projectDir","beforeAll","console","log","fn","beforeEach","tempDirectory","realpathSync","tmpdir","Math","random","toString","substring","afterEach","existsSync","rmSync","recursive","args","_","packageManager","it","projectName","template","name","type","description","url","cliArgs","packageJsonPath","resolve","packageJson","readJsonSync","expect","toStrictEqual","templates","each","templateName","db","find","t","dbDetails","dbUri","dbReplacement","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","content","readFileSync","not","toContain","importReplacement","configReplacement","join"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare function downloadTemplate({ name, branch, projectDir, }: {
2
+ branch: string;
3
+ /**
4
+ * The name of the template to download
5
+ * Must be dir /templates/<name>
6
+ */
7
+ name: string;
8
+ projectDir: string;
9
+ }): Promise<void>;
10
+ //# sourceMappingURL=download-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-template.d.ts","sourceRoot":"","sources":["../../src/lib/download-template.ts"],"names":[],"mappings":"AAIA,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,MAAM,EACN,UAAU,GACX,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB,iBAWA"}
@@ -0,0 +1,21 @@
1
+ import { Readable } from 'node:stream';
2
+ import { pipeline } from 'node:stream/promises';
3
+ import { x } from 'tar';
4
+ export async function downloadTemplate({ name, branch, projectDir }) {
5
+ const url = `https://codeload.github.com/payloadcms/payload/tar.gz/${branch}`;
6
+ const filter = `payload-${branch}/templates/${name}/`;
7
+ await pipeline(await downloadTarStream(url), x({
8
+ cwd: projectDir,
9
+ filter: (p)=>p.includes(filter),
10
+ strip: 2 + name.split('/').length
11
+ }));
12
+ }
13
+ async function downloadTarStream(url) {
14
+ const res = await fetch(url);
15
+ if (!res.body) {
16
+ throw new Error(`Failed to download: ${url}`);
17
+ }
18
+ return Readable.from(res.body);
19
+ }
20
+
21
+ //# sourceMappingURL=download-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/download-template.ts"],"sourcesContent":["import { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport { x } from 'tar'\n\nexport async function downloadTemplate({\n name,\n branch,\n projectDir,\n}: {\n branch: string\n /**\n * The name of the template to download\n * Must be dir /templates/<name>\n */\n name: string\n projectDir: string\n}) {\n const url = `https://codeload.github.com/payloadcms/payload/tar.gz/${branch}`\n const filter = `payload-${branch}/templates/${name}/`\n await pipeline(\n await downloadTarStream(url),\n x({\n cwd: projectDir,\n filter: (p) => p.includes(filter),\n strip: 2 + name.split('/').length,\n }),\n )\n}\n\nasync function downloadTarStream(url: string) {\n const res = await fetch(url)\n\n if (!res.body) {\n throw new Error(`Failed to download: ${url}`)\n }\n\n return Readable.from(res.body as unknown as NodeJS.ReadableStream)\n}\n"],"names":["Readable","pipeline","x","downloadTemplate","name","branch","projectDir","url","filter","downloadTarStream","cwd","p","includes","strip","split","length","res","fetch","body","Error","from"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,cAAa;AACtC,SAASC,QAAQ,QAAQ,uBAAsB;AAC/C,SAASC,CAAC,QAAQ,MAAK;AAEvB,OAAO,eAAeC,iBAAiB,EACrCC,IAAI,EACJC,MAAM,EACNC,UAAU,EASX;IACC,MAAMC,MAAM,CAAC,sDAAsD,EAAEF,OAAO,CAAC;IAC7E,MAAMG,SAAS,CAAC,QAAQ,EAAEH,OAAO,WAAW,EAAED,KAAK,CAAC,CAAC;IACrD,MAAMH,SACJ,MAAMQ,kBAAkBF,MACxBL,EAAE;QACAQ,KAAKJ;QACLE,QAAQ,CAACG,IAAMA,EAAEC,QAAQ,CAACJ;QAC1BK,OAAO,IAAIT,KAAKU,KAAK,CAAC,KAAKC,MAAM;IACnC;AAEJ;AAEA,eAAeN,kBAAkBF,GAAW;IAC1C,MAAMS,MAAM,MAAMC,MAAMV;IAExB,IAAI,CAACS,IAAIE,IAAI,EAAE;QACb,MAAM,IAAIC,MAAM,CAAC,oBAAoB,EAAEZ,IAAI,CAAC;IAC9C;IAEA,OAAOP,SAASoB,IAAI,CAACJ,IAAIE,IAAI;AAC/B"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/generate-secret.ts"],"sourcesContent":["import { randomBytes } from 'crypto'\n\nexport function generateSecret(): string {\n return randomBytes(32).toString('hex').slice(0, 24)\n}\n"],"names":["randomBytes","generateSecret","toString","slice"],"rangeMappings":";;;","mappings":"AAAA,SAASA,WAAW,QAAQ,SAAQ;AAEpC,OAAO,SAASC;IACd,OAAOD,YAAY,IAAIE,QAAQ,CAAC,OAAOC,KAAK,CAAC,GAAG;AAClD"}
1
+ {"version":3,"sources":["../../src/lib/generate-secret.ts"],"sourcesContent":["import { randomBytes } from 'crypto'\n\nexport function generateSecret(): string {\n return randomBytes(32).toString('hex').slice(0, 24)\n}\n"],"names":["randomBytes","generateSecret","toString","slice"],"mappings":"AAAA,SAASA,WAAW,QAAQ,SAAQ;AAEpC,OAAO,SAASC;IACd,OAAOD,YAAY,IAAIE,QAAQ,CAAC,OAAOC,KAAK,CAAC,GAAG;AAClD"}
@@ -3,23 +3,44 @@ import fse from 'fs-extra';
3
3
  export async function getPackageManager(args) {
4
4
  const { cliArgs, projectDir } = args;
5
5
  try {
6
- // Check for yarn.lock, package-lock.json, or pnpm-lock.yaml
6
+ // Check for flag or lockfile
7
7
  let detected = 'npm';
8
- if (cliArgs?.['--use-pnpm'] || fse.existsSync(`${projectDir}/pnpm-lock.yaml`) || await commandExists('pnpm')) {
8
+ if (cliArgs?.['--use-pnpm'] || fse.existsSync(`${projectDir}/pnpm-lock.yaml`)) {
9
9
  detected = 'pnpm';
10
- } else if (cliArgs?.['--use-yarn'] || fse.existsSync(`${projectDir}/yarn.lock`) || await commandExists('yarn')) {
10
+ } else if (cliArgs?.['--use-yarn'] || fse.existsSync(`${projectDir}/yarn.lock`)) {
11
11
  detected = 'yarn';
12
12
  } else if (cliArgs?.['--use-npm'] || fse.existsSync(`${projectDir}/package-lock.json`)) {
13
13
  detected = 'npm';
14
+ } else if (cliArgs?.['--use-bun'] || fse.existsSync(`${projectDir}/bun.lockb`)) {
15
+ detected = 'bun';
16
+ } else if (await commandExists('pnpm')) {
17
+ // Prefer pnpm if it's installed
18
+ detected = 'pnpm';
19
+ } else {
20
+ // Otherwise check the execution environment
21
+ detected = getEnvironmentPackageManager();
14
22
  }
15
23
  return detected;
16
- } catch (error) {
24
+ } catch (ignore) {
17
25
  return 'npm';
18
26
  }
19
27
  }
28
+ function getEnvironmentPackageManager() {
29
+ const userAgent = process.env.npm_config_user_agent || '';
30
+ if (userAgent.startsWith('yarn')) {
31
+ return 'yarn';
32
+ }
33
+ if (userAgent.startsWith('pnpm')) {
34
+ return 'pnpm';
35
+ }
36
+ if (userAgent.startsWith('bun')) {
37
+ return 'bun';
38
+ }
39
+ return 'npm';
40
+ }
20
41
  async function commandExists(command) {
21
42
  try {
22
- await execa.command(`command -v ${command}`);
43
+ await execa.command(process.platform === 'win32' ? `where ${command}` : `command -v ${command}`);
23
44
  return true;
24
45
  } catch {
25
46
  return false;