create-payload-app 3.69.0-internal.2883df2 → 3.69.0
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.
- package/dist/ast-integration.spec.js +1 -0
- package/dist/ast-integration.spec.js.map +1 -1
- package/dist/lib/ast/adapter-config.js +1 -1
- package/dist/lib/ast/adapter-config.js.map +1 -1
- package/dist/lib/ast/package-json.spec.js +1 -0
- package/dist/lib/ast/package-json.spec.js.map +1 -1
- package/dist/lib/ast/payload-config.js +1 -1
- package/dist/lib/ast/payload-config.js.map +1 -1
- package/dist/lib/ast/payload-config.spec.js +5 -4
- package/dist/lib/ast/payload-config.spec.js.map +1 -1
- package/dist/lib/ast/utils.spec.js +1 -0
- package/dist/lib/ast/utils.spec.js.map +1 -1
- package/dist/lib/configure-payload-config.js +1 -1
- package/dist/lib/configure-payload-config.js.map +1 -1
- package/dist/lib/create-project.spec.js +3 -3
- package/dist/lib/create-project.spec.js.map +1 -1
- package/dist/lib/manage-env-files.js +4 -4
- package/dist/lib/manage-env-files.js.map +1 -1
- package/dist/lib/manage-env-files.spec.js +10 -10
- package/dist/lib/manage-env-files.spec.js.map +1 -1
- package/dist/lib/wrap-next-config.spec.js +2 -2
- package/dist/lib/wrap-next-config.spec.js.map +1 -1
- package/dist/template/src/payload-types.ts +1 -0
- package/dist/template/src/payload.config.ts +1 -1
- package/package.json +1 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ast-integration.spec.ts"],"sourcesContent":["import * as fs from 'fs'\nimport * as fse from 'fs-extra'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { configurePayloadConfig } from './lib/configure-payload-config'\nimport type { DbType, StorageAdapterType } from './types'\nimport { DB_ADAPTER_CONFIG, STORAGE_ADAPTER_CONFIG } from './lib/ast/adapter-config'\n\ninterface TestCase {\n name: string\n template: string\n dbType: DbType\n storageAdapter: StorageAdapterType\n}\n\nconst TEST_CASES: TestCase[] = [\n {\n name: 'blank + mongodb + localDisk',\n template: 'blank',\n dbType: 'mongodb',\n storageAdapter: 'localDisk',\n },\n {\n name: 'blank + postgres + vercelBlobStorage',\n template: 'blank',\n dbType: 'postgres',\n storageAdapter: 'vercelBlobStorage',\n },\n {\n name: 'website + mongodb + s3Storage',\n template: 'website',\n dbType: 'mongodb',\n storageAdapter: 's3Storage',\n },\n {\n name: 'website + postgres + localDisk',\n template: 'website',\n dbType: 'postgres',\n storageAdapter: 'localDisk',\n },\n {\n name: 'ecommerce + mongodb + localDisk',\n template: 'ecommerce',\n dbType: 'mongodb',\n storageAdapter: 'localDisk',\n },\n {\n name: 'ecommerce + postgres + r2Storage',\n template: 'ecommerce',\n dbType: 'postgres',\n storageAdapter: 'r2Storage',\n },\n]\n\ndescribe('AST Integration Tests', () => {\n let tempDir: string\n const templatesRoot = path.resolve(__dirname, '../../..', 'templates')\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-ast-integration-'))\n })\n\n afterEach(() => {\n if (tempDir && fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n }\n })\n\n describe.each(TEST_CASES)('$name', ({ template, dbType, storageAdapter }) => {\n it('successfully applies AST transformations', async () => {\n // Setup: Copy template to temp directory\n const templateDir = path.join(templatesRoot, template)\n const testProjectDir = path.join(tempDir, template)\n\n if (!fs.existsSync(templateDir)) {\n throw new Error(`Template ${template} not found at ${templateDir}`)\n }\n\n fse.copySync(templateDir, testProjectDir)\n\n const payloadConfigPath = path.join(testProjectDir, 'src', 'payload.config.ts')\n const packageJsonPath = path.join(testProjectDir, 'package.json')\n\n // Verify files exist before transformation\n expect(fs.existsSync(payloadConfigPath)).toBe(true)\n expect(fs.existsSync(packageJsonPath)).toBe(true)\n\n // Apply transformations\n await configurePayloadConfig({\n dbType,\n storageAdapter,\n projectDirOrConfigPath: { projectDir: testProjectDir },\n })\n\n // Verify payload.config.ts transformations\n const configContent = fs.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check database adapter import\n const dbConfig = DB_ADAPTER_CONFIG[dbType]\n expect(configContent).toContain(`from '${dbConfig.packageName}'`)\n expect(configContent).toContain(`import { ${dbConfig.adapterName} }`)\n\n // Check database adapter config\n expect(configContent).toMatch(new RegExp(`db:\\\\s*${dbConfig.adapterName}\\\\(`))\n\n // Check storage adapter if not localDisk\n if (storageAdapter !== 'localDisk') {\n const storageConfig = STORAGE_ADAPTER_CONFIG[storageAdapter]\n\n if (storageConfig.packageName && storageConfig.adapterName) {\n expect(configContent).toContain(`from '${storageConfig.packageName}'`)\n expect(configContent).toContain(`import { ${storageConfig.adapterName} }`)\n expect(configContent).toContain(`${storageConfig.adapterName}(`)\n }\n }\n\n // Check that old mongodb adapter is removed if we switched to postgres\n if (dbType === 'postgres') {\n expect(configContent).not.toContain('@payloadcms/db-mongodb')\n expect(configContent).not.toContain('mongooseAdapter')\n }\n\n // Check that plugins array exists if storage adapter was added\n if (storageAdapter !== 'localDisk') {\n expect(configContent).toContain('plugins:')\n }\n\n // Verify package.json transformations\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n // Check that correct db adapter package is in dependencies\n expect(packageJson.dependencies[dbConfig.packageName]).toBeDefined()\n\n // Check that old db adapters are removed\n Object.entries(DB_ADAPTER_CONFIG).forEach(([key, config]) => {\n if (key !== dbType && config.packageName !== dbConfig.packageName) {\n expect(packageJson.dependencies[config.packageName]).toBeUndefined()\n }\n })\n\n // Note: Storage adapter dependencies are NOT automatically added to package.json\n // by configurePayloadConfig - only the payload.config.ts is updated.\n // This is expected behavior as storage adapters are typically installed separately.\n\n // Verify file is valid TypeScript (basic syntax check)\n expect(configContent).toContain('buildConfig')\n expect(configContent).toContain('export default')\n\n // Verify no placeholder comments remain\n expect(configContent).not.toContain('database-adapter-import')\n expect(configContent).not.toContain('database-adapter-config-start')\n expect(configContent).not.toContain('storage-adapter-placeholder')\n })\n })\n})\n"],"names":["fs","fse","path","os","configurePayloadConfig","DB_ADAPTER_CONFIG","STORAGE_ADAPTER_CONFIG","TEST_CASES","name","template","dbType","storageAdapter","
|
|
1
|
+
{"version":3,"sources":["../src/ast-integration.spec.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, afterEach } from 'vitest'\nimport * as fs from 'fs'\nimport * as fse from 'fs-extra'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { configurePayloadConfig } from './lib/configure-payload-config'\nimport type { DbType, StorageAdapterType } from './types'\nimport { DB_ADAPTER_CONFIG, STORAGE_ADAPTER_CONFIG } from './lib/ast/adapter-config'\n\ninterface TestCase {\n name: string\n template: string\n dbType: DbType\n storageAdapter: StorageAdapterType\n}\n\nconst TEST_CASES: TestCase[] = [\n {\n name: 'blank + mongodb + localDisk',\n template: 'blank',\n dbType: 'mongodb',\n storageAdapter: 'localDisk',\n },\n {\n name: 'blank + postgres + vercelBlobStorage',\n template: 'blank',\n dbType: 'postgres',\n storageAdapter: 'vercelBlobStorage',\n },\n {\n name: 'website + mongodb + s3Storage',\n template: 'website',\n dbType: 'mongodb',\n storageAdapter: 's3Storage',\n },\n {\n name: 'website + postgres + localDisk',\n template: 'website',\n dbType: 'postgres',\n storageAdapter: 'localDisk',\n },\n {\n name: 'ecommerce + mongodb + localDisk',\n template: 'ecommerce',\n dbType: 'mongodb',\n storageAdapter: 'localDisk',\n },\n {\n name: 'ecommerce + postgres + r2Storage',\n template: 'ecommerce',\n dbType: 'postgres',\n storageAdapter: 'r2Storage',\n },\n]\n\ndescribe('AST Integration Tests', () => {\n let tempDir: string\n const templatesRoot = path.resolve(__dirname, '../../..', 'templates')\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-ast-integration-'))\n })\n\n afterEach(() => {\n if (tempDir && fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true })\n }\n })\n\n describe.each(TEST_CASES)('$name', ({ template, dbType, storageAdapter }) => {\n it('successfully applies AST transformations', async () => {\n // Setup: Copy template to temp directory\n const templateDir = path.join(templatesRoot, template)\n const testProjectDir = path.join(tempDir, template)\n\n if (!fs.existsSync(templateDir)) {\n throw new Error(`Template ${template} not found at ${templateDir}`)\n }\n\n fse.copySync(templateDir, testProjectDir)\n\n const payloadConfigPath = path.join(testProjectDir, 'src', 'payload.config.ts')\n const packageJsonPath = path.join(testProjectDir, 'package.json')\n\n // Verify files exist before transformation\n expect(fs.existsSync(payloadConfigPath)).toBe(true)\n expect(fs.existsSync(packageJsonPath)).toBe(true)\n\n // Apply transformations\n await configurePayloadConfig({\n dbType,\n storageAdapter,\n projectDirOrConfigPath: { projectDir: testProjectDir },\n })\n\n // Verify payload.config.ts transformations\n const configContent = fs.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check database adapter import\n const dbConfig = DB_ADAPTER_CONFIG[dbType]\n expect(configContent).toContain(`from '${dbConfig.packageName}'`)\n expect(configContent).toContain(`import { ${dbConfig.adapterName} }`)\n\n // Check database adapter config\n expect(configContent).toMatch(new RegExp(`db:\\\\s*${dbConfig.adapterName}\\\\(`))\n\n // Check storage adapter if not localDisk\n if (storageAdapter !== 'localDisk') {\n const storageConfig = STORAGE_ADAPTER_CONFIG[storageAdapter]\n\n if (storageConfig.packageName && storageConfig.adapterName) {\n expect(configContent).toContain(`from '${storageConfig.packageName}'`)\n expect(configContent).toContain(`import { ${storageConfig.adapterName} }`)\n expect(configContent).toContain(`${storageConfig.adapterName}(`)\n }\n }\n\n // Check that old mongodb adapter is removed if we switched to postgres\n if (dbType === 'postgres') {\n expect(configContent).not.toContain('@payloadcms/db-mongodb')\n expect(configContent).not.toContain('mongooseAdapter')\n }\n\n // Check that plugins array exists if storage adapter was added\n if (storageAdapter !== 'localDisk') {\n expect(configContent).toContain('plugins:')\n }\n\n // Verify package.json transformations\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n // Check that correct db adapter package is in dependencies\n expect(packageJson.dependencies[dbConfig.packageName]).toBeDefined()\n\n // Check that old db adapters are removed\n Object.entries(DB_ADAPTER_CONFIG).forEach(([key, config]) => {\n if (key !== dbType && config.packageName !== dbConfig.packageName) {\n expect(packageJson.dependencies[config.packageName]).toBeUndefined()\n }\n })\n\n // Note: Storage adapter dependencies are NOT automatically added to package.json\n // by configurePayloadConfig - only the payload.config.ts is updated.\n // This is expected behavior as storage adapters are typically installed separately.\n\n // Verify file is valid TypeScript (basic syntax check)\n expect(configContent).toContain('buildConfig')\n expect(configContent).toContain('export default')\n\n // Verify no placeholder comments remain\n expect(configContent).not.toContain('database-adapter-import')\n expect(configContent).not.toContain('database-adapter-config-start')\n expect(configContent).not.toContain('storage-adapter-placeholder')\n })\n })\n})\n"],"names":["describe","it","expect","beforeEach","afterEach","fs","fse","path","os","configurePayloadConfig","DB_ADAPTER_CONFIG","STORAGE_ADAPTER_CONFIG","TEST_CASES","name","template","dbType","storageAdapter","tempDir","templatesRoot","resolve","__dirname","mkdtempSync","join","tmpdir","existsSync","rmSync","recursive","force","each","templateDir","testProjectDir","Error","copySync","payloadConfigPath","packageJsonPath","toBe","projectDirOrConfigPath","projectDir","configContent","readFileSync","dbConfig","toContain","packageName","adapterName","toMatch","RegExp","storageConfig","not","packageJson","JSON","parse","dependencies","toBeDefined","Object","entries","forEach","key","config","toBeUndefined"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/ast/adapter-config.ts"],"sourcesContent":["/**\n * Centralized adapter configuration\n * Shared across all AST transformation and test files\n */\n\nimport type { DatabaseAdapter, StorageAdapter } from './types.js'\n\nexport type DatabaseAdapterConfig = {\n adapterName: string\n configTemplate: (envVar: string) => string\n packageName: string\n}\n\nexport type StorageAdapterConfig = {\n adapterName: null | string\n configTemplate: () => null | string\n packageName: null | string\n}\n\n/**\n * Database adapter configurations\n */\nexport const DB_ADAPTER_CONFIG: Record<DatabaseAdapter, DatabaseAdapterConfig> = {\n 'd1-sqlite': {\n adapterName: 'sqliteD1Adapter',\n configTemplate: () => `sqliteD1Adapter({\n binding: cloudflare.env.D1,\n})`,\n packageName: '@payloadcms/db-d1-sqlite',\n },\n mongodb: {\n adapterName: 'mongooseAdapter',\n configTemplate: (envVar: string) => `mongooseAdapter({\n url: process.env.${envVar} || '',\n})`,\n packageName: '@payloadcms/db-mongodb',\n },\n postgres: {\n adapterName: 'postgresAdapter',\n configTemplate: (envVar: string) => `postgresAdapter({\n pool: {\n connectionString: process.env.${envVar} || '',\n },\n})`,\n packageName: '@payloadcms/db-postgres',\n },\n sqlite: {\n adapterName: 'sqliteAdapter',\n configTemplate: () => `sqliteAdapter({\n client: {\n url: process.env.
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/ast/adapter-config.ts"],"sourcesContent":["/**\n * Centralized adapter configuration\n * Shared across all AST transformation and test files\n */\n\nimport type { DatabaseAdapter, StorageAdapter } from './types.js'\n\nexport type DatabaseAdapterConfig = {\n adapterName: string\n configTemplate: (envVar: string) => string\n packageName: string\n}\n\nexport type StorageAdapterConfig = {\n adapterName: null | string\n configTemplate: () => null | string\n packageName: null | string\n}\n\n/**\n * Database adapter configurations\n */\nexport const DB_ADAPTER_CONFIG: Record<DatabaseAdapter, DatabaseAdapterConfig> = {\n 'd1-sqlite': {\n adapterName: 'sqliteD1Adapter',\n configTemplate: () => `sqliteD1Adapter({\n binding: cloudflare.env.D1,\n})`,\n packageName: '@payloadcms/db-d1-sqlite',\n },\n mongodb: {\n adapterName: 'mongooseAdapter',\n configTemplate: (envVar: string) => `mongooseAdapter({\n url: process.env.${envVar} || '',\n})`,\n packageName: '@payloadcms/db-mongodb',\n },\n postgres: {\n adapterName: 'postgresAdapter',\n configTemplate: (envVar: string) => `postgresAdapter({\n pool: {\n connectionString: process.env.${envVar} || '',\n },\n})`,\n packageName: '@payloadcms/db-postgres',\n },\n sqlite: {\n adapterName: 'sqliteAdapter',\n configTemplate: () => `sqliteAdapter({\n client: {\n url: process.env.DATABASE_URL || '',\n },\n})`,\n packageName: '@payloadcms/db-sqlite',\n },\n 'vercel-postgres': {\n adapterName: 'vercelPostgresAdapter',\n configTemplate: () => `vercelPostgresAdapter({\n pool: {\n connectionString: process.env.POSTGRES_URL || '',\n },\n})`,\n packageName: '@payloadcms/db-vercel-postgres',\n },\n} as const\n\n/**\n * Storage adapter configurations\n */\nexport const STORAGE_ADAPTER_CONFIG: Record<StorageAdapter, StorageAdapterConfig> = {\n azureStorage: {\n adapterName: 'azureStorage',\n configTemplate: () => `azureStorage({\n collections: {\n media: true,\n },\n connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING || '',\n containerName: process.env.AZURE_STORAGE_CONTAINER_NAME || '',\n })`,\n packageName: '@payloadcms/storage-azure',\n },\n gcsStorage: {\n adapterName: 'gcsStorage',\n configTemplate: () => `gcsStorage({\n collections: {\n media: true,\n },\n bucket: process.env.GCS_BUCKET || '',\n })`,\n packageName: '@payloadcms/storage-gcs',\n },\n localDisk: {\n adapterName: null,\n configTemplate: () => null,\n packageName: null,\n },\n r2Storage: {\n adapterName: 'r2Storage',\n configTemplate: () => `r2Storage({\n bucket: cloudflare.env.R2,\n collections: { media: true },\n })`,\n packageName: '@payloadcms/storage-r2',\n },\n s3Storage: {\n adapterName: 's3Storage',\n configTemplate: () => `s3Storage({\n collections: {\n media: true,\n },\n bucket: process.env.S3_BUCKET || '',\n config: {\n credentials: {\n accessKeyId: process.env.S3_ACCESS_KEY_ID || '',\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || '',\n },\n region: process.env.S3_REGION || '',\n },\n })`,\n packageName: '@payloadcms/storage-s3',\n },\n uploadthingStorage: {\n adapterName: 'uploadthingStorage',\n configTemplate: () => `uploadthingStorage({\n collections: {\n media: true,\n },\n token: process.env.UPLOADTHING_SECRET || '',\n })`,\n packageName: '@payloadcms/storage-uploadthing',\n },\n vercelBlobStorage: {\n adapterName: 'vercelBlobStorage',\n configTemplate: () => `vercelBlobStorage({\n collections: {\n media: true,\n },\n token: process.env.BLOB_READ_WRITE_TOKEN || '',\n })`,\n packageName: '@payloadcms/storage-vercel-blob',\n },\n} as const\n\n/**\n * Helper to get database adapter package name\n */\nexport function getDbPackageName(adapter: DatabaseAdapter): string {\n return DB_ADAPTER_CONFIG[adapter].packageName\n}\n\n/**\n * Helper to get database adapter name\n */\nexport function getDbAdapterName(adapter: DatabaseAdapter): string {\n return DB_ADAPTER_CONFIG[adapter].adapterName\n}\n\n/**\n * Helper to get storage adapter package name\n */\nexport function getStoragePackageName(adapter: StorageAdapter): null | string {\n return STORAGE_ADAPTER_CONFIG[adapter].packageName\n}\n\n/**\n * Helper to get storage adapter name\n */\nexport function getStorageAdapterName(adapter: StorageAdapter): null | string {\n return STORAGE_ADAPTER_CONFIG[adapter].adapterName\n}\n"],"names":["DB_ADAPTER_CONFIG","adapterName","configTemplate","packageName","mongodb","envVar","postgres","sqlite","STORAGE_ADAPTER_CONFIG","azureStorage","gcsStorage","localDisk","r2Storage","s3Storage","uploadthingStorage","vercelBlobStorage","getDbPackageName","adapter","getDbAdapterName","getStoragePackageName","getStorageAdapterName"],"mappings":"AAAA;;;CAGC,GAgBD;;CAEC,GACD,OAAO,MAAMA,oBAAoE;IAC/E,aAAa;QACXC,aAAa;QACbC,gBAAgB,IAAM,CAAC;;EAEzB,CAAC;QACCC,aAAa;IACf;IACAC,SAAS;QACPH,aAAa;QACbC,gBAAgB,CAACG,SAAmB,CAAC;mBACtB,EAAEA,OAAO;EAC1B,CAAC;QACCF,aAAa;IACf;IACAG,UAAU;QACRL,aAAa;QACbC,gBAAgB,CAACG,SAAmB,CAAC;;kCAEP,EAAEA,OAAO;;EAEzC,CAAC;QACCF,aAAa;IACf;IACAI,QAAQ;QACNN,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;EAIzB,CAAC;QACCC,aAAa;IACf;IACA,mBAAmB;QACjBF,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;EAIzB,CAAC;QACCC,aAAa;IACf;AACF,EAAU;AAEV;;CAEC,GACD,OAAO,MAAMK,yBAAuE;IAClFC,cAAc;QACZR,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;;;IAMvB,CAAC;QACDC,aAAa;IACf;IACAO,YAAY;QACVT,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;;IAKvB,CAAC;QACDC,aAAa;IACf;IACAQ,WAAW;QACTV,aAAa;QACbC,gBAAgB,IAAM;QACtBC,aAAa;IACf;IACAS,WAAW;QACTX,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;IAGvB,CAAC;QACDC,aAAa;IACf;IACAU,WAAW;QACTZ,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;;;;;;;;;IAYvB,CAAC;QACDC,aAAa;IACf;IACAW,oBAAoB;QAClBb,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;;IAKvB,CAAC;QACDC,aAAa;IACf;IACAY,mBAAmB;QACjBd,aAAa;QACbC,gBAAgB,IAAM,CAAC;;;;;IAKvB,CAAC;QACDC,aAAa;IACf;AACF,EAAU;AAEV;;CAEC,GACD,OAAO,SAASa,iBAAiBC,OAAwB;IACvD,OAAOjB,iBAAiB,CAACiB,QAAQ,CAACd,WAAW;AAC/C;AAEA;;CAEC,GACD,OAAO,SAASe,iBAAiBD,OAAwB;IACvD,OAAOjB,iBAAiB,CAACiB,QAAQ,CAAChB,WAAW;AAC/C;AAEA;;CAEC,GACD,OAAO,SAASkB,sBAAsBF,OAAuB;IAC3D,OAAOT,sBAAsB,CAACS,QAAQ,CAACd,WAAW;AACpD;AAEA;;CAEC,GACD,OAAO,SAASiB,sBAAsBH,OAAuB;IAC3D,OAAOT,sBAAsB,CAACS,QAAQ,CAAChB,WAAW;AACpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/ast/package-json.spec.ts"],"sourcesContent":["import { updatePackageJson } from './package-json'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\ndescribe('updatePackageJson', () => {\n let tempDir: string\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-test-'))\n })\n\n afterEach(() => {\n fs.rmSync(tempDir, { recursive: true, force: true })\n })\n\n it('updates database dependencies', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'test-app',\n dependencies: {\n '@payloadcms/db-mongodb': '^3.0.0',\n payload: '^3.0.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n databaseAdapter: 'postgres',\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.dependencies['@payloadcms/db-postgres']).toBeDefined()\n expect(updated.dependencies['@payloadcms/db-mongodb']).toBeUndefined()\n })\n\n it('removes sharp when requested', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'test-app',\n dependencies: {\n payload: '^3.0.0',\n sharp: '^0.33.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n removeSharp: true,\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.dependencies.sharp).toBeUndefined()\n })\n\n it('updates package name', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'template-name',\n dependencies: {\n payload: '^3.0.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n packageName: 'my-new-app',\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.name).toBe('my-new-app')\n })\n})\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/ast/package-json.spec.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, afterEach } from 'vitest'\nimport { updatePackageJson } from './package-json'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\ndescribe('updatePackageJson', () => {\n let tempDir: string\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-test-'))\n })\n\n afterEach(() => {\n fs.rmSync(tempDir, { recursive: true, force: true })\n })\n\n it('updates database dependencies', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'test-app',\n dependencies: {\n '@payloadcms/db-mongodb': '^3.0.0',\n payload: '^3.0.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n databaseAdapter: 'postgres',\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.dependencies['@payloadcms/db-postgres']).toBeDefined()\n expect(updated.dependencies['@payloadcms/db-mongodb']).toBeUndefined()\n })\n\n it('removes sharp when requested', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'test-app',\n dependencies: {\n payload: '^3.0.0',\n sharp: '^0.33.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n removeSharp: true,\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.dependencies.sharp).toBeUndefined()\n })\n\n it('updates package name', () => {\n const pkgPath = path.join(tempDir, 'package.json')\n const originalPkg = {\n name: 'template-name',\n dependencies: {\n payload: '^3.0.0',\n },\n }\n fs.writeFileSync(pkgPath, JSON.stringify(originalPkg, null, 2))\n\n updatePackageJson(pkgPath, {\n packageName: 'my-new-app',\n })\n\n const updated = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n expect(updated.name).toBe('my-new-app')\n })\n})\n"],"names":["describe","it","expect","beforeEach","afterEach","updatePackageJson","fs","path","os","tempDir","mkdtempSync","join","tmpdir","rmSync","recursive","force","pkgPath","originalPkg","name","dependencies","payload","writeFileSync","JSON","stringify","databaseAdapter","updated","parse","readFileSync","toBeDefined","toBeUndefined","sharp","removeSharp","packageName","toBe"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,EAAEC,UAAU,EAAEC,SAAS,QAAQ,SAAQ;AACpE,SAASC,iBAAiB,QAAQ,iBAAgB;AAClD,YAAYC,QAAQ,KAAI;AACxB,YAAYC,UAAU,OAAM;AAC5B,YAAYC,QAAQ,KAAI;AAExBR,SAAS,qBAAqB;IAC5B,IAAIS;IAEJN,WAAW;QACTM,UAAUH,GAAGI,WAAW,CAACH,KAAKI,IAAI,CAACH,GAAGI,MAAM,IAAI;IAClD;IAEAR,UAAU;QACRE,GAAGO,MAAM,CAACJ,SAAS;YAAEK,WAAW;YAAMC,OAAO;QAAK;IACpD;IAEAd,GAAG,iCAAiC;QAClC,MAAMe,UAAUT,KAAKI,IAAI,CAACF,SAAS;QACnC,MAAMQ,cAAc;YAClBC,MAAM;YACNC,cAAc;gBACZ,0BAA0B;gBAC1BC,SAAS;YACX;QACF;QACAd,GAAGe,aAAa,CAACL,SAASM,KAAKC,SAAS,CAACN,aAAa,MAAM;QAE5DZ,kBAAkBW,SAAS;YACzBQ,iBAAiB;QACnB;QAEA,MAAMC,UAAUH,KAAKI,KAAK,CAACpB,GAAGqB,YAAY,CAACX,SAAS;QACpDd,OAAOuB,QAAQN,YAAY,CAAC,0BAA0B,EAAES,WAAW;QACnE1B,OAAOuB,QAAQN,YAAY,CAAC,yBAAyB,EAAEU,aAAa;IACtE;IAEA5B,GAAG,gCAAgC;QACjC,MAAMe,UAAUT,KAAKI,IAAI,CAACF,SAAS;QACnC,MAAMQ,cAAc;YAClBC,MAAM;YACNC,cAAc;gBACZC,SAAS;gBACTU,OAAO;YACT;QACF;QACAxB,GAAGe,aAAa,CAACL,SAASM,KAAKC,SAAS,CAACN,aAAa,MAAM;QAE5DZ,kBAAkBW,SAAS;YACzBe,aAAa;QACf;QAEA,MAAMN,UAAUH,KAAKI,KAAK,CAACpB,GAAGqB,YAAY,CAACX,SAAS;QACpDd,OAAOuB,QAAQN,YAAY,CAACW,KAAK,EAAED,aAAa;IAClD;IAEA5B,GAAG,wBAAwB;QACzB,MAAMe,UAAUT,KAAKI,IAAI,CAACF,SAAS;QACnC,MAAMQ,cAAc;YAClBC,MAAM;YACNC,cAAc;gBACZC,SAAS;YACX;QACF;QACAd,GAAGe,aAAa,CAACL,SAASM,KAAKC,SAAS,CAACN,aAAa,MAAM;QAE5DZ,kBAAkBW,SAAS;YACzBgB,aAAa;QACf;QAEA,MAAMP,UAAUH,KAAKI,KAAK,CAACpB,GAAGqB,YAAY,CAACX,SAAS;QACpDd,OAAOuB,QAAQP,IAAI,EAAEe,IAAI,CAAC;IAC5B;AACF"}
|
|
@@ -119,7 +119,7 @@ export function detectPayloadConfigStructure(sourceFile) {
|
|
|
119
119
|
success: true
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
|
-
export function addDatabaseAdapter({ adapter, envVarName = '
|
|
122
|
+
export function addDatabaseAdapter({ adapter, envVarName = 'DATABASE_URL', sourceFile }) {
|
|
123
123
|
debug(`[AST] Adding database adapter: ${adapter} (envVar: ${envVarName})`);
|
|
124
124
|
const modifications = [];
|
|
125
125
|
const detection = detectPayloadConfigStructure(sourceFile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/ast/payload-config.ts"],"sourcesContent":["import { execSync } from 'child_process'\nimport path from 'path'\nimport { Project, QuoteKind, type SourceFile, SyntaxKind } from 'ts-morph'\n\nimport type {\n ConfigureOptions,\n DatabaseAdapter,\n DetectionResult,\n Modification,\n StorageAdapter,\n TransformationResult,\n WriteOptions,\n WriteResult,\n} from './types.js'\n\nimport { debug } from '../../utils/log.js'\nimport { DB_ADAPTER_CONFIG, STORAGE_ADAPTER_CONFIG } from './adapter-config.js'\nimport {\n addImportDeclaration,\n cleanupOrphanedImports,\n formatError,\n removeImportDeclaration,\n} from './utils.js'\n\nexport function detectPayloadConfigStructure(sourceFile: SourceFile): DetectionResult {\n debug(`[AST] Detecting payload config structure in ${sourceFile.getFilePath()}`)\n\n // First find the actual name being used (might be aliased)\n const payloadImport = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === 'payload')\n\n const buildConfigImportSpec = payloadImport\n ?.getNamedImports()\n .find((spec) => spec.getName() === 'buildConfig')\n\n const aliasNode = buildConfigImportSpec?.getAliasNode()\n const buildConfigName = aliasNode ? aliasNode.getText() : 'buildConfig'\n\n debug(`[AST] Looking for function call: ${buildConfigName}`)\n\n // Find buildConfig call expression (using actual name in code)\n const buildConfigCall = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .find((call) => {\n const expression = call.getExpression()\n return expression.getText() === buildConfigName\n })\n\n if (!buildConfigCall) {\n debug(`[AST] ✗ ${buildConfigName} call not found`)\n return {\n error: formatError({\n actual: `No ${buildConfigName} call found in file`,\n context: 'buildConfig call',\n expected: `export default ${buildConfigName}({ ... })`,\n technicalDetails: `Could not find CallExpression with identifier \"${buildConfigName}\"`,\n }),\n success: false,\n }\n }\n\n debug(`[AST] ✓ ${buildConfigName} call found`)\n\n // Get import statements\n const importStatements = sourceFile.getImportDeclarations()\n debug(`[AST] Found ${importStatements.length} import statements`)\n\n // Find db property if it exists\n const configObject = buildConfigCall.getArguments()[0]\n let dbProperty\n if (configObject && configObject.getKind() === SyntaxKind.ObjectLiteralExpression) {\n dbProperty = configObject\n .asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n .getProperty('db')\n ?.asKind(SyntaxKind.PropertyAssignment)\n }\n\n debug(`[AST] db property: ${dbProperty ? '✓ found' : '✗ not found'}`)\n\n // Find plugins array if it exists\n let pluginsArray\n if (configObject && configObject.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n const pluginsProperty = objLiteral.getProperty('plugins')\n\n // Handle PropertyAssignment (e.g., plugins: [...])\n const propertyAssignment = pluginsProperty?.asKind(SyntaxKind.PropertyAssignment)\n if (propertyAssignment) {\n const initializer = propertyAssignment.getInitializer()\n if (initializer?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n pluginsArray = initializer.asKind(SyntaxKind.ArrayLiteralExpression)\n }\n }\n // For ShorthandPropertyAssignment (e.g., plugins), we can't get the array directly\n // but we'll detect it in addStorageAdapter\n }\n\n debug(`[AST] plugins array: ${pluginsArray ? '✓ found' : '✗ not found'}`)\n\n // Find all buildConfig calls for edge case detection (using actual name)\n const allBuildConfigCalls = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .filter((call) => {\n const expression = call.getExpression()\n return expression.getText() === buildConfigName\n })\n\n const hasImportAlias = !!aliasNode\n\n // Check for other Payload imports\n const payloadImports = payloadImport?.getNamedImports() || []\n const hasOtherPayloadImports =\n payloadImports.length > 1 || payloadImports.some((imp) => imp.getName() !== 'buildConfig')\n\n // Track database adapter imports\n let dbAdapterImportInfo\n for (const [, config] of Object.entries(DB_ADAPTER_CONFIG)) {\n const importDecl = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === config.packageName)\n\n if (importDecl) {\n const namedImports = importDecl.getNamedImports()\n dbAdapterImportInfo = {\n hasOtherImports: namedImports.length > 1,\n importDeclaration: importDecl,\n packageName: config.packageName,\n }\n break\n }\n }\n\n // Track storage adapter imports\n const storageAdapterImports = []\n for (const [, config] of Object.entries(STORAGE_ADAPTER_CONFIG)) {\n if (!config.packageName || !config.adapterName) {\n continue\n }\n\n const importDecl = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === config.packageName)\n\n if (importDecl) {\n const namedImports = importDecl.getNamedImports()\n storageAdapterImports.push({\n hasOtherImports: namedImports.length > 1,\n importDeclaration: importDecl,\n packageName: config.packageName,\n })\n }\n }\n\n const needsManualIntervention = hasImportAlias || allBuildConfigCalls.length > 2\n\n debug(\n `[AST] Edge cases: alias=${hasImportAlias}, multiple=${allBuildConfigCalls.length > 1}, otherImports=${hasOtherPayloadImports}, manual=${needsManualIntervention}`,\n )\n\n return {\n edgeCases: {\n hasImportAlias,\n hasOtherPayloadImports,\n multipleBuildConfigCalls: allBuildConfigCalls.length > 1,\n needsManualIntervention,\n },\n importSources: {\n dbAdapter: dbAdapterImportInfo,\n storageAdapters: storageAdapterImports.length > 0 ? storageAdapterImports : undefined,\n },\n sourceFile,\n structures: {\n buildConfigCall,\n dbProperty,\n importStatements,\n pluginsArray,\n },\n success: true,\n }\n}\n\nexport function addDatabaseAdapter({\n adapter,\n envVarName = 'DATABASE_URI',\n sourceFile,\n}: {\n adapter: DatabaseAdapter\n envVarName?: string\n sourceFile: SourceFile\n}): TransformationResult {\n debug(`[AST] Adding database adapter: ${adapter} (envVar: ${envVarName})`)\n\n const modifications: Modification[] = []\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const { buildConfigCall, dbProperty } = detection.structures\n const config = DB_ADAPTER_CONFIG[adapter]\n\n // Remove old db adapter imports and track position for replacement\n const oldAdapters = Object.values(DB_ADAPTER_CONFIG)\n const removedAdapters: string[] = []\n let importInsertIndex: number | undefined\n oldAdapters.forEach((oldConfig) => {\n if (oldConfig.packageName !== config.packageName) {\n const { removedIndex } = removeImportDeclaration({\n moduleSpecifier: oldConfig.packageName,\n sourceFile,\n })\n if (removedIndex !== undefined) {\n // Use the first removed adapter's position\n if (importInsertIndex === undefined) {\n importInsertIndex = removedIndex\n }\n removedAdapters.push(oldConfig.packageName)\n modifications.push({\n type: 'import-removed',\n description: `Removed import from '${oldConfig.packageName}'`,\n })\n }\n }\n })\n\n if (removedAdapters.length > 0) {\n debug(`[AST] Removed old adapter imports: ${removedAdapters.join(', ')}`)\n }\n\n // Add new import at the position of the removed one (or default position)\n addImportDeclaration({\n insertIndex: importInsertIndex,\n moduleSpecifier: config.packageName,\n namedImports: [config.adapterName],\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: { ${config.adapterName} } from '${config.packageName}'`,\n })\n\n // Add special imports for specific adapters\n if (adapter === 'd1-sqlite') {\n debug('[AST] Adding special import: ./db/migrations')\n addImportDeclaration({\n defaultImport: 'migrations',\n moduleSpecifier: './db/migrations',\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: migrations from './db/migrations'`,\n })\n }\n\n // Get config object\n const configObject = buildConfigCall.getArguments()[0]\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n error: formatError({\n actual: 'buildConfig has no object literal argument',\n context: 'database adapter configuration',\n expected: 'buildConfig({ ... })',\n technicalDetails: 'buildConfig call must have an object literal as first argument',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\n const newDbCode = `db: ${config.configTemplate(envVarName)}`\n\n if (dbProperty) {\n // Replace existing db property\n // NOTE: Using replaceWithText() instead of remove() + insertPropertyAssignment()\n // to avoid double comma issues. When remove() is called, ts-morph doesn't always\n // clean up trailing commas correctly, which can result in syntax like \"},,\" when\n // inserting a new property at that position. replaceWithText() preserves the\n // surrounding punctuation correctly.\n debug(`[AST] Replacing existing db property`)\n dbProperty.replaceWithText(newDbCode)\n modifications.push({\n type: 'property-added',\n description: `Replaced db property with ${adapter} adapter`,\n })\n } else {\n // No existing db property - insert at end\n const insertIndex = objLiteral.getProperties().length\n debug(`[AST] Adding db property at index ${insertIndex}`)\n objLiteral.insertPropertyAssignment(insertIndex, {\n name: 'db',\n initializer: config.configTemplate(envVarName),\n })\n modifications.push({\n type: 'property-added',\n description: `Added db property with ${adapter} adapter`,\n })\n }\n\n debug(`[AST] ✓ Database adapter ${adapter} added successfully`)\n\n return {\n modifications,\n modified: true,\n success: true,\n }\n}\n\nexport function addStorageAdapter({\n adapter,\n sourceFile,\n}: {\n adapter: StorageAdapter\n sourceFile: SourceFile\n}): TransformationResult {\n debug(`[AST] Adding storage adapter: ${adapter}`)\n\n const modifications: Modification[] = []\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const config = STORAGE_ADAPTER_CONFIG[adapter]\n\n // Local disk doesn't need any imports or plugins\n if (adapter === 'localDisk') {\n debug('[AST] localDisk storage adapter - no imports or plugins needed')\n return {\n modifications: [],\n modified: false,\n success: true,\n }\n }\n\n // Add import\n if (config.packageName && config.adapterName) {\n addImportDeclaration({\n moduleSpecifier: config.packageName,\n namedImports: [config.adapterName],\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: { ${config.adapterName} } from '${config.packageName}'`,\n })\n }\n\n const { buildConfigCall } = detection.structures\n const configObject = buildConfigCall.getArguments()[0]\n\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n error: formatError({\n actual: 'buildConfig has no object literal argument',\n context: 'storage adapter configuration',\n expected: 'buildConfig({ ... })',\n technicalDetails: 'buildConfig call must have an object literal as first argument',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\n // Find or create plugins array\n const pluginsPropertyRaw = objLiteral.getProperty('plugins')\n let pluginsProperty = pluginsPropertyRaw?.asKind(SyntaxKind.PropertyAssignment)\n\n // Check if it's a shorthand property (e.g., `plugins` referencing an imported variable)\n const shorthandProperty = pluginsPropertyRaw?.asKind(SyntaxKind.ShorthandPropertyAssignment)\n\n if (shorthandProperty) {\n debug('[AST] Found shorthand plugins property, converting to long form with spread')\n // Get the identifier name (usually 'plugins')\n const identifierName = shorthandProperty.getName()\n\n // Find insert position before removing\n const allProperties = objLiteral.getProperties()\n const insertIndex = allProperties.indexOf(shorthandProperty)\n\n // Remove the shorthand property\n shorthandProperty.remove()\n\n // Create new property with spread operator: plugins: [...plugins, newAdapter]\n objLiteral.insertPropertyAssignment(insertIndex, {\n name: 'plugins',\n initializer: `[...${identifierName}]`,\n })\n\n pluginsProperty = objLiteral.getProperty('plugins')?.asKind(SyntaxKind.PropertyAssignment)\n modifications.push({\n type: 'property-added',\n description: `Converted shorthand plugins property to array with spread syntax`,\n })\n } else if (!pluginsProperty) {\n debug('[AST] Creating new plugins array')\n // Create plugins array\n objLiteral.addPropertyAssignment({\n name: 'plugins',\n initializer: '[]',\n })\n pluginsProperty = objLiteral.getProperty('plugins')?.asKind(SyntaxKind.PropertyAssignment)\n modifications.push({\n type: 'property-added',\n description: `Created plugins array`,\n })\n } else {\n debug('[AST] Reusing existing plugins array')\n }\n\n if (!pluginsProperty) {\n return {\n error: formatError({\n actual: 'Failed to create or find plugins property',\n context: 'storage adapter configuration',\n expected: 'plugins array property',\n technicalDetails: 'Could not create or access plugins property',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const initializer = pluginsProperty.getInitializer()\n if (!initializer || initializer.getKind() !== SyntaxKind.ArrayLiteralExpression) {\n return {\n error: formatError({\n actual: 'plugins property is not an array',\n context: 'storage adapter configuration',\n expected: 'plugins: [...]',\n technicalDetails: 'plugins property must be an array literal expression',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const pluginsArray = initializer.asKindOrThrow(SyntaxKind.ArrayLiteralExpression)\n\n // Add storage adapter call\n const configText = config.configTemplate()\n if (configText) {\n pluginsArray.addElement(configText)\n modifications.push({\n type: 'property-added',\n description: `Added ${adapter} to plugins array`,\n })\n }\n\n debug(`[AST] ✓ Storage adapter ${adapter} added successfully`)\n\n return {\n modifications,\n modified: true,\n success: true,\n }\n}\n\nexport function removeSharp(sourceFile: SourceFile): TransformationResult {\n debug('[AST] Removing sharp import and property')\n\n const modifications: Modification[] = []\n\n // Remove import\n const { removedIndex } = removeImportDeclaration({ moduleSpecifier: 'sharp', sourceFile })\n if (removedIndex !== undefined) {\n modifications.push({\n type: 'import-removed',\n description: `Removed import from 'sharp'`,\n })\n }\n\n // Find and remove sharp property from buildConfig\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n // If detection failed but we removed import, still count as partial success\n if (modifications.length > 0) {\n return {\n modifications,\n modified: true,\n success: true,\n warnings: ['Could not detect config structure to remove sharp property'],\n }\n }\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const { buildConfigCall } = detection.structures\n const configObject = buildConfigCall.getArguments()[0]\n\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n modifications,\n modified: modifications.length > 0,\n success: true,\n warnings: ['buildConfig has no object literal argument - could not remove sharp property'],\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n const sharpProperty = objLiteral.getProperty('sharp')\n\n if (sharpProperty) {\n sharpProperty.remove()\n modifications.push({\n type: 'property-removed',\n description: `Removed sharp property from config`,\n })\n debug('[AST] ✓ Sharp property removed from config')\n } else {\n debug('[AST] Sharp property not found (already absent)')\n }\n\n return {\n modifications,\n modified: modifications.length > 0,\n success: true,\n }\n}\n\n/** This shouldn't be necessary once the templates are updated. Can't hurt to keep in, though */\nexport function removeCommentMarkers(sourceFile: SourceFile): SourceFile {\n // Get the full text and replace comment markers\n let text = sourceFile.getFullText()\n\n // Remove inline comment markers from imports\n text = text.replace(/\\s*\\/\\/\\s*database-adapter-import\\s*$/gm, '')\n text = text.replace(/\\s*\\/\\/\\s*storage-adapter-import-placeholder\\s*$/gm, '')\n\n // Remove standalone comment lines\n text = text.replace(/^\\s*\\/\\/\\s*database-adapter-config-start\\s*\\n/gm, '')\n text = text.replace(/^\\s*\\/\\/\\s*database-adapter-config-end\\s*\\n/gm, '')\n text = text.replace(/^\\s*\\/\\/\\s*storage-adapter-placeholder\\s*\\n/gm, '')\n\n // Also remove the placeholder line from template (storage-adapter-import-placeholder at top)\n text = text.replace(/^\\/\\/\\s*storage-adapter-import-placeholder\\s*\\n/gm, '')\n\n // Replace the entire source file content\n sourceFile.replaceWithText(text)\n\n return sourceFile\n}\n\n/**\n * Validates payload config structure has required elements after transformation.\n * Checks that buildConfig() call exists and has a db property configured.\n */\nexport function validateStructure(sourceFile: SourceFile): WriteResult {\n debug('[AST] Validating payload config structure')\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success) {\n debug('[AST] ✗ Validation failed: detection unsuccessful')\n return {\n error: detection.error,\n success: false,\n }\n }\n\n const { structures } = detection\n\n // Validate db property exists\n if (!structures?.dbProperty) {\n debug('[AST] ✗ Validation failed: db property missing')\n return {\n error: formatError({\n actual: 'No db property found',\n context: 'database configuration',\n expected: 'buildConfig must have a db property',\n technicalDetails: 'PropertyAssignment with name \"db\" not found in buildConfig object',\n }),\n success: false,\n }\n }\n\n debug('[AST] ✓ Validation passed')\n return { success: true }\n}\n\nexport async function writeTransformedFile(\n sourceFile: SourceFile,\n options: WriteOptions = {},\n): Promise<WriteResult> {\n const { formatWithPrettier = true, validateStructure: shouldValidate = true } = options\n\n debug(`[AST] Writing transformed file: ${sourceFile.getFilePath()}`)\n\n // Validate if requested\n if (shouldValidate) {\n const validation = validateStructure(sourceFile)\n if (!validation.success) {\n return validation\n }\n }\n\n // Get file path and save to disk\n const filePath = sourceFile.getFilePath()\n\n // Format with ts-morph before saving (fixes trailing commas, indentation)\n debug('[AST] Formatting with ts-morph')\n sourceFile.formatText()\n\n // Write file\n debug('[AST] Writing file to disk')\n await sourceFile.save()\n\n // Format with prettier if requested\n if (formatWithPrettier) {\n debug('[AST] Running prettier formatting via CLI')\n try {\n // Detect project directory (go up from file until we find package.json or use dirname)\n const projectDir = path.dirname(filePath)\n\n // Run prettier via CLI (avoids Jest/ESM compatibility issues)\n const prettierCmd = `npx prettier --write \"${filePath}\"`\n\n debug(`[AST] Executing: ${prettierCmd}`)\n execSync(prettierCmd, {\n cwd: projectDir,\n stdio: 'pipe', // Suppress output\n })\n debug('[AST] ✓ Prettier formatting successful')\n } catch (error) {\n // Log but don't fail if prettier fails (might not be installed)\n debug(\n `[AST] ⚠ Prettier formatting failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n debug('[AST] Continuing with unformatted output')\n }\n } else {\n debug('[AST] Skipping prettier formatting (disabled)')\n }\n\n debug('[AST] ✓ File written successfully')\n\n return { success: true }\n}\n\nexport async function configurePayloadConfig(\n filePath: string,\n options: ConfigureOptions = {},\n): Promise<WriteResult> {\n debug(`[AST] Configuring payload config: ${filePath}`)\n debug(\n `[AST] Options: db=${options.db?.type}, storage=${options.storage}, removeSharp=${options.removeSharp}`,\n )\n\n const allModifications: Modification[] = []\n const allWarnings: string[] = []\n\n try {\n // Create Project and load source file with proper settings\n const project = new Project({\n manipulationSettings: {\n quoteKind: QuoteKind.Single,\n },\n })\n let sourceFile = project.addSourceFileAtPath(filePath)\n\n // Run detection\n const detection = detectPayloadConfigStructure(sourceFile)\n if (!detection.success) {\n return detection\n }\n\n // Apply transformations based on options\n if (options.db) {\n debug('[AST] Applying database adapter transformation')\n const result = addDatabaseAdapter({\n adapter: options.db.type,\n envVarName: options.db.envVarName,\n sourceFile,\n })\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n if (options.storage) {\n debug('[AST] Applying storage adapter transformation')\n const result = addStorageAdapter({ adapter: options.storage, sourceFile })\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n if (options.removeSharp) {\n debug('[AST] Applying sharp removal')\n const result = removeSharp(sourceFile)\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n // Remove comment markers from template\n sourceFile = removeCommentMarkers(sourceFile)\n\n // Cleanup orphaned imports after all transformations\n debug('[AST] Cleaning up orphaned imports')\n\n // Cleanup database adapter imports if db was removed\n for (const [, config] of Object.entries(DB_ADAPTER_CONFIG)) {\n if (options.db && config.packageName !== DB_ADAPTER_CONFIG[options.db.type].packageName) {\n const cleanup = cleanupOrphanedImports({\n importNames: [config.adapterName],\n moduleSpecifier: config.packageName,\n sourceFile,\n })\n if (cleanup.removed.length > 0) {\n cleanup.removed.forEach((importName) => {\n allModifications.push({\n type: 'import-removed',\n description: `Cleaned up unused import '${importName}' from '${config.packageName}'`,\n })\n })\n }\n }\n }\n\n // Log summary of modifications\n if (allModifications.length > 0) {\n debug(`[AST] Applied ${allModifications.length} modification(s):`)\n allModifications.forEach((mod) => {\n debug(`[AST] - ${mod.type}: ${mod.description}`)\n })\n }\n\n if (allWarnings.length > 0) {\n debug(`[AST] ${allWarnings.length} warning(s):`)\n allWarnings.forEach((warning) => {\n debug(`[AST] - ${warning}`)\n })\n }\n\n // Write transformed file with validation and formatting\n return await writeTransformedFile(sourceFile, {\n formatWithPrettier: options.formatWithPrettier,\n validateStructure: options.validateStructure ?? true,\n })\n } catch (error) {\n debug(`[AST] ✗ Configuration failed: ${error instanceof Error ? error.message : String(error)}`)\n return {\n error: formatError({\n actual: error instanceof Error ? error.message : String(error),\n context: 'configurePayloadConfig',\n expected: 'Successful file transformation',\n technicalDetails: error instanceof Error ? error.stack || error.message : String(error),\n }),\n success: false,\n }\n }\n}\n"],"names":["execSync","path","Project","QuoteKind","SyntaxKind","debug","DB_ADAPTER_CONFIG","STORAGE_ADAPTER_CONFIG","addImportDeclaration","cleanupOrphanedImports","formatError","removeImportDeclaration","detectPayloadConfigStructure","sourceFile","getFilePath","payloadImport","getImportDeclarations","find","imp","getModuleSpecifierValue","buildConfigImportSpec","getNamedImports","spec","getName","aliasNode","getAliasNode","buildConfigName","getText","buildConfigCall","getDescendantsOfKind","CallExpression","call","expression","getExpression","error","actual","context","expected","technicalDetails","success","importStatements","length","configObject","getArguments","dbProperty","getKind","ObjectLiteralExpression","asKindOrThrow","getProperty","asKind","PropertyAssignment","pluginsArray","objLiteral","pluginsProperty","propertyAssignment","initializer","getInitializer","ArrayLiteralExpression","allBuildConfigCalls","filter","hasImportAlias","payloadImports","hasOtherPayloadImports","some","dbAdapterImportInfo","config","Object","entries","importDecl","packageName","namedImports","hasOtherImports","importDeclaration","storageAdapterImports","adapterName","push","needsManualIntervention","edgeCases","multipleBuildConfigCalls","importSources","dbAdapter","storageAdapters","undefined","structures","addDatabaseAdapter","adapter","envVarName","modifications","detection","modified","oldAdapters","values","removedAdapters","importInsertIndex","forEach","oldConfig","removedIndex","moduleSpecifier","type","description","join","insertIndex","defaultImport","newDbCode","configTemplate","replaceWithText","getProperties","insertPropertyAssignment","name","addStorageAdapter","pluginsPropertyRaw","shorthandProperty","ShorthandPropertyAssignment","identifierName","allProperties","indexOf","remove","addPropertyAssignment","configText","addElement","removeSharp","warnings","sharpProperty","removeCommentMarkers","text","getFullText","replace","validateStructure","writeTransformedFile","options","formatWithPrettier","shouldValidate","validation","filePath","formatText","save","projectDir","dirname","prettierCmd","cwd","stdio","Error","message","configurePayloadConfig","db","storage","allModifications","allWarnings","project","manipulationSettings","quoteKind","Single","addSourceFileAtPath","result","cleanup","importNames","removed","importName","mod","warning","String","stack"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/ast/payload-config.ts"],"sourcesContent":["import { execSync } from 'child_process'\nimport path from 'path'\nimport { Project, QuoteKind, type SourceFile, SyntaxKind } from 'ts-morph'\n\nimport type {\n ConfigureOptions,\n DatabaseAdapter,\n DetectionResult,\n Modification,\n StorageAdapter,\n TransformationResult,\n WriteOptions,\n WriteResult,\n} from './types.js'\n\nimport { debug } from '../../utils/log.js'\nimport { DB_ADAPTER_CONFIG, STORAGE_ADAPTER_CONFIG } from './adapter-config.js'\nimport {\n addImportDeclaration,\n cleanupOrphanedImports,\n formatError,\n removeImportDeclaration,\n} from './utils.js'\n\nexport function detectPayloadConfigStructure(sourceFile: SourceFile): DetectionResult {\n debug(`[AST] Detecting payload config structure in ${sourceFile.getFilePath()}`)\n\n // First find the actual name being used (might be aliased)\n const payloadImport = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === 'payload')\n\n const buildConfigImportSpec = payloadImport\n ?.getNamedImports()\n .find((spec) => spec.getName() === 'buildConfig')\n\n const aliasNode = buildConfigImportSpec?.getAliasNode()\n const buildConfigName = aliasNode ? aliasNode.getText() : 'buildConfig'\n\n debug(`[AST] Looking for function call: ${buildConfigName}`)\n\n // Find buildConfig call expression (using actual name in code)\n const buildConfigCall = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .find((call) => {\n const expression = call.getExpression()\n return expression.getText() === buildConfigName\n })\n\n if (!buildConfigCall) {\n debug(`[AST] ✗ ${buildConfigName} call not found`)\n return {\n error: formatError({\n actual: `No ${buildConfigName} call found in file`,\n context: 'buildConfig call',\n expected: `export default ${buildConfigName}({ ... })`,\n technicalDetails: `Could not find CallExpression with identifier \"${buildConfigName}\"`,\n }),\n success: false,\n }\n }\n\n debug(`[AST] ✓ ${buildConfigName} call found`)\n\n // Get import statements\n const importStatements = sourceFile.getImportDeclarations()\n debug(`[AST] Found ${importStatements.length} import statements`)\n\n // Find db property if it exists\n const configObject = buildConfigCall.getArguments()[0]\n let dbProperty\n if (configObject && configObject.getKind() === SyntaxKind.ObjectLiteralExpression) {\n dbProperty = configObject\n .asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n .getProperty('db')\n ?.asKind(SyntaxKind.PropertyAssignment)\n }\n\n debug(`[AST] db property: ${dbProperty ? '✓ found' : '✗ not found'}`)\n\n // Find plugins array if it exists\n let pluginsArray\n if (configObject && configObject.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n const pluginsProperty = objLiteral.getProperty('plugins')\n\n // Handle PropertyAssignment (e.g., plugins: [...])\n const propertyAssignment = pluginsProperty?.asKind(SyntaxKind.PropertyAssignment)\n if (propertyAssignment) {\n const initializer = propertyAssignment.getInitializer()\n if (initializer?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n pluginsArray = initializer.asKind(SyntaxKind.ArrayLiteralExpression)\n }\n }\n // For ShorthandPropertyAssignment (e.g., plugins), we can't get the array directly\n // but we'll detect it in addStorageAdapter\n }\n\n debug(`[AST] plugins array: ${pluginsArray ? '✓ found' : '✗ not found'}`)\n\n // Find all buildConfig calls for edge case detection (using actual name)\n const allBuildConfigCalls = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .filter((call) => {\n const expression = call.getExpression()\n return expression.getText() === buildConfigName\n })\n\n const hasImportAlias = !!aliasNode\n\n // Check for other Payload imports\n const payloadImports = payloadImport?.getNamedImports() || []\n const hasOtherPayloadImports =\n payloadImports.length > 1 || payloadImports.some((imp) => imp.getName() !== 'buildConfig')\n\n // Track database adapter imports\n let dbAdapterImportInfo\n for (const [, config] of Object.entries(DB_ADAPTER_CONFIG)) {\n const importDecl = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === config.packageName)\n\n if (importDecl) {\n const namedImports = importDecl.getNamedImports()\n dbAdapterImportInfo = {\n hasOtherImports: namedImports.length > 1,\n importDeclaration: importDecl,\n packageName: config.packageName,\n }\n break\n }\n }\n\n // Track storage adapter imports\n const storageAdapterImports = []\n for (const [, config] of Object.entries(STORAGE_ADAPTER_CONFIG)) {\n if (!config.packageName || !config.adapterName) {\n continue\n }\n\n const importDecl = sourceFile\n .getImportDeclarations()\n .find((imp) => imp.getModuleSpecifierValue() === config.packageName)\n\n if (importDecl) {\n const namedImports = importDecl.getNamedImports()\n storageAdapterImports.push({\n hasOtherImports: namedImports.length > 1,\n importDeclaration: importDecl,\n packageName: config.packageName,\n })\n }\n }\n\n const needsManualIntervention = hasImportAlias || allBuildConfigCalls.length > 2\n\n debug(\n `[AST] Edge cases: alias=${hasImportAlias}, multiple=${allBuildConfigCalls.length > 1}, otherImports=${hasOtherPayloadImports}, manual=${needsManualIntervention}`,\n )\n\n return {\n edgeCases: {\n hasImportAlias,\n hasOtherPayloadImports,\n multipleBuildConfigCalls: allBuildConfigCalls.length > 1,\n needsManualIntervention,\n },\n importSources: {\n dbAdapter: dbAdapterImportInfo,\n storageAdapters: storageAdapterImports.length > 0 ? storageAdapterImports : undefined,\n },\n sourceFile,\n structures: {\n buildConfigCall,\n dbProperty,\n importStatements,\n pluginsArray,\n },\n success: true,\n }\n}\n\nexport function addDatabaseAdapter({\n adapter,\n envVarName = 'DATABASE_URL',\n sourceFile,\n}: {\n adapter: DatabaseAdapter\n envVarName?: string\n sourceFile: SourceFile\n}): TransformationResult {\n debug(`[AST] Adding database adapter: ${adapter} (envVar: ${envVarName})`)\n\n const modifications: Modification[] = []\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const { buildConfigCall, dbProperty } = detection.structures\n const config = DB_ADAPTER_CONFIG[adapter]\n\n // Remove old db adapter imports and track position for replacement\n const oldAdapters = Object.values(DB_ADAPTER_CONFIG)\n const removedAdapters: string[] = []\n let importInsertIndex: number | undefined\n oldAdapters.forEach((oldConfig) => {\n if (oldConfig.packageName !== config.packageName) {\n const { removedIndex } = removeImportDeclaration({\n moduleSpecifier: oldConfig.packageName,\n sourceFile,\n })\n if (removedIndex !== undefined) {\n // Use the first removed adapter's position\n if (importInsertIndex === undefined) {\n importInsertIndex = removedIndex\n }\n removedAdapters.push(oldConfig.packageName)\n modifications.push({\n type: 'import-removed',\n description: `Removed import from '${oldConfig.packageName}'`,\n })\n }\n }\n })\n\n if (removedAdapters.length > 0) {\n debug(`[AST] Removed old adapter imports: ${removedAdapters.join(', ')}`)\n }\n\n // Add new import at the position of the removed one (or default position)\n addImportDeclaration({\n insertIndex: importInsertIndex,\n moduleSpecifier: config.packageName,\n namedImports: [config.adapterName],\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: { ${config.adapterName} } from '${config.packageName}'`,\n })\n\n // Add special imports for specific adapters\n if (adapter === 'd1-sqlite') {\n debug('[AST] Adding special import: ./db/migrations')\n addImportDeclaration({\n defaultImport: 'migrations',\n moduleSpecifier: './db/migrations',\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: migrations from './db/migrations'`,\n })\n }\n\n // Get config object\n const configObject = buildConfigCall.getArguments()[0]\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n error: formatError({\n actual: 'buildConfig has no object literal argument',\n context: 'database adapter configuration',\n expected: 'buildConfig({ ... })',\n technicalDetails: 'buildConfig call must have an object literal as first argument',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\n const newDbCode = `db: ${config.configTemplate(envVarName)}`\n\n if (dbProperty) {\n // Replace existing db property\n // NOTE: Using replaceWithText() instead of remove() + insertPropertyAssignment()\n // to avoid double comma issues. When remove() is called, ts-morph doesn't always\n // clean up trailing commas correctly, which can result in syntax like \"},,\" when\n // inserting a new property at that position. replaceWithText() preserves the\n // surrounding punctuation correctly.\n debug(`[AST] Replacing existing db property`)\n dbProperty.replaceWithText(newDbCode)\n modifications.push({\n type: 'property-added',\n description: `Replaced db property with ${adapter} adapter`,\n })\n } else {\n // No existing db property - insert at end\n const insertIndex = objLiteral.getProperties().length\n debug(`[AST] Adding db property at index ${insertIndex}`)\n objLiteral.insertPropertyAssignment(insertIndex, {\n name: 'db',\n initializer: config.configTemplate(envVarName),\n })\n modifications.push({\n type: 'property-added',\n description: `Added db property with ${adapter} adapter`,\n })\n }\n\n debug(`[AST] ✓ Database adapter ${adapter} added successfully`)\n\n return {\n modifications,\n modified: true,\n success: true,\n }\n}\n\nexport function addStorageAdapter({\n adapter,\n sourceFile,\n}: {\n adapter: StorageAdapter\n sourceFile: SourceFile\n}): TransformationResult {\n debug(`[AST] Adding storage adapter: ${adapter}`)\n\n const modifications: Modification[] = []\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const config = STORAGE_ADAPTER_CONFIG[adapter]\n\n // Local disk doesn't need any imports or plugins\n if (adapter === 'localDisk') {\n debug('[AST] localDisk storage adapter - no imports or plugins needed')\n return {\n modifications: [],\n modified: false,\n success: true,\n }\n }\n\n // Add import\n if (config.packageName && config.adapterName) {\n addImportDeclaration({\n moduleSpecifier: config.packageName,\n namedImports: [config.adapterName],\n sourceFile,\n })\n modifications.push({\n type: 'import-added',\n description: `Added import: { ${config.adapterName} } from '${config.packageName}'`,\n })\n }\n\n const { buildConfigCall } = detection.structures\n const configObject = buildConfigCall.getArguments()[0]\n\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n error: formatError({\n actual: 'buildConfig has no object literal argument',\n context: 'storage adapter configuration',\n expected: 'buildConfig({ ... })',\n technicalDetails: 'buildConfig call must have an object literal as first argument',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\n // Find or create plugins array\n const pluginsPropertyRaw = objLiteral.getProperty('plugins')\n let pluginsProperty = pluginsPropertyRaw?.asKind(SyntaxKind.PropertyAssignment)\n\n // Check if it's a shorthand property (e.g., `plugins` referencing an imported variable)\n const shorthandProperty = pluginsPropertyRaw?.asKind(SyntaxKind.ShorthandPropertyAssignment)\n\n if (shorthandProperty) {\n debug('[AST] Found shorthand plugins property, converting to long form with spread')\n // Get the identifier name (usually 'plugins')\n const identifierName = shorthandProperty.getName()\n\n // Find insert position before removing\n const allProperties = objLiteral.getProperties()\n const insertIndex = allProperties.indexOf(shorthandProperty)\n\n // Remove the shorthand property\n shorthandProperty.remove()\n\n // Create new property with spread operator: plugins: [...plugins, newAdapter]\n objLiteral.insertPropertyAssignment(insertIndex, {\n name: 'plugins',\n initializer: `[...${identifierName}]`,\n })\n\n pluginsProperty = objLiteral.getProperty('plugins')?.asKind(SyntaxKind.PropertyAssignment)\n modifications.push({\n type: 'property-added',\n description: `Converted shorthand plugins property to array with spread syntax`,\n })\n } else if (!pluginsProperty) {\n debug('[AST] Creating new plugins array')\n // Create plugins array\n objLiteral.addPropertyAssignment({\n name: 'plugins',\n initializer: '[]',\n })\n pluginsProperty = objLiteral.getProperty('plugins')?.asKind(SyntaxKind.PropertyAssignment)\n modifications.push({\n type: 'property-added',\n description: `Created plugins array`,\n })\n } else {\n debug('[AST] Reusing existing plugins array')\n }\n\n if (!pluginsProperty) {\n return {\n error: formatError({\n actual: 'Failed to create or find plugins property',\n context: 'storage adapter configuration',\n expected: 'plugins array property',\n technicalDetails: 'Could not create or access plugins property',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const initializer = pluginsProperty.getInitializer()\n if (!initializer || initializer.getKind() !== SyntaxKind.ArrayLiteralExpression) {\n return {\n error: formatError({\n actual: 'plugins property is not an array',\n context: 'storage adapter configuration',\n expected: 'plugins: [...]',\n technicalDetails: 'plugins property must be an array literal expression',\n }),\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const pluginsArray = initializer.asKindOrThrow(SyntaxKind.ArrayLiteralExpression)\n\n // Add storage adapter call\n const configText = config.configTemplate()\n if (configText) {\n pluginsArray.addElement(configText)\n modifications.push({\n type: 'property-added',\n description: `Added ${adapter} to plugins array`,\n })\n }\n\n debug(`[AST] ✓ Storage adapter ${adapter} added successfully`)\n\n return {\n modifications,\n modified: true,\n success: true,\n }\n}\n\nexport function removeSharp(sourceFile: SourceFile): TransformationResult {\n debug('[AST] Removing sharp import and property')\n\n const modifications: Modification[] = []\n\n // Remove import\n const { removedIndex } = removeImportDeclaration({ moduleSpecifier: 'sharp', sourceFile })\n if (removedIndex !== undefined) {\n modifications.push({\n type: 'import-removed',\n description: `Removed import from 'sharp'`,\n })\n }\n\n // Find and remove sharp property from buildConfig\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success || !detection.structures) {\n // If detection failed but we removed import, still count as partial success\n if (modifications.length > 0) {\n return {\n modifications,\n modified: true,\n success: true,\n warnings: ['Could not detect config structure to remove sharp property'],\n }\n }\n return {\n error: detection.error,\n modifications: [],\n modified: false,\n success: false,\n }\n }\n\n const { buildConfigCall } = detection.structures\n const configObject = buildConfigCall.getArguments()[0]\n\n if (!configObject || configObject.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return {\n modifications,\n modified: modifications.length > 0,\n success: true,\n warnings: ['buildConfig has no object literal argument - could not remove sharp property'],\n }\n }\n\n const objLiteral = configObject.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n const sharpProperty = objLiteral.getProperty('sharp')\n\n if (sharpProperty) {\n sharpProperty.remove()\n modifications.push({\n type: 'property-removed',\n description: `Removed sharp property from config`,\n })\n debug('[AST] ✓ Sharp property removed from config')\n } else {\n debug('[AST] Sharp property not found (already absent)')\n }\n\n return {\n modifications,\n modified: modifications.length > 0,\n success: true,\n }\n}\n\n/** This shouldn't be necessary once the templates are updated. Can't hurt to keep in, though */\nexport function removeCommentMarkers(sourceFile: SourceFile): SourceFile {\n // Get the full text and replace comment markers\n let text = sourceFile.getFullText()\n\n // Remove inline comment markers from imports\n text = text.replace(/\\s*\\/\\/\\s*database-adapter-import\\s*$/gm, '')\n text = text.replace(/\\s*\\/\\/\\s*storage-adapter-import-placeholder\\s*$/gm, '')\n\n // Remove standalone comment lines\n text = text.replace(/^\\s*\\/\\/\\s*database-adapter-config-start\\s*\\n/gm, '')\n text = text.replace(/^\\s*\\/\\/\\s*database-adapter-config-end\\s*\\n/gm, '')\n text = text.replace(/^\\s*\\/\\/\\s*storage-adapter-placeholder\\s*\\n/gm, '')\n\n // Also remove the placeholder line from template (storage-adapter-import-placeholder at top)\n text = text.replace(/^\\/\\/\\s*storage-adapter-import-placeholder\\s*\\n/gm, '')\n\n // Replace the entire source file content\n sourceFile.replaceWithText(text)\n\n return sourceFile\n}\n\n/**\n * Validates payload config structure has required elements after transformation.\n * Checks that buildConfig() call exists and has a db property configured.\n */\nexport function validateStructure(sourceFile: SourceFile): WriteResult {\n debug('[AST] Validating payload config structure')\n\n const detection = detectPayloadConfigStructure(sourceFile)\n\n if (!detection.success) {\n debug('[AST] ✗ Validation failed: detection unsuccessful')\n return {\n error: detection.error,\n success: false,\n }\n }\n\n const { structures } = detection\n\n // Validate db property exists\n if (!structures?.dbProperty) {\n debug('[AST] ✗ Validation failed: db property missing')\n return {\n error: formatError({\n actual: 'No db property found',\n context: 'database configuration',\n expected: 'buildConfig must have a db property',\n technicalDetails: 'PropertyAssignment with name \"db\" not found in buildConfig object',\n }),\n success: false,\n }\n }\n\n debug('[AST] ✓ Validation passed')\n return { success: true }\n}\n\nexport async function writeTransformedFile(\n sourceFile: SourceFile,\n options: WriteOptions = {},\n): Promise<WriteResult> {\n const { formatWithPrettier = true, validateStructure: shouldValidate = true } = options\n\n debug(`[AST] Writing transformed file: ${sourceFile.getFilePath()}`)\n\n // Validate if requested\n if (shouldValidate) {\n const validation = validateStructure(sourceFile)\n if (!validation.success) {\n return validation\n }\n }\n\n // Get file path and save to disk\n const filePath = sourceFile.getFilePath()\n\n // Format with ts-morph before saving (fixes trailing commas, indentation)\n debug('[AST] Formatting with ts-morph')\n sourceFile.formatText()\n\n // Write file\n debug('[AST] Writing file to disk')\n await sourceFile.save()\n\n // Format with prettier if requested\n if (formatWithPrettier) {\n debug('[AST] Running prettier formatting via CLI')\n try {\n // Detect project directory (go up from file until we find package.json or use dirname)\n const projectDir = path.dirname(filePath)\n\n // Run prettier via CLI (avoids Jest/ESM compatibility issues)\n const prettierCmd = `npx prettier --write \"${filePath}\"`\n\n debug(`[AST] Executing: ${prettierCmd}`)\n execSync(prettierCmd, {\n cwd: projectDir,\n stdio: 'pipe', // Suppress output\n })\n debug('[AST] ✓ Prettier formatting successful')\n } catch (error) {\n // Log but don't fail if prettier fails (might not be installed)\n debug(\n `[AST] ⚠ Prettier formatting failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n debug('[AST] Continuing with unformatted output')\n }\n } else {\n debug('[AST] Skipping prettier formatting (disabled)')\n }\n\n debug('[AST] ✓ File written successfully')\n\n return { success: true }\n}\n\nexport async function configurePayloadConfig(\n filePath: string,\n options: ConfigureOptions = {},\n): Promise<WriteResult> {\n debug(`[AST] Configuring payload config: ${filePath}`)\n debug(\n `[AST] Options: db=${options.db?.type}, storage=${options.storage}, removeSharp=${options.removeSharp}`,\n )\n\n const allModifications: Modification[] = []\n const allWarnings: string[] = []\n\n try {\n // Create Project and load source file with proper settings\n const project = new Project({\n manipulationSettings: {\n quoteKind: QuoteKind.Single,\n },\n })\n let sourceFile = project.addSourceFileAtPath(filePath)\n\n // Run detection\n const detection = detectPayloadConfigStructure(sourceFile)\n if (!detection.success) {\n return detection\n }\n\n // Apply transformations based on options\n if (options.db) {\n debug('[AST] Applying database adapter transformation')\n const result = addDatabaseAdapter({\n adapter: options.db.type,\n envVarName: options.db.envVarName,\n sourceFile,\n })\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n if (options.storage) {\n debug('[AST] Applying storage adapter transformation')\n const result = addStorageAdapter({ adapter: options.storage, sourceFile })\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n if (options.removeSharp) {\n debug('[AST] Applying sharp removal')\n const result = removeSharp(sourceFile)\n\n if (!result.success) {\n return {\n error: result.error,\n success: false,\n }\n }\n\n allModifications.push(...result.modifications)\n if (result.warnings) {\n allWarnings.push(...result.warnings)\n }\n }\n\n // Remove comment markers from template\n sourceFile = removeCommentMarkers(sourceFile)\n\n // Cleanup orphaned imports after all transformations\n debug('[AST] Cleaning up orphaned imports')\n\n // Cleanup database adapter imports if db was removed\n for (const [, config] of Object.entries(DB_ADAPTER_CONFIG)) {\n if (options.db && config.packageName !== DB_ADAPTER_CONFIG[options.db.type].packageName) {\n const cleanup = cleanupOrphanedImports({\n importNames: [config.adapterName],\n moduleSpecifier: config.packageName,\n sourceFile,\n })\n if (cleanup.removed.length > 0) {\n cleanup.removed.forEach((importName) => {\n allModifications.push({\n type: 'import-removed',\n description: `Cleaned up unused import '${importName}' from '${config.packageName}'`,\n })\n })\n }\n }\n }\n\n // Log summary of modifications\n if (allModifications.length > 0) {\n debug(`[AST] Applied ${allModifications.length} modification(s):`)\n allModifications.forEach((mod) => {\n debug(`[AST] - ${mod.type}: ${mod.description}`)\n })\n }\n\n if (allWarnings.length > 0) {\n debug(`[AST] ${allWarnings.length} warning(s):`)\n allWarnings.forEach((warning) => {\n debug(`[AST] - ${warning}`)\n })\n }\n\n // Write transformed file with validation and formatting\n return await writeTransformedFile(sourceFile, {\n formatWithPrettier: options.formatWithPrettier,\n validateStructure: options.validateStructure ?? true,\n })\n } catch (error) {\n debug(`[AST] ✗ Configuration failed: ${error instanceof Error ? error.message : String(error)}`)\n return {\n error: formatError({\n actual: error instanceof Error ? error.message : String(error),\n context: 'configurePayloadConfig',\n expected: 'Successful file transformation',\n technicalDetails: error instanceof Error ? error.stack || error.message : String(error),\n }),\n success: false,\n }\n }\n}\n"],"names":["execSync","path","Project","QuoteKind","SyntaxKind","debug","DB_ADAPTER_CONFIG","STORAGE_ADAPTER_CONFIG","addImportDeclaration","cleanupOrphanedImports","formatError","removeImportDeclaration","detectPayloadConfigStructure","sourceFile","getFilePath","payloadImport","getImportDeclarations","find","imp","getModuleSpecifierValue","buildConfigImportSpec","getNamedImports","spec","getName","aliasNode","getAliasNode","buildConfigName","getText","buildConfigCall","getDescendantsOfKind","CallExpression","call","expression","getExpression","error","actual","context","expected","technicalDetails","success","importStatements","length","configObject","getArguments","dbProperty","getKind","ObjectLiteralExpression","asKindOrThrow","getProperty","asKind","PropertyAssignment","pluginsArray","objLiteral","pluginsProperty","propertyAssignment","initializer","getInitializer","ArrayLiteralExpression","allBuildConfigCalls","filter","hasImportAlias","payloadImports","hasOtherPayloadImports","some","dbAdapterImportInfo","config","Object","entries","importDecl","packageName","namedImports","hasOtherImports","importDeclaration","storageAdapterImports","adapterName","push","needsManualIntervention","edgeCases","multipleBuildConfigCalls","importSources","dbAdapter","storageAdapters","undefined","structures","addDatabaseAdapter","adapter","envVarName","modifications","detection","modified","oldAdapters","values","removedAdapters","importInsertIndex","forEach","oldConfig","removedIndex","moduleSpecifier","type","description","join","insertIndex","defaultImport","newDbCode","configTemplate","replaceWithText","getProperties","insertPropertyAssignment","name","addStorageAdapter","pluginsPropertyRaw","shorthandProperty","ShorthandPropertyAssignment","identifierName","allProperties","indexOf","remove","addPropertyAssignment","configText","addElement","removeSharp","warnings","sharpProperty","removeCommentMarkers","text","getFullText","replace","validateStructure","writeTransformedFile","options","formatWithPrettier","shouldValidate","validation","filePath","formatText","save","projectDir","dirname","prettierCmd","cwd","stdio","Error","message","configurePayloadConfig","db","storage","allModifications","allWarnings","project","manipulationSettings","quoteKind","Single","addSourceFileAtPath","result","cleanup","importNames","removed","importName","mod","warning","String","stack"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
1
2
|
import { Project } from 'ts-morph';
|
|
2
3
|
import { addDatabaseAdapter, addStorageAdapter, detectPayloadConfigStructure, removeSharp } from './payload-config';
|
|
3
4
|
import * as fs from 'fs';
|
|
@@ -112,7 +113,7 @@ export default buildConfig({
|
|
|
112
113
|
const result = addDatabaseAdapter({
|
|
113
114
|
sourceFile,
|
|
114
115
|
adapter,
|
|
115
|
-
envVarName: '
|
|
116
|
+
envVarName: 'DATABASE_URL'
|
|
116
117
|
});
|
|
117
118
|
expect(result.success).toBe(true);
|
|
118
119
|
expect(result.modified).toBe(true);
|
|
@@ -120,7 +121,7 @@ export default buildConfig({
|
|
|
120
121
|
const text = sourceFile.getText();
|
|
121
122
|
expect(text).toMatch(new RegExp(`import.*${adapterName}.*from.*${packageName.replace('/', '\\/')}`));
|
|
122
123
|
expect(text).toContain(`db: ${adapterName}`);
|
|
123
|
-
expect(text).toContain('process.env.
|
|
124
|
+
expect(text).toContain('process.env.DATABASE_URL');
|
|
124
125
|
});
|
|
125
126
|
it('replaces existing db adapter', ()=>{
|
|
126
127
|
const project = new Project({
|
|
@@ -136,7 +137,7 @@ export default buildConfig({
|
|
|
136
137
|
const result = addDatabaseAdapter({
|
|
137
138
|
sourceFile,
|
|
138
139
|
adapter: 'postgres',
|
|
139
|
-
envVarName: '
|
|
140
|
+
envVarName: 'DATABASE_URL'
|
|
140
141
|
});
|
|
141
142
|
expect(result.success).toBe(true);
|
|
142
143
|
const text = sourceFile.getText();
|
|
@@ -341,7 +342,7 @@ export default buildConfig({
|
|
|
341
342
|
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
|
342
343
|
|
|
343
344
|
export default buildConfig({
|
|
344
|
-
db: mongooseAdapter({ url: process.env.
|
|
345
|
+
db: mongooseAdapter({ url: process.env.DATABASE_URL || '' }),
|
|
345
346
|
collections: []
|
|
346
347
|
})`);
|
|
347
348
|
const { configurePayloadConfig } = await import('./payload-config');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/ast/payload-config.spec.ts"],"sourcesContent":["import { Project } from 'ts-morph'\nimport {\n addDatabaseAdapter,\n addStorageAdapter,\n detectPayloadConfigStructure,\n removeSharp,\n} from './payload-config'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\ndescribe('detectPayloadConfigStructure', () => {\n it('successfully detects buildConfig call', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n plugins: []\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('fails when buildConfig call not found', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('payload.config.ts', `export default {}`)\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(false)\n expect(result.error?.userMessage).toContain('buildConfig')\n expect(result.error?.technicalDetails).toContain('CallExpression')\n })\n\n it('detects buildConfig in variable declaration', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nconst config = buildConfig({\n db: mongooseAdapter({ url: '' })\n})\n\nexport default config`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('detects import alias edge case', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig as createConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default createConfig({\n db: mongooseAdapter({ url: '' }),\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.hasImportAlias).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('detects multiple buildConfig calls', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nconst helper = buildConfig({ collections: [] })\n\nexport default buildConfig({\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.multipleBuildConfigCalls).toBe(true)\n })\n\n it('detects other Payload imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig, CollectionConfig } from 'payload'\n\nexport default buildConfig({\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.hasOtherPayloadImports).toBe(true)\n })\n})\n\ndescribe('addDatabaseAdapter', () => {\n it.each([\n {\n adapter: 'mongodb' as const,\n adapterName: 'mongooseAdapter',\n packageName: '@payloadcms/db-mongodb',\n },\n {\n adapter: 'postgres' as const,\n adapterName: 'postgresAdapter',\n packageName: '@payloadcms/db-postgres',\n },\n ])('adds $adapter adapter with import and config', ({ adapter, adapterName, packageName }) => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = addDatabaseAdapter({\n sourceFile,\n adapter,\n envVarName: 'DATABASE_URI',\n })\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n expect(result.modifications.length).toBeGreaterThan(0)\n\n const text = sourceFile.getText()\n expect(text).toMatch(\n new RegExp(`import.*${adapterName}.*from.*${packageName.replace('/', '\\\\/')}`),\n )\n expect(text).toContain(`db: ${adapterName}`)\n expect(text).toContain('process.env.DATABASE_URI')\n })\n\n it('replaces existing db adapter', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n collections: []\n})`,\n )\n\n const result = addDatabaseAdapter({\n sourceFile,\n adapter: 'postgres',\n envVarName: 'DATABASE_URI',\n })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toMatch(/import.*postgresAdapter.*from.*@payloadcms\\/db-postgres/)\n expect(text).toContain('db: postgresAdapter')\n expect(text).not.toContain('mongooseAdapter')\n expect(text).not.toContain('@payloadcms/db-mongodb')\n })\n})\n\ndescribe('addStorageAdapter', () => {\n it('adds vercelBlobStorage adapter to plugins array', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n plugins: []\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 'vercelBlobStorage' })\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n const text = sourceFile.getText()\n expect(text).toMatch(/import.*vercelBlobStorage.*from.*@payloadcms\\/storage-vercel-blob/)\n expect(text).toContain('vercelBlobStorage(')\n })\n\n it('creates plugins array if missing', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 'r2Storage' })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toContain('plugins: [')\n expect(text).toContain('r2Storage(')\n })\n\n it('adds to existing plugins array', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n plugins: [\n someOtherPlugin()\n ]\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 's3Storage' })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toContain('someOtherPlugin()')\n expect(text).toContain('s3Storage(')\n })\n})\n\ndescribe('removeSharp', () => {\n it('removes sharp import and property', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'\n\nexport default buildConfig({\n sharp,\n collections: []\n})`,\n )\n\n const result = removeSharp(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n expect(result.modifications.length).toBeGreaterThan(0)\n const text = sourceFile.getText()\n expect(text).not.toContain(\"import sharp from 'sharp'\")\n expect(text).not.toContain('sharp,')\n })\n\n it('does nothing if sharp not present', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = removeSharp(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(false)\n })\n})\n\ndescribe('configurePayloadConfig', () => {\n let tempDir: string\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-test-'))\n })\n\n afterEach(() => {\n fs.rmSync(tempDir, { recursive: true, force: true })\n })\n\n it('applies all transformations in one call (db + storage)', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n storage: 'vercelBlobStorage',\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('postgresAdapter')\n expect(content).toContain('vercelBlobStorage')\n expect(content).toContain('DATABASE_URL')\n })\n\n it('applies db transformation only', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'mongodb', envVarName: 'MONGO_URL' },\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('mongooseAdapter')\n expect(content).toContain('MONGO_URL')\n })\n\n it('applies removeSharp transformation', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n sharp,\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n removeSharp: true,\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).not.toContain(\"import sharp from 'sharp'\")\n expect(content).not.toContain('sharp,')\n })\n\n it('handles transformation errors gracefully', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `export default {}`, // Invalid structure\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(false)\n expect(result.error?.userMessage).toContain('buildConfig')\n })\n\n it('handles file not found error', async () => {\n const filePath = path.join(tempDir, 'nonexistent.ts')\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(false)\n expect(result.error).toBeDefined()\n })\n\n it('replaces adapter in config file', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: process.env.DATABASE_URI || '' }),\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(true)\n\n // Verify config was updated\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('postgresAdapter')\n expect(content).toContain('@payloadcms/db-postgres')\n expect(content).not.toContain('mongooseAdapter')\n expect(content).not.toContain('@payloadcms/db-mongodb')\n })\n})\n"],"names":["Project","addDatabaseAdapter","addStorageAdapter","detectPayloadConfigStructure","removeSharp","fs","path","os","describe","it","project","useInMemoryFileSystem","sourceFile","createSourceFile","result","expect","success","toBe","structures","buildConfigCall","toBeDefined","error","userMessage","toContain","technicalDetails","edgeCases","hasImportAlias","multipleBuildConfigCalls","hasOtherPayloadImports","each","adapter","adapterName","packageName","envVarName","modified","modifications","length","toBeGreaterThan","text","getText","toMatch","RegExp","replace","not","tempDir","beforeEach","mkdtempSync","join","tmpdir","afterEach","rmSync","recursive","force","filePath","writeFileSync","configurePayloadConfig","db","type","storage","content","readFileSync"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/ast/payload-config.spec.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, afterEach } from 'vitest'\nimport { Project } from 'ts-morph'\nimport {\n addDatabaseAdapter,\n addStorageAdapter,\n detectPayloadConfigStructure,\n removeSharp,\n} from './payload-config'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\n\ndescribe('detectPayloadConfigStructure', () => {\n it('successfully detects buildConfig call', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n plugins: []\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('fails when buildConfig call not found', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('payload.config.ts', `export default {}`)\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(false)\n expect(result.error?.userMessage).toContain('buildConfig')\n expect(result.error?.technicalDetails).toContain('CallExpression')\n })\n\n it('detects buildConfig in variable declaration', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nconst config = buildConfig({\n db: mongooseAdapter({ url: '' })\n})\n\nexport default config`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('detects import alias edge case', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig as createConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default createConfig({\n db: mongooseAdapter({ url: '' }),\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.hasImportAlias).toBe(true)\n expect(result.structures?.buildConfigCall).toBeDefined()\n })\n\n it('detects multiple buildConfig calls', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nconst helper = buildConfig({ collections: [] })\n\nexport default buildConfig({\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.multipleBuildConfigCalls).toBe(true)\n })\n\n it('detects other Payload imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig, CollectionConfig } from 'payload'\n\nexport default buildConfig({\n collections: [],\n})`,\n )\n\n const result = detectPayloadConfigStructure(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.edgeCases?.hasOtherPayloadImports).toBe(true)\n })\n})\n\ndescribe('addDatabaseAdapter', () => {\n it.each([\n {\n adapter: 'mongodb' as const,\n adapterName: 'mongooseAdapter',\n packageName: '@payloadcms/db-mongodb',\n },\n {\n adapter: 'postgres' as const,\n adapterName: 'postgresAdapter',\n packageName: '@payloadcms/db-postgres',\n },\n ])('adds $adapter adapter with import and config', ({ adapter, adapterName, packageName }) => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = addDatabaseAdapter({\n sourceFile,\n adapter,\n envVarName: 'DATABASE_URL',\n })\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n expect(result.modifications.length).toBeGreaterThan(0)\n\n const text = sourceFile.getText()\n expect(text).toMatch(\n new RegExp(`import.*${adapterName}.*from.*${packageName.replace('/', '\\\\/')}`),\n )\n expect(text).toContain(`db: ${adapterName}`)\n expect(text).toContain('process.env.DATABASE_URL')\n })\n\n it('replaces existing db adapter', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n collections: []\n})`,\n )\n\n const result = addDatabaseAdapter({\n sourceFile,\n adapter: 'postgres',\n envVarName: 'DATABASE_URL',\n })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toMatch(/import.*postgresAdapter.*from.*@payloadcms\\/db-postgres/)\n expect(text).toContain('db: postgresAdapter')\n expect(text).not.toContain('mongooseAdapter')\n expect(text).not.toContain('@payloadcms/db-mongodb')\n })\n})\n\ndescribe('addStorageAdapter', () => {\n it('adds vercelBlobStorage adapter to plugins array', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n plugins: []\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 'vercelBlobStorage' })\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n const text = sourceFile.getText()\n expect(text).toMatch(/import.*vercelBlobStorage.*from.*@payloadcms\\/storage-vercel-blob/)\n expect(text).toContain('vercelBlobStorage(')\n })\n\n it('creates plugins array if missing', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 'r2Storage' })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toContain('plugins: [')\n expect(text).toContain('r2Storage(')\n })\n\n it('adds to existing plugins array', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n plugins: [\n someOtherPlugin()\n ]\n})`,\n )\n\n const result = addStorageAdapter({ sourceFile, adapter: 's3Storage' })\n\n expect(result.success).toBe(true)\n const text = sourceFile.getText()\n expect(text).toContain('someOtherPlugin()')\n expect(text).toContain('s3Storage(')\n })\n})\n\ndescribe('removeSharp', () => {\n it('removes sharp import and property', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'\n\nexport default buildConfig({\n sharp,\n collections: []\n})`,\n )\n\n const result = removeSharp(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(true)\n expect(result.modifications.length).toBeGreaterThan(0)\n const text = sourceFile.getText()\n expect(text).not.toContain(\"import sharp from 'sharp'\")\n expect(text).not.toContain('sharp,')\n })\n\n it('does nothing if sharp not present', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'payload.config.ts',\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const result = removeSharp(sourceFile)\n\n expect(result.success).toBe(true)\n expect(result.modified).toBe(false)\n })\n})\n\ndescribe('configurePayloadConfig', () => {\n let tempDir: string\n\n beforeEach(() => {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'payload-test-'))\n })\n\n afterEach(() => {\n fs.rmSync(tempDir, { recursive: true, force: true })\n })\n\n it('applies all transformations in one call (db + storage)', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n storage: 'vercelBlobStorage',\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('postgresAdapter')\n expect(content).toContain('vercelBlobStorage')\n expect(content).toContain('DATABASE_URL')\n })\n\n it('applies db transformation only', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'mongodb', envVarName: 'MONGO_URL' },\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('mongooseAdapter')\n expect(content).toContain('MONGO_URL')\n })\n\n it('applies removeSharp transformation', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' }),\n sharp,\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n removeSharp: true,\n })\n\n expect(result.success).toBe(true)\n\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).not.toContain(\"import sharp from 'sharp'\")\n expect(content).not.toContain('sharp,')\n })\n\n it('handles transformation errors gracefully', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `export default {}`, // Invalid structure\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(false)\n expect(result.error?.userMessage).toContain('buildConfig')\n })\n\n it('handles file not found error', async () => {\n const filePath = path.join(tempDir, 'nonexistent.ts')\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(false)\n expect(result.error).toBeDefined()\n })\n\n it('replaces adapter in config file', async () => {\n const filePath = path.join(tempDir, 'payload.config.ts')\n fs.writeFileSync(\n filePath,\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: process.env.DATABASE_URL || '' }),\n collections: []\n})`,\n )\n\n const { configurePayloadConfig } = await import('./payload-config')\n const result = await configurePayloadConfig(filePath, {\n db: { type: 'postgres', envVarName: 'DATABASE_URL' },\n })\n\n expect(result.success).toBe(true)\n\n // Verify config was updated\n const content = fs.readFileSync(filePath, 'utf-8')\n expect(content).toContain('postgresAdapter')\n expect(content).toContain('@payloadcms/db-postgres')\n expect(content).not.toContain('mongooseAdapter')\n expect(content).not.toContain('@payloadcms/db-mongodb')\n })\n})\n"],"names":["describe","it","expect","beforeEach","afterEach","Project","addDatabaseAdapter","addStorageAdapter","detectPayloadConfigStructure","removeSharp","fs","path","os","project","useInMemoryFileSystem","sourceFile","createSourceFile","result","success","toBe","structures","buildConfigCall","toBeDefined","error","userMessage","toContain","technicalDetails","edgeCases","hasImportAlias","multipleBuildConfigCalls","hasOtherPayloadImports","each","adapter","adapterName","packageName","envVarName","modified","modifications","length","toBeGreaterThan","text","getText","toMatch","RegExp","replace","not","tempDir","mkdtempSync","join","tmpdir","rmSync","recursive","force","filePath","writeFileSync","configurePayloadConfig","db","type","storage","content","readFileSync"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
1
2
|
import { Project } from 'ts-morph';
|
|
2
3
|
import { addImportDeclaration, cleanupOrphanedImports, findImportDeclaration, isNamedImportUsed, removeImportDeclaration, removeNamedImports } from './utils';
|
|
3
4
|
describe('findImportDeclaration', ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/ast/utils.spec.ts"],"sourcesContent":["import { Project } from 'ts-morph'\nimport {\n addImportDeclaration,\n cleanupOrphanedImports,\n findImportDeclaration,\n isNamedImportUsed,\n removeImportDeclaration,\n removeNamedImports,\n} from './utils'\n\ndescribe('findImportDeclaration', () => {\n it('finds import by module specifier', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const result = findImportDeclaration({ sourceFile, moduleSpecifier: '@payloadcms/db-mongodb' })\n\n expect(result).toBeDefined()\n expect(result?.getModuleSpecifierValue()).toBe('@payloadcms/db-mongodb')\n })\n})\n\ndescribe('addImportDeclaration', () => {\n it('adds new import when not present', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-postgres',\n namedImports: ['postgresAdapter'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(2)\n expect(imports[1].getModuleSpecifierValue()).toBe('@payloadcms/db-postgres')\n expect(imports[1].getNamedImports()[0].getName()).toBe('postgresAdapter')\n })\n\n it('does not duplicate existing import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n namedImports: ['mongooseAdapter'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(1)\n })\n\n it('adds named import to existing module import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: 'payload',\n namedImports: ['Field'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(1)\n const namedImports = imports[0].getNamedImports().map((ni) => ni.getName())\n expect(namedImports).toContain('buildConfig')\n expect(namedImports).toContain('Field')\n })\n})\n\ndescribe('removeImportDeclaration', () => {\n it('removes import by module specifier', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'`,\n )\n\n const result = removeImportDeclaration({ sourceFile, moduleSpecifier: 'sharp' })\n\n expect(result.removedIndex).toBe(1)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('payload')\n })\n\n it('returns undefined removedIndex when import not found', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = removeImportDeclaration({ sourceFile, moduleSpecifier: 'sharp' })\n\n expect(result.removedIndex).toBeUndefined()\n })\n})\n\ndescribe('removeNamedImports', () => {\n it('removes specific named imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter, SomeOtherType } from '@payloadcms/db-mongodb'`,\n )\n\n const importDecl = findImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n })!\n\n const result = removeNamedImports({\n sourceFile,\n importDeclaration: importDecl,\n namedImportsToRemove: ['mongooseAdapter'],\n })\n\n expect(result.fullyRemoved).toBe(false)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n const namedImports = imports[0].getNamedImports().map((ni) => ni.getName())\n expect(namedImports).toEqual(['SomeOtherType'])\n })\n\n it('removes entire import when no named imports remain', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const importDecl = findImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n })!\n\n const result = removeNamedImports({\n sourceFile,\n importDeclaration: importDecl,\n namedImportsToRemove: ['mongooseAdapter'],\n })\n\n expect(result.fullyRemoved).toBe(true)\n expect(result.index).toBe(1)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('payload')\n })\n})\n\ndescribe('isNamedImportUsed', () => {\n it('detects used import in code', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' })\n})`,\n )\n\n const isUsed = isNamedImportUsed(sourceFile, 'mongooseAdapter')\n\n expect(isUsed).toBe(true)\n })\n\n it('detects unused import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\n\nexport default buildConfig({\n db: postgresAdapter({ url: '' })\n})`,\n )\n\n const isUsed = isNamedImportUsed(sourceFile, 'mongooseAdapter')\n\n expect(isUsed).toBe(false)\n })\n})\n\ndescribe('cleanupOrphanedImports', () => {\n it('removes unused imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\n\nexport default buildConfig({\n db: postgresAdapter({ url: '' })\n})`,\n )\n\n const result = cleanupOrphanedImports({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n importNames: ['mongooseAdapter'],\n })\n\n expect(result.removed).toEqual(['mongooseAdapter'])\n expect(result.kept).toEqual([])\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('@payloadcms/db-postgres')\n })\n\n it('keeps used imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' })\n})`,\n )\n\n const result = cleanupOrphanedImports({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n importNames: ['mongooseAdapter'],\n })\n\n expect(result.removed).toEqual([])\n expect(result.kept).toEqual(['mongooseAdapter'])\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n })\n})\n"],"names":["Project","addImportDeclaration","cleanupOrphanedImports","findImportDeclaration","isNamedImportUsed","removeImportDeclaration","removeNamedImports","describe","it","project","useInMemoryFileSystem","sourceFile","createSourceFile","result","moduleSpecifier","expect","toBeDefined","getModuleSpecifierValue","toBe","namedImports","imports","getImportDeclarations","toHaveLength","getNamedImports","getName","map","ni","toContain","removedIndex","toBeUndefined","importDecl","importDeclaration","namedImportsToRemove","fullyRemoved","toEqual","index","isUsed","importNames","removed","kept"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/ast/utils.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport { Project } from 'ts-morph'\nimport {\n addImportDeclaration,\n cleanupOrphanedImports,\n findImportDeclaration,\n isNamedImportUsed,\n removeImportDeclaration,\n removeNamedImports,\n} from './utils'\n\ndescribe('findImportDeclaration', () => {\n it('finds import by module specifier', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const result = findImportDeclaration({ sourceFile, moduleSpecifier: '@payloadcms/db-mongodb' })\n\n expect(result).toBeDefined()\n expect(result?.getModuleSpecifierValue()).toBe('@payloadcms/db-mongodb')\n })\n})\n\ndescribe('addImportDeclaration', () => {\n it('adds new import when not present', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-postgres',\n namedImports: ['postgresAdapter'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(2)\n expect(imports[1].getModuleSpecifierValue()).toBe('@payloadcms/db-postgres')\n expect(imports[1].getNamedImports()[0].getName()).toBe('postgresAdapter')\n })\n\n it('does not duplicate existing import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n namedImports: ['mongooseAdapter'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(1)\n })\n\n it('adds named import to existing module import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = addImportDeclaration({\n sourceFile,\n moduleSpecifier: 'payload',\n namedImports: ['Field'],\n })\n\n const imports = result.getImportDeclarations()\n expect(imports).toHaveLength(1)\n const namedImports = imports[0].getNamedImports().map((ni) => ni.getName())\n expect(namedImports).toContain('buildConfig')\n expect(namedImports).toContain('Field')\n })\n})\n\ndescribe('removeImportDeclaration', () => {\n it('removes import by module specifier', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport sharp from 'sharp'`,\n )\n\n const result = removeImportDeclaration({ sourceFile, moduleSpecifier: 'sharp' })\n\n expect(result.removedIndex).toBe(1)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('payload')\n })\n\n it('returns undefined removedIndex when import not found', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('test.ts', `import { buildConfig } from 'payload'`)\n\n const result = removeImportDeclaration({ sourceFile, moduleSpecifier: 'sharp' })\n\n expect(result.removedIndex).toBeUndefined()\n })\n})\n\ndescribe('removeNamedImports', () => {\n it('removes specific named imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter, SomeOtherType } from '@payloadcms/db-mongodb'`,\n )\n\n const importDecl = findImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n })!\n\n const result = removeNamedImports({\n sourceFile,\n importDeclaration: importDecl,\n namedImportsToRemove: ['mongooseAdapter'],\n })\n\n expect(result.fullyRemoved).toBe(false)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n const namedImports = imports[0].getNamedImports().map((ni) => ni.getName())\n expect(namedImports).toEqual(['SomeOtherType'])\n })\n\n it('removes entire import when no named imports remain', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { buildConfig } from 'payload'\nimport { mongooseAdapter } from '@payloadcms/db-mongodb'`,\n )\n\n const importDecl = findImportDeclaration({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n })!\n\n const result = removeNamedImports({\n sourceFile,\n importDeclaration: importDecl,\n namedImportsToRemove: ['mongooseAdapter'],\n })\n\n expect(result.fullyRemoved).toBe(true)\n expect(result.index).toBe(1)\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('payload')\n })\n})\n\ndescribe('isNamedImportUsed', () => {\n it('detects used import in code', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' })\n})`,\n )\n\n const isUsed = isNamedImportUsed(sourceFile, 'mongooseAdapter')\n\n expect(isUsed).toBe(true)\n })\n\n it('detects unused import', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\n\nexport default buildConfig({\n db: postgresAdapter({ url: '' })\n})`,\n )\n\n const isUsed = isNamedImportUsed(sourceFile, 'mongooseAdapter')\n\n expect(isUsed).toBe(false)\n })\n})\n\ndescribe('cleanupOrphanedImports', () => {\n it('removes unused imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\n\nexport default buildConfig({\n db: postgresAdapter({ url: '' })\n})`,\n )\n\n const result = cleanupOrphanedImports({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n importNames: ['mongooseAdapter'],\n })\n\n expect(result.removed).toEqual(['mongooseAdapter'])\n expect(result.kept).toEqual([])\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n expect(imports[0].getModuleSpecifierValue()).toBe('@payloadcms/db-postgres')\n })\n\n it('keeps used imports', () => {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile(\n 'test.ts',\n `import { mongooseAdapter } from '@payloadcms/db-mongodb'\n\nexport default buildConfig({\n db: mongooseAdapter({ url: '' })\n})`,\n )\n\n const result = cleanupOrphanedImports({\n sourceFile,\n moduleSpecifier: '@payloadcms/db-mongodb',\n importNames: ['mongooseAdapter'],\n })\n\n expect(result.removed).toEqual([])\n expect(result.kept).toEqual(['mongooseAdapter'])\n const imports = result.sourceFile.getImportDeclarations()\n expect(imports).toHaveLength(1)\n })\n})\n"],"names":["describe","it","expect","Project","addImportDeclaration","cleanupOrphanedImports","findImportDeclaration","isNamedImportUsed","removeImportDeclaration","removeNamedImports","project","useInMemoryFileSystem","sourceFile","createSourceFile","result","moduleSpecifier","toBeDefined","getModuleSpecifierValue","toBe","namedImports","imports","getImportDeclarations","toHaveLength","getNamedImports","getName","map","ni","toContain","removedIndex","toBeUndefined","importDecl","importDeclaration","namedImportsToRemove","fullyRemoved","toEqual","index","isUsed","importNames","removed","kept"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ import { configurePayloadConfig as configurePayloadConfigAST } from './ast/paylo
|
|
|
12
12
|
if (dbType === 'vercel-postgres') {
|
|
13
13
|
return 'POSTGRES_URL';
|
|
14
14
|
}
|
|
15
|
-
return '
|
|
15
|
+
return 'DATABASE_URL';
|
|
16
16
|
}
|
|
17
17
|
/** Update payload config with necessary imports and adapters */ export async function configurePayloadConfig(args) {
|
|
18
18
|
if (!args.dbType) {
|
|
@@ -1 +1 @@
|
|
|
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 { updatePackageJson } from './ast/package-json.js'\nimport { configurePayloadConfig as configurePayloadConfigAST } from './ast/payload-config.js'\n\n/** Get default env var name for db type */\nfunction getEnvVarName(dbType: DbType, customEnvName?: string): string {\n if (customEnvName) {\n return customEnvName\n }\n // Default env var names per adapter type\n if (dbType === 'vercel-postgres') {\n return 'POSTGRES_URL'\n }\n return '
|
|
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 { updatePackageJson } from './ast/package-json.js'\nimport { configurePayloadConfig as configurePayloadConfigAST } from './ast/payload-config.js'\n\n/** Get default env var name for db type */\nfunction getEnvVarName(dbType: DbType, customEnvName?: string): string {\n if (customEnvName) {\n return customEnvName\n }\n // Default env var names per adapter type\n if (dbType === 'vercel-postgres') {\n return 'POSTGRES_URL'\n }\n return 'DATABASE_URL'\n}\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 updatePackageJson(packageJsonPath, {\n databaseAdapter: args.dbType,\n packageName: args.packageJsonName,\n removeSharp: args.sharp === false,\n storageAdapter: args.storageAdapter,\n })\n } catch (err: unknown) {\n warning(`Unable to configure Payload in package.json`)\n warning(err instanceof Error ? err.message : '')\n }\n }\n\n // Update payload.config.ts\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 envVarName = getEnvVarName(args.dbType, args.envNames?.dbUri)\n\n const result = await configurePayloadConfigAST(payloadConfigPath, {\n db: {\n type: args.dbType,\n envVarName,\n },\n formatWithPrettier: true,\n removeSharp: args.sharp === false,\n storage: args.storageAdapter,\n validateStructure: false,\n })\n\n if (!result.success && result.error) {\n warning(`Unable to update payload.config.ts: ${result.error.userMessage}`)\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","path","warning","updatePackageJson","configurePayloadConfig","configurePayloadConfigAST","getEnvVarName","dbType","customEnvName","args","packageJsonPath","projectDirOrConfigPath","resolve","projectDir","existsSync","databaseAdapter","packageName","packageJsonName","removeSharp","sharp","storageAdapter","err","Error","message","payloadConfigPath","absolute","cwd","envVarName","envNames","dbUri","result","db","type","formatWithPrettier","storage","validateStructure","success","error","userMessage"],"mappings":"AAAA,OAAOA,SAAS,WAAU;AAC1B,OAAOC,YAAY,SAAQ;AAC3B,OAAOC,UAAU,OAAM;AAIvB,SAASC,OAAO,QAAQ,kBAAiB;AACzC,SAASC,iBAAiB,QAAQ,wBAAuB;AACzD,SAASC,0BAA0BC,yBAAyB,QAAQ,0BAAyB;AAE7F,yCAAyC,GACzC,SAASC,cAAcC,MAAc,EAAEC,aAAsB;IAC3D,IAAIA,eAAe;QACjB,OAAOA;IACT;IACA,yCAAyC;IACzC,IAAID,WAAW,mBAAmB;QAChC,OAAO;IACT;IACA,OAAO;AACT;AAEA,8DAA8D,GAC9D,OAAO,eAAeH,uBAAuBK,IAS5C;IACC,IAAI,CAACA,KAAKF,MAAM,EAAE;QAChB;IACF;IAEA,sBAAsB;IACtB,MAAMG,kBACJ,gBAAgBD,KAAKE,sBAAsB,IAC3CV,KAAKW,OAAO,CAACH,KAAKE,sBAAsB,CAACE,UAAU,EAAE;IAEvD,IAAIH,mBAAmBX,IAAIe,UAAU,CAACJ,kBAAkB;QACtD,IAAI;YACFP,kBAAkBO,iBAAiB;gBACjCK,iBAAiBN,KAAKF,MAAM;gBAC5BS,aAAaP,KAAKQ,eAAe;gBACjCC,aAAaT,KAAKU,KAAK,KAAK;gBAC5BC,gBAAgBX,KAAKW,cAAc;YACrC;QACF,EAAE,OAAOC,KAAc;YACrBnB,QAAQ,CAAC,2CAA2C,CAAC;YACrDA,QAAQmB,eAAeC,QAAQD,IAAIE,OAAO,GAAG;QAC/C;IACF;IAEA,2BAA2B;IAC3B,IAAI;QACF,IAAIC;QACJ,IAAI,CAAE,CAAA,uBAAuBf,KAAKE,sBAAsB,AAAD,GAAI;YACzDa,oBACE,CAAA,MAAMxB,OAAO,wBAAwB;gBACnCyB,UAAU;gBACVC,KAAKjB,KAAKE,sBAAsB,CAACE,UAAU;YAC7C,EAAC,GACA,CAAC,EAAE;QACR,OAAO;YACLW,oBAAoBf,KAAKE,sBAAsB,CAACa,iBAAiB;QACnE;QAEA,IAAI,CAACA,mBAAmB;YACtBtB,QAAQ;YACR;QACF;QAEA,MAAMyB,aAAarB,cAAcG,KAAKF,MAAM,EAAEE,KAAKmB,QAAQ,EAAEC;QAE7D,MAAMC,SAAS,MAAMzB,0BAA0BmB,mBAAmB;YAChEO,IAAI;gBACFC,MAAMvB,KAAKF,MAAM;gBACjBoB;YACF;YACAM,oBAAoB;YACpBf,aAAaT,KAAKU,KAAK,KAAK;YAC5Be,SAASzB,KAAKW,cAAc;YAC5Be,mBAAmB;QACrB;QAEA,IAAI,CAACL,OAAOM,OAAO,IAAIN,OAAOO,KAAK,EAAE;YACnCnC,QAAQ,CAAC,oCAAoC,EAAE4B,OAAOO,KAAK,CAACC,WAAW,EAAE;QAC3E;IACF,EAAE,OAAOjB,KAAc;QACrBnB,QACE,CAAC,iDAAiD,EAAEmB,eAAeC,QAAQD,IAAIE,OAAO,GAAG,IAAI;IAEjG;AACF"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import fse from 'fs-extra';
|
|
4
3
|
import globby from 'globby';
|
|
5
4
|
import * as os from 'node:os';
|
|
6
5
|
import path from 'path';
|
|
6
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it, vitest } from 'vitest';
|
|
7
7
|
import { createProject, updatePackageJSONDependencies } from './create-project.js';
|
|
8
8
|
import { getValidTemplates } from './templates.js';
|
|
9
9
|
describe('createProject', ()=>{
|
|
10
10
|
let projectDir;
|
|
11
11
|
beforeAll(()=>{
|
|
12
12
|
// eslint-disable-next-line no-console
|
|
13
|
-
console.log =
|
|
13
|
+
console.log = vitest.fn();
|
|
14
14
|
});
|
|
15
15
|
beforeEach(()=>{
|
|
16
16
|
const tempDirectory = fs.realpathSync(os.tmpdir());
|
|
@@ -100,7 +100,7 @@ describe('createProject', ()=>{
|
|
|
100
100
|
const packageJson = fse.readJsonSync(packageJsonPath);
|
|
101
101
|
// Check package name and description
|
|
102
102
|
expect(packageJson.name).toStrictEqual(projectName);
|
|
103
|
-
});
|
|
103
|
+
}, 90_000);
|
|
104
104
|
describe('creates project from template', ()=>{
|
|
105
105
|
const templates = getValidTemplates();
|
|
106
106
|
it.each([
|
|
@@ -1 +1 @@
|
|
|
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, ProjectExample, ProjectTemplate } from '../types.js'\n\nimport { createProject, updatePackageJSONDependencies } from './create-project.js'\nimport { getValidTemplates } from './templates.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n\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/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\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 it('updates project name in plugin template importMap file', async () => {\n const projectName = 'my-custom-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/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n template,\n })\n\n const importMapPath = path.resolve(projectDir, './dev/app/(payload)/admin/importMap.js')\n const importMapFile = fse.readFileSync(importMapPath, 'utf-8')\n\n expect(importMapFile).not.toContain('plugin-package-name-placeholder')\n expect(importMapFile).toContain('my-custom-plugin')\n })\n\n it('creates example', async () => {\n const projectName = 'custom-server-example'\n const example: ProjectExample = {\n name: 'custom-server',\n url: 'https://github.com/payloadcms/payload/examples/custom-server#main',\n }\n\n await createProject({\n cliArgs: {\n ...args,\n '--local-template': undefined,\n '--local-example': 'custom-server',\n } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n example,\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 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 doesn't have placeholder comments\n expect(content).not.toContain('// database-adapter-import')\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n\n // Verify correct adapter import and usage based on db type\n if (db === 'mongodb') {\n expect(content).toContain(\"import { mongooseAdapter } from '@payloadcms/db-mongodb'\")\n expect(content).toContain('mongooseAdapter')\n } else if (db === 'postgres') {\n expect(content).toContain(\"import { postgresAdapter } from '@payloadcms/db-postgres'\")\n expect(content).toContain('postgresAdapter')\n }\n })\n })\n\n describe('updates package.json', () => {\n it('updates package name and bumps workspace versions', async () => {\n const latestVersion = '3.0.0'\n const initialJSON = {\n name: 'test-project',\n version: '1.0.0',\n dependencies: {\n '@payloadcms/db-mongodb': 'workspace:*',\n payload: 'workspace:*',\n '@payloadcms/ui': 'workspace:*',\n },\n }\n\n const correctlyModifiedJSON = {\n name: 'test-project',\n version: '1.0.0',\n dependencies: {\n '@payloadcms/db-mongodb': `${latestVersion}`,\n payload: `${latestVersion}`,\n '@payloadcms/ui': `${latestVersion}`,\n },\n }\n\n updatePackageJSONDependencies({\n latestVersion,\n packageJson: initialJSON,\n })\n\n expect(initialJSON).toEqual(correctlyModifiedJSON)\n })\n })\n })\n})\n"],"names":["jest","fs","fse","globby","os","path","createProject","updatePackageJSONDependencies","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","importMapPath","importMapFile","readFileSync","not","toContain","example","undefined","templates","each","templateName","db","find","t","dbDetails","dbUri","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","content","latestVersion","initialJSON","version","payload","correctlyModifiedJSON","toEqual"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/create-project.spec.ts"],"sourcesContent":["import fs from 'fs'\nimport fse from 'fs-extra'\nimport globby from 'globby'\nimport * as os from 'node:os'\nimport path from 'path'\nimport { afterEach, beforeAll, beforeEach, describe, expect, it, vitest } from 'vitest'\nimport type { CliArgs, DbType, ProjectExample, ProjectTemplate } from '../types.js'\n\nimport { createProject, updatePackageJSONDependencies } from './create-project.js'\nimport { getValidTemplates } from './templates.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n\n beforeAll(() => {\n // eslint-disable-next-line no-console\n console.log = vitest.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/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\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 it('updates project name in plugin template importMap file', async () => {\n const projectName = 'my-custom-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/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n template,\n })\n\n const importMapPath = path.resolve(projectDir, './dev/app/(payload)/admin/importMap.js')\n const importMapFile = fse.readFileSync(importMapPath, 'utf-8')\n\n expect(importMapFile).not.toContain('plugin-package-name-placeholder')\n expect(importMapFile).toContain('my-custom-plugin')\n })\n\n it('creates example', async () => {\n const projectName = 'custom-server-example'\n const example: ProjectExample = {\n name: 'custom-server',\n url: 'https://github.com/payloadcms/payload/examples/custom-server#main',\n }\n\n await createProject({\n cliArgs: {\n ...args,\n '--local-template': undefined,\n '--local-example': 'custom-server',\n } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n example,\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 }, 90_000)\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 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 doesn't have placeholder comments\n expect(content).not.toContain('// database-adapter-import')\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n\n // Verify correct adapter import and usage based on db type\n if (db === 'mongodb') {\n expect(content).toContain(\"import { mongooseAdapter } from '@payloadcms/db-mongodb'\")\n expect(content).toContain('mongooseAdapter')\n } else if (db === 'postgres') {\n expect(content).toContain(\"import { postgresAdapter } from '@payloadcms/db-postgres'\")\n expect(content).toContain('postgresAdapter')\n }\n })\n })\n\n describe('updates package.json', () => {\n it('updates package name and bumps workspace versions', async () => {\n const latestVersion = '3.0.0'\n const initialJSON = {\n name: 'test-project',\n version: '1.0.0',\n dependencies: {\n '@payloadcms/db-mongodb': 'workspace:*',\n payload: 'workspace:*',\n '@payloadcms/ui': 'workspace:*',\n },\n }\n\n const correctlyModifiedJSON = {\n name: 'test-project',\n version: '1.0.0',\n dependencies: {\n '@payloadcms/db-mongodb': `${latestVersion}`,\n payload: `${latestVersion}`,\n '@payloadcms/ui': `${latestVersion}`,\n },\n }\n\n updatePackageJSONDependencies({\n latestVersion,\n packageJson: initialJSON,\n })\n\n expect(initialJSON).toEqual(correctlyModifiedJSON)\n })\n })\n })\n})\n"],"names":["fs","fse","globby","os","path","afterEach","beforeAll","beforeEach","describe","expect","it","vitest","createProject","updatePackageJSONDependencies","getValidTemplates","projectDir","console","log","fn","tempDirectory","realpathSync","tmpdir","Math","random","toString","substring","existsSync","rmSync","recursive","args","_","packageManager","projectName","template","name","type","description","url","cliArgs","packageJsonPath","resolve","packageJson","readJsonSync","toStrictEqual","importMapPath","importMapFile","readFileSync","not","toContain","example","undefined","templates","each","templateName","db","find","t","dbDetails","dbUri","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","content","latestVersion","initialJSON","version","payload","correctlyModifiedJSON","toEqual"],"mappings":"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"}
|
|
@@ -6,8 +6,8 @@ const sanitizeEnv = ({ contents, databaseType, databaseUri, payloadSecret })=>{
|
|
|
6
6
|
const seenKeys = new Set();
|
|
7
7
|
// add defaults
|
|
8
8
|
let withDefaults = contents;
|
|
9
|
-
if (!contents.includes('
|
|
10
|
-
withDefaults += '\
|
|
9
|
+
if (!contents.includes('DATABASE_URL') && !contents.includes('POSTGRES_URL') && !contents.includes('MONGODB_URL') && databaseType !== 'd1-sqlite') {
|
|
10
|
+
withDefaults += '\nDATABASE_URL=your-connection-string-here';
|
|
11
11
|
}
|
|
12
12
|
if (!contents.includes('PAYLOAD_SECRET')) {
|
|
13
13
|
withDefaults += '\nPAYLOAD_SECRET=YOUR_SECRET_HERE';
|
|
@@ -20,11 +20,11 @@ const sanitizeEnv = ({ contents, databaseType, databaseUri, payloadSecret })=>{
|
|
|
20
20
|
if (!key) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
if (key === '
|
|
23
|
+
if (key === 'DATABASE_URL' || key === 'POSTGRES_URL' || key === 'MONGODB_URL') {
|
|
24
24
|
const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null;
|
|
25
25
|
if (dbChoice) {
|
|
26
26
|
const placeholderUri = databaseUri ? databaseUri : `${dbChoice.dbConnectionPrefix}your-database-name${dbChoice.dbConnectionSuffix || ''}`;
|
|
27
|
-
line = databaseType === 'vercel-postgres' ? `POSTGRES_URL=${placeholderUri}` : `
|
|
27
|
+
line = databaseType === 'vercel-postgres' ? `POSTGRES_URL=${placeholderUri}` : `DATABASE_URL=${placeholderUri}`;
|
|
28
28
|
} else {
|
|
29
29
|
line = `${key}=${value}`;
|
|
30
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/manage-env-files.ts"],"sourcesContent":["import fs from 'fs-extra'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\n\nimport { debug, error } from '../utils/log.js'\nimport { dbChoiceRecord } from './select-db.js'\n\nconst sanitizeEnv = ({\n contents,\n databaseType,\n databaseUri,\n payloadSecret,\n}: {\n contents: string\n databaseType: DbType | undefined\n databaseUri?: string\n payloadSecret?: string\n}): string => {\n const seenKeys = new Set<string>()\n\n // add defaults\n let withDefaults = contents\n\n if (\n !contents.includes('
|
|
1
|
+
{"version":3,"sources":["../../src/lib/manage-env-files.ts"],"sourcesContent":["import fs from 'fs-extra'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\n\nimport { debug, error } from '../utils/log.js'\nimport { dbChoiceRecord } from './select-db.js'\n\nconst sanitizeEnv = ({\n contents,\n databaseType,\n databaseUri,\n payloadSecret,\n}: {\n contents: string\n databaseType: DbType | undefined\n databaseUri?: string\n payloadSecret?: string\n}): string => {\n const seenKeys = new Set<string>()\n\n // add defaults\n let withDefaults = contents\n\n if (\n !contents.includes('DATABASE_URL') &&\n !contents.includes('POSTGRES_URL') &&\n !contents.includes('MONGODB_URL') &&\n databaseType !== 'd1-sqlite'\n ) {\n withDefaults += '\\nDATABASE_URL=your-connection-string-here'\n }\n\n if (!contents.includes('PAYLOAD_SECRET')) {\n withDefaults += '\\nPAYLOAD_SECRET=YOUR_SECRET_HERE'\n }\n\n let updatedEnv = withDefaults\n .split('\\n')\n .map((line) => {\n if (line.startsWith('#') || !line.includes('=')) {\n return line\n }\n\n const [key, value] = line.split('=')\n\n if (!key) {\n return\n }\n\n if (key === 'DATABASE_URL' || key === 'POSTGRES_URL' || key === 'MONGODB_URL') {\n const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null\n\n if (dbChoice) {\n const placeholderUri = databaseUri\n ? databaseUri\n : `${dbChoice.dbConnectionPrefix}your-database-name${dbChoice.dbConnectionSuffix || ''}`\n line =\n databaseType === 'vercel-postgres'\n ? `POSTGRES_URL=${placeholderUri}`\n : `DATABASE_URL=${placeholderUri}`\n } else {\n line = `${key}=${value}`\n }\n }\n\n if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {\n line = `PAYLOAD_SECRET=${payloadSecret || 'YOUR_SECRET_HERE'}`\n }\n\n // handles dupes\n if (seenKeys.has(key)) {\n return null\n }\n\n seenKeys.add(key)\n\n return line\n })\n .filter(Boolean)\n .reverse()\n .join('\\n')\n\n if (!updatedEnv.includes('# Added by Payload')) {\n updatedEnv = `# Added by Payload\\n${updatedEnv}`\n }\n\n return updatedEnv\n}\n\n/** Parse and swap .env.example values and write .env */\nexport async function manageEnvFiles(args: {\n cliArgs: CliArgs\n databaseType?: DbType\n databaseUri?: string\n payloadSecret: string\n projectDir: string\n template?: ProjectTemplate\n}): Promise<void> {\n const { cliArgs, databaseType, databaseUri, payloadSecret, projectDir, template } = args\n\n const debugFlag = cliArgs['--debug']\n\n if (cliArgs['--dry-run']) {\n debug(`DRY RUN: Environment files managed`)\n return\n }\n\n const pathToEnvExample = path.join(projectDir, '.env.example')\n const envPath = path.join(projectDir, '.env')\n\n let exampleEnv: null | string = ''\n\n try {\n if (template?.type === 'plugin') {\n if (debugFlag) {\n debug(`plugin template detected - no .env added .env.example added`)\n }\n\n return\n }\n\n // If there's a .env.example file, use it to create or update the .env file\n if (fs.existsSync(pathToEnvExample)) {\n const envExampleContents = await fs.readFile(pathToEnvExample, 'utf8')\n\n exampleEnv = sanitizeEnv({\n contents: envExampleContents,\n databaseType,\n databaseUri,\n payloadSecret,\n })\n\n if (debugFlag) {\n debug(`.env.example file successfully read`)\n }\n }\n\n // If there's no .env file, create it using the .env.example content (if it exists)\n if (!fs.existsSync(envPath)) {\n const envContent = sanitizeEnv({\n contents: exampleEnv,\n databaseType,\n databaseUri,\n payloadSecret,\n })\n\n await fs.writeFile(envPath, envContent)\n\n if (debugFlag) {\n debug(`.env file successfully created`)\n }\n } else {\n // If the .env file already exists, sanitize it as-is\n const envContents = await fs.readFile(envPath, 'utf8')\n\n const updatedEnvContents = sanitizeEnv({\n contents: envContents,\n databaseType,\n databaseUri,\n payloadSecret,\n })\n\n await fs.writeFile(envPath, updatedEnvContents)\n\n if (debugFlag) {\n debug(`.env file successfully updated`)\n }\n }\n } catch (err: unknown) {\n error('Unable to manage environment files')\n if (err instanceof Error) {\n error(err.message)\n }\n process.exit(1)\n }\n}\n"],"names":["fs","path","debug","error","dbChoiceRecord","sanitizeEnv","contents","databaseType","databaseUri","payloadSecret","seenKeys","Set","withDefaults","includes","updatedEnv","split","map","line","startsWith","key","value","dbChoice","placeholderUri","dbConnectionPrefix","dbConnectionSuffix","has","add","filter","Boolean","reverse","join","manageEnvFiles","args","cliArgs","projectDir","template","debugFlag","pathToEnvExample","envPath","exampleEnv","type","existsSync","envExampleContents","readFile","envContent","writeFile","envContents","updatedEnvContents","err","Error","message","process","exit"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import fse from 'fs-extra';
|
|
4
3
|
import * as os from 'node:os';
|
|
5
4
|
import path from 'path';
|
|
5
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it, vitest } from 'vitest';
|
|
6
6
|
import { manageEnvFiles } from './manage-env-files.js';
|
|
7
7
|
describe('createProject', ()=>{
|
|
8
8
|
let projectDir;
|
|
@@ -10,7 +10,7 @@ describe('createProject', ()=>{
|
|
|
10
10
|
let envExampleFilePath = '';
|
|
11
11
|
beforeAll(()=>{
|
|
12
12
|
// eslint-disable-next-line no-console
|
|
13
|
-
console.log =
|
|
13
|
+
console.log = vitest.fn();
|
|
14
14
|
});
|
|
15
15
|
beforeEach(()=>{
|
|
16
16
|
const tempDirectory = fs.realpathSync(os.tmpdir());
|
|
@@ -46,12 +46,12 @@ describe('createProject', ()=>{
|
|
|
46
46
|
});
|
|
47
47
|
expect(fse.existsSync(envFilePath)).toBe(true);
|
|
48
48
|
const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
|
|
49
|
-
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=YOUR_SECRET_HERE\
|
|
49
|
+
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=YOUR_SECRET_HERE\nDATABASE_URL=your-connection-string-here`);
|
|
50
50
|
});
|
|
51
51
|
it('generates .env from .env.example', async ()=>{
|
|
52
52
|
// create or override the .env.example file with a connection string that will NOT be overridden
|
|
53
53
|
fse.ensureFileSync(envExampleFilePath);
|
|
54
|
-
fse.writeFileSync(envExampleFilePath, `
|
|
54
|
+
fse.writeFileSync(envExampleFilePath, `DATABASE_URL=example-connection-string\nCUSTOM_VAR=custom-value\n`);
|
|
55
55
|
await manageEnvFiles({
|
|
56
56
|
cliArgs: {
|
|
57
57
|
'--debug': true
|
|
@@ -63,15 +63,15 @@ describe('createProject', ()=>{
|
|
|
63
63
|
});
|
|
64
64
|
expect(fse.existsSync(envFilePath)).toBe(true);
|
|
65
65
|
const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
|
|
66
|
-
expect(updatedEnvContent).toBe(`
|
|
66
|
+
expect(updatedEnvContent).toBe(`DATABASE_URL=example-connection-string\nCUSTOM_VAR=custom-value\nPAYLOAD_SECRET=YOUR_SECRET_HERE\n# Added by Payload`);
|
|
67
67
|
});
|
|
68
68
|
it('updates existing .env without overriding vars', async ()=>{
|
|
69
69
|
// create an existing .env file with some custom variables that should NOT be overridden
|
|
70
70
|
fse.ensureFileSync(envFilePath);
|
|
71
|
-
fse.writeFileSync(envFilePath, `CUSTOM_VAR=custom-value\
|
|
71
|
+
fse.writeFileSync(envFilePath, `CUSTOM_VAR=custom-value\nDATABASE_URL=example-connection-string\n`);
|
|
72
72
|
// create an .env.example file to ensure that its contents DO NOT override existing .env vars
|
|
73
73
|
fse.ensureFileSync(envExampleFilePath);
|
|
74
|
-
fse.writeFileSync(envExampleFilePath, `CUSTOM_VAR=custom-value-2\
|
|
74
|
+
fse.writeFileSync(envExampleFilePath, `CUSTOM_VAR=custom-value-2\nDATABASE_URL=example-connection-string-2\n`);
|
|
75
75
|
await manageEnvFiles({
|
|
76
76
|
cliArgs: {
|
|
77
77
|
'--debug': true
|
|
@@ -83,7 +83,7 @@ describe('createProject', ()=>{
|
|
|
83
83
|
});
|
|
84
84
|
expect(fse.existsSync(envFilePath)).toBe(true);
|
|
85
85
|
const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
|
|
86
|
-
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=YOUR_SECRET_HERE\
|
|
86
|
+
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=YOUR_SECRET_HERE\nDATABASE_URL=example-connection-string\nCUSTOM_VAR=custom-value`);
|
|
87
87
|
});
|
|
88
88
|
it('sanitizes .env based on selected database type', async ()=>{
|
|
89
89
|
await manageEnvFiles({
|
|
@@ -97,7 +97,7 @@ describe('createProject', ()=>{
|
|
|
97
97
|
template: undefined
|
|
98
98
|
});
|
|
99
99
|
const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
|
|
100
|
-
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=test-secret\
|
|
100
|
+
expect(updatedEnvContent).toBe(`# Added by Payload\nPAYLOAD_SECRET=test-secret\nDATABASE_URL=mongodb://localhost:27017/test`);
|
|
101
101
|
// delete the generated .env file and do it again, but this time, omit the databaseUri to ensure the default is generated
|
|
102
102
|
fse.removeSync(envFilePath);
|
|
103
103
|
await manageEnvFiles({
|
|
@@ -111,7 +111,7 @@ describe('createProject', ()=>{
|
|
|
111
111
|
template: undefined
|
|
112
112
|
});
|
|
113
113
|
const updatedEnvContentWithDefault = fse.readFileSync(envFilePath, 'utf-8');
|
|
114
|
-
expect(updatedEnvContentWithDefault).toBe(`# Added by Payload\nPAYLOAD_SECRET=test-secret\
|
|
114
|
+
expect(updatedEnvContentWithDefault).toBe(`# Added by Payload\nPAYLOAD_SECRET=test-secret\nDATABASE_URL=mongodb://127.0.0.1/your-database-name`);
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
117
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/manage-env-files.spec.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/lib/manage-env-files.spec.ts"],"sourcesContent":["import fs from 'fs'\nimport fse from 'fs-extra'\nimport * as os from 'node:os'\nimport path from 'path'\nimport { afterEach, beforeAll, beforeEach, describe, expect, it, vitest } from 'vitest'\n\nimport type { CliArgs } from '../types.js'\n\nimport { manageEnvFiles } from './manage-env-files.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n let envFilePath = ''\n let envExampleFilePath = ''\n\n beforeAll(() => {\n // eslint-disable-next-line no-console\n console.log = vitest.fn()\n })\n\n beforeEach(() => {\n const tempDirectory = fs.realpathSync(os.tmpdir())\n projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`\n\n envFilePath = path.join(projectDir, '.env')\n envExampleFilePath = path.join(projectDir, '.env.example')\n\n if (fse.existsSync(envFilePath)) {\n fse.removeSync(envFilePath)\n }\n\n fse.ensureDirSync(projectDir)\n })\n\n afterEach(() => {\n if (fse.existsSync(projectDir)) {\n fse.rmSync(projectDir, { recursive: true })\n }\n })\n\n it('generates .env using defaults (not from .env.example)', async () => {\n // ensure no .env.example exists so that the default values are used\n // the `manageEnvFiles` function will look for .env.example in the file system\n if (fse.existsSync(envExampleFilePath)) {\n fse.removeSync(envExampleFilePath)\n }\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseUri: '', // omitting this will ensure the default vars are used\n payloadSecret: '', // omitting this will ensure the default vars are used\n projectDir,\n template: undefined,\n })\n\n expect(fse.existsSync(envFilePath)).toBe(true)\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n\n expect(updatedEnvContent).toBe(\n `# Added by Payload\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\nDATABASE_URL=your-connection-string-here`,\n )\n })\n\n it('generates .env from .env.example', async () => {\n // create or override the .env.example file with a connection string that will NOT be overridden\n fse.ensureFileSync(envExampleFilePath)\n fse.writeFileSync(\n envExampleFilePath,\n `DATABASE_URL=example-connection-string\\nCUSTOM_VAR=custom-value\\n`,\n )\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseUri: '', // omitting this will ensure the `.env.example` vars are used\n payloadSecret: '', // omitting this will ensure the `.env.example` vars are used\n projectDir,\n template: undefined,\n })\n\n expect(fse.existsSync(envFilePath)).toBe(true)\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n\n expect(updatedEnvContent).toBe(\n `DATABASE_URL=example-connection-string\\nCUSTOM_VAR=custom-value\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\n# Added by Payload`,\n )\n })\n\n it('updates existing .env without overriding vars', async () => {\n // create an existing .env file with some custom variables that should NOT be overridden\n fse.ensureFileSync(envFilePath)\n fse.writeFileSync(\n envFilePath,\n `CUSTOM_VAR=custom-value\\nDATABASE_URL=example-connection-string\\n`,\n )\n\n // create an .env.example file to ensure that its contents DO NOT override existing .env vars\n fse.ensureFileSync(envExampleFilePath)\n fse.writeFileSync(\n envExampleFilePath,\n `CUSTOM_VAR=custom-value-2\\nDATABASE_URL=example-connection-string-2\\n`,\n )\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseUri: '', // omitting this will ensure the `.env` vars are kept\n payloadSecret: '', // omitting this will ensure the `.env` vars are kept\n projectDir,\n template: undefined,\n })\n\n expect(fse.existsSync(envFilePath)).toBe(true)\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n\n expect(updatedEnvContent).toBe(\n `# Added by Payload\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\nDATABASE_URL=example-connection-string\\nCUSTOM_VAR=custom-value`,\n )\n })\n\n it('sanitizes .env based on selected database type', async () => {\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseType: 'mongodb', // this mimics the CLI selection and will be used as the DATABASE_URL\n databaseUri: 'mongodb://localhost:27017/test', // this mimics the CLI selection and will be used as the DATABASE_URL\n payloadSecret: 'test-secret', // this mimics the CLI selection and will be used as the PAYLOAD_SECRET\n projectDir,\n template: undefined,\n })\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n\n expect(updatedEnvContent).toBe(\n `# Added by Payload\\nPAYLOAD_SECRET=test-secret\\nDATABASE_URL=mongodb://localhost:27017/test`,\n )\n\n // delete the generated .env file and do it again, but this time, omit the databaseUri to ensure the default is generated\n fse.removeSync(envFilePath)\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseType: 'mongodb', // this mimics the CLI selection and will be used as the DATABASE_URL\n databaseUri: '', // omit this to ensure the default is generated based on the selected database type\n payloadSecret: 'test-secret',\n projectDir,\n template: undefined,\n })\n\n const updatedEnvContentWithDefault = fse.readFileSync(envFilePath, 'utf-8')\n expect(updatedEnvContentWithDefault).toBe(\n `# Added by Payload\\nPAYLOAD_SECRET=test-secret\\nDATABASE_URL=mongodb://127.0.0.1/your-database-name`,\n )\n })\n})\n"],"names":["fs","fse","os","path","afterEach","beforeAll","beforeEach","describe","expect","it","vitest","manageEnvFiles","projectDir","envFilePath","envExampleFilePath","console","log","fn","tempDirectory","realpathSync","tmpdir","Math","random","toString","substring","join","existsSync","removeSync","ensureDirSync","rmSync","recursive","cliArgs","databaseUri","payloadSecret","template","undefined","toBe","updatedEnvContent","readFileSync","ensureFileSync","writeFileSync","databaseType","updatedEnvContentWithDefault"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
|
-
import {
|
|
2
|
+
import { describe, it, expect, vitest } from 'vitest';
|
|
3
3
|
import { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js';
|
|
4
4
|
const tsConfigs = {
|
|
5
5
|
defaultNextConfig: `import type { NextConfig } from "next";
|
|
@@ -122,7 +122,7 @@ describe('parseAndInsertWithPayload', ()=>{
|
|
|
122
122
|
});
|
|
123
123
|
// Unsupported: export { wrapped as default }
|
|
124
124
|
it('should give warning with a named export as default', async ()=>{
|
|
125
|
-
const warnLogSpy =
|
|
125
|
+
const warnLogSpy = vitest.spyOn(p.log, 'warn').mockImplementation(()=>{});
|
|
126
126
|
const { modifiedConfigContent, success } = await parseAndModifyConfigContent(esmConfigs.nextConfigExportNamedDefault, configType);
|
|
127
127
|
expect(modifiedConfigContent).toContain(importStatement);
|
|
128
128
|
expect(success).toBe(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/wrap-next-config.spec.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport { jest } from '@jest/globals'\n\nimport { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js'\n\nconst tsConfigs = {\n defaultNextConfig: `import type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {};\nexport default nextConfig;`,\n\n nextConfigExportNamedDefault: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nconst wrapped = someFunc(asdf);\nexport { wrapped as default };\n`,\n nextConfigWithFunc: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nexport default someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nexport default someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {\n ...someConfig,\n};\nexport default nextConfig;\n`,\n}\n\nconst esmConfigs = {\n defaultNextConfig: `/** @type {import('next').NextConfig} */\nconst nextConfig = {};\nexport default nextConfig;\n`,\n nextConfigExportNamedDefault: `const nextConfig = {};\nconst wrapped = someFunc(asdf);\nexport { wrapped as default };\n`,\n nextConfigWithFunc: `const nextConfig = {};\nexport default someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `const nextConfig = {};;\nexport default someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `const nextConfig = {\n ...someConfig,\n};\nexport default nextConfig;\n`,\n}\n\nconst cjsConfigs = {\n anonConfig: `module.exports = {};`,\n defaultNextConfig: `\n /** @type {import('next').NextConfig} */\nconst nextConfig = {};\nmodule.exports = nextConfig;\n`,\n nextConfigExportNamedDefault: `const nextConfig = {};\nconst wrapped = someFunc(asdf);\nmodule.exports = wrapped;\n`,\n nextConfigWithFunc: `const nextConfig = {};\nmodule.exports = someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `const nextConfig = {};\nmodule.exports = someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `const nextConfig = { ...someConfig };\nmodule.exports = nextConfig;\n`,\n}\n\ndescribe('parseAndInsertWithPayload', () => {\n describe('ts', () => {\n const configType = 'ts'\n const importStatement = withPayloadStatement[configType]\n\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent: modifiedConfigContent2 } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent2).toContain('withPayload(someFunc(nextConfig))')\n })\n\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n })\n describe('esm', () => {\n const configType = 'esm'\n const importStatement = withPayloadStatement[configType]\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')\n })\n\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n\n // Unsupported: export { wrapped as default }\n it('should give warning with a named export as default', async () => {\n const warnLogSpy = jest.spyOn(p.log, 'warn').mockImplementation(() => {})\n\n const { modifiedConfigContent, success } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigExportNamedDefault,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(success).toBe(false)\n\n expect(warnLogSpy).toHaveBeenCalledWith(\n expect.stringContaining('Could not automatically wrap'),\n )\n })\n })\n\n describe('cjs', () => {\n const configType = 'cjs'\n const requireStatement = withPayloadStatement[configType]\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n it('should parse anonymous default config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.anonConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload({})')\n })\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')\n })\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n it('should parse the config with a named export as default', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigExportNamedDefault,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(wrapped)')\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n })\n})\n"],"names":["p","jest","parseAndModifyConfigContent","withPayloadStatement","tsConfigs","defaultNextConfig","nextConfigExportNamedDefault","nextConfigWithFunc","nextConfigWithFuncMultiline","nextConfigWithSpread","esmConfigs","cjsConfigs","anonConfig","describe","configType","importStatement","it","modifiedConfigContent","expect","toContain","modifiedConfigContent2","toMatch","warnLogSpy","spyOn","log","mockImplementation","success","toBe","toHaveBeenCalledWith","stringContaining","requireStatement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/wrap-next-config.spec.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport { describe, it, expect, vitest } from 'vitest'\n\nimport { parseAndModifyConfigContent, withPayloadStatement } from './wrap-next-config.js'\n\nconst tsConfigs = {\n defaultNextConfig: `import type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {};\nexport default nextConfig;`,\n\n nextConfigExportNamedDefault: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nconst wrapped = someFunc(asdf);\nexport { wrapped as default };\n`,\n nextConfigWithFunc: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nexport default someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {};\nexport default someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `import type { NextConfig } from \"next\";\nconst nextConfig: NextConfig = {\n ...someConfig,\n};\nexport default nextConfig;\n`,\n}\n\nconst esmConfigs = {\n defaultNextConfig: `/** @type {import('next').NextConfig} */\nconst nextConfig = {};\nexport default nextConfig;\n`,\n nextConfigExportNamedDefault: `const nextConfig = {};\nconst wrapped = someFunc(asdf);\nexport { wrapped as default };\n`,\n nextConfigWithFunc: `const nextConfig = {};\nexport default someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `const nextConfig = {};;\nexport default someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `const nextConfig = {\n ...someConfig,\n};\nexport default nextConfig;\n`,\n}\n\nconst cjsConfigs = {\n anonConfig: `module.exports = {};`,\n defaultNextConfig: `\n /** @type {import('next').NextConfig} */\nconst nextConfig = {};\nmodule.exports = nextConfig;\n`,\n nextConfigExportNamedDefault: `const nextConfig = {};\nconst wrapped = someFunc(asdf);\nmodule.exports = wrapped;\n`,\n nextConfigWithFunc: `const nextConfig = {};\nmodule.exports = someFunc(nextConfig);\n`,\n nextConfigWithFuncMultiline: `const nextConfig = {};\nmodule.exports = someFunc(\n nextConfig\n);\n`,\n nextConfigWithSpread: `const nextConfig = { ...someConfig };\nmodule.exports = nextConfig;\n`,\n}\n\ndescribe('parseAndInsertWithPayload', () => {\n describe('ts', () => {\n const configType = 'ts'\n const importStatement = withPayloadStatement[configType]\n\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent: modifiedConfigContent2 } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent2).toContain('withPayload(someFunc(nextConfig))')\n })\n\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n tsConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n })\n describe('esm', () => {\n const configType = 'esm'\n const importStatement = withPayloadStatement[configType]\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')\n })\n\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n\n // Unsupported: export { wrapped as default }\n it('should give warning with a named export as default', async () => {\n const warnLogSpy = vitest.spyOn(p.log, 'warn').mockImplementation(() => {})\n\n const { modifiedConfigContent, success } = await parseAndModifyConfigContent(\n esmConfigs.nextConfigExportNamedDefault,\n configType,\n )\n expect(modifiedConfigContent).toContain(importStatement)\n expect(success).toBe(false)\n\n expect(warnLogSpy).toHaveBeenCalledWith(\n expect.stringContaining('Could not automatically wrap'),\n )\n })\n })\n\n describe('cjs', () => {\n const configType = 'cjs'\n const requireStatement = withPayloadStatement[configType]\n it('should parse the default next config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.defaultNextConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n it('should parse anonymous default config', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.anonConfig,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload({})')\n })\n it('should parse the config with a function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithFunc,\n configType,\n )\n expect(modifiedConfigContent).toContain('withPayload(someFunc(nextConfig))')\n })\n it('should parse the config with a multi-lined function', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithFuncMultiline,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toMatch(/withPayload\\(someFunc\\(\\n {2}nextConfig\\n\\)\\)/)\n })\n it('should parse the config with a named export as default', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigExportNamedDefault,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(wrapped)')\n })\n\n it('should parse the config with a spread', async () => {\n const { modifiedConfigContent } = await parseAndModifyConfigContent(\n cjsConfigs.nextConfigWithSpread,\n configType,\n )\n expect(modifiedConfigContent).toContain(requireStatement)\n expect(modifiedConfigContent).toContain('withPayload(nextConfig)')\n })\n })\n})\n"],"names":["p","describe","it","expect","vitest","parseAndModifyConfigContent","withPayloadStatement","tsConfigs","defaultNextConfig","nextConfigExportNamedDefault","nextConfigWithFunc","nextConfigWithFuncMultiline","nextConfigWithSpread","esmConfigs","cjsConfigs","anonConfig","configType","importStatement","modifiedConfigContent","toContain","modifiedConfigContent2","toMatch","warnLogSpy","spyOn","log","mockImplementation","success","toBe","toHaveBeenCalledWith","stringContaining","requireStatement"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-payload-app",
|
|
3
|
-
"version": "3.69.0
|
|
3
|
+
"version": "3.69.0",
|
|
4
4
|
"homepage": "https://payloadcms.com",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -67,7 +67,6 @@
|
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/esprima": "^4.0.6",
|
|
69
69
|
"@types/fs-extra": "^9.0.12",
|
|
70
|
-
"@types/jest": "29.5.12",
|
|
71
70
|
"@types/node": "22.15.30"
|
|
72
71
|
},
|
|
73
72
|
"engines": {
|