-
Notifications
You must be signed in to change notification settings - Fork 3.1k
perf(cpa): use AST for templates #14648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
denolfe
wants to merge
46
commits into
main
Choose a base branch
from
feat/cpa-ast-parsing
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implement AST-based detection of buildConfig call structure in Payload config files using TDD approach. Detects: - buildConfig CallExpression - Import declarations - db property assignment - plugins array All tests pass (3/3).
Implements removeSharp function using TDD to remove sharp import and property from payload config files. This completes Phase 3 - Transformation Implementation.
Refactored configure-payload-config.ts to use AST-based transformations instead of string manipulation: - Replaced string manipulation logic with calls to configurePayloadConfig() and updatePackageJson() from AST modules - Added helper functions: mapDbType(), mapStorageAdapter(), and getEnvVarName() - Enhanced AST payload-config module with removeCommentMarkers() to clean up template markers - Fixed quote style conversion (double to single quotes) - Added indentation normalization to handle ts-morph's formatting quirks - Updated database and storage adapter templates with proper indentation - All existing integration tests pass
Removed AST comment markers from all template payload.config.ts files: - storage-adapter-import-placeholder - database-adapter-import - database-adapter-config-start - database-adapter-config-end - storage-adapter-placeholder - sharp-import Normalized template structures with clean imports and empty plugins arrays where applicable. Templates cleaned: - templates/_template/src/payload.config.ts - templates/blank/src/payload.config.ts - templates/website/src/payload.config.ts - templates/ecommerce/src/payload.config.ts - templates/with-cloudflare-d1/src/payload.config.ts - templates/with-vercel-website/src/payload.config.ts
Removed string-based replacement utilities that were superseded by AST-based config manipulation. Updated test to verify adapter configuration directly instead of using replacement templates.
Fixed .js extension in AST utils import and updated pnpm-lock.yaml with prettier version.
Add integration tests for sampled template × database × storage combinations. Tests verify AST transformations are correctly applied to payload.config.ts and package.json for representative combinations: - blank + mongodb + localDisk - blank + postgres + vercelBlobStorage - website + mongodb + s3Storage - website + postgres + localDisk - ecommerce + mongodb + localDisk - ecommerce + postgres + r2Storage Tests copy template to temp directory, apply transformations via configurePayloadConfig(), and verify imports/config properties are correctly modified. Skip TypeScript compilation for speed.
- Add .js extension to types import in package-json.ts - Add type assertion for DB_PACKAGE_NAMES lookup - Import QuoteKind enum from ts-morph - Add null checks for regex match results in indentation normalization - Remove invalid indentationText setting
…, azureStorage, gcsStorage, uploadthingStorage)
Convert all interfaces to types in AST implementation:
- types.ts: 7 interfaces (DetectionError, PayloadConfigStructures, etc.)
- adapter-config.ts: 2 interfaces (DatabaseAdapterConfig, StorageAdapterConfig)
- utils.ts: 2 internal interfaces (FormatErrorOptions, AddImportOptions)
- package-json.ts: 2 internal interfaces (PackageJsonTransformOptions, PackageJsonStructure)
ConfigureOptions now uses intersection type (WriteOptions & {...}) instead of extends.
…ations Add debug logging throughout AST transformation pipeline when --debug flag is passed: **payload-config.ts:** - Detection phase: buildConfig found/missing, import counts, structure details - Transformations: adapter types, imports added/removed, special imports (vercel-postgres, d1-sqlite) - Validation: structure validation results - Write phase: quote/indent normalization, prettier status, file operations **utils.ts:** - Import operations: additions to existing vs new imports, removals **package-json.ts:** - Dependency updates: adapter changes, sharp removal, package name updates **Integration:** - configure-payload-config.ts: accepts debugMode parameter - create-project.ts: passes cliArgs['--debug'] to AST functions All debug messages use [AST] prefix with status indicators (✓ success, ✗ failure, ⚠ warning).
… code - Set process.env.DEBUG in main.ts when --debug flag is passed - Update debug() function to check process.env.DEBUG internally - Remove debugMode parameters from all AST functions (56 if-blocks eliminated) - Update all call sites to remove debugMode arguments - Remove debugMode from WriteOptions and ConfigureOptions types This eliminates ~150 LOC and improves code readability by removing conditional debug blocks throughout the codebase.
… with 2+ params
- addDatabaseAdapter: (sourceFile, adapter, envVarName) → (sourceFile, { adapter, envVarName })
- addStorageAdapter: (sourceFile, adapter) → (sourceFile, { adapter })
- findImportDeclaration: (sourceFile, moduleSpecifier) → (sourceFile, { moduleSpecifier })
- removeImportDeclaration: (sourceFile, moduleSpecifier) → (sourceFile, { moduleSpecifier })
Benefits:
- Improved backwards-compatibility (can add new options without breaking changes)
- More explicit at call sites
- Consistent with existing functions (addImportDeclaration, configurePayloadConfig)
All 64 tests passing.
… AST code Replace dynamic prettier import with CLI execution to resolve Jest/ESM issues. - Add detectPackageManager() for pnpm/npm/yarn/bun detection - Refactor writeTransformedFile() to call prettier CLI after save - Remove 50+ lines of manual normalization code - Enable formatWithPrettier by default - Update tests to use prettier (remove formatWithPrettier: false)
… replacing DB adapters Enhance AST transformations to maintain original positions of imports and properties during database adapter replacement. Changes (done alongside prettier refactoring): - Update removeImportDeclaration() to return removed import index - Add insertIndex parameter to addImportDeclaration() - Modify addDatabaseAdapter() to track and preserve import positions - Preserve db property position in buildConfig object - Add tests for import and property position preservation Behavior: - When replacing adapter: import and db property stay in original positions - When adding new adapter: inserted at end to avoid disrupting existing structure Tests: 36/36 unit tests passing, 6/6 integration tests passing
Contributor
📦 esbuild Bundle Analysis for payloadThis analysis was generated by esbuild-bundle-analyzer. 🤖 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
Refactor
create-payload-appfrom string manipulation to AST-based transformations usingts-morph,enabling safer and more maintainable template configuration.
Key Changes
AST transformation engine (
packages/create-payload-app/src/lib/ast/)Template normalization
Improved reliability
Design Decisions
AST over string manipulation
String-based replacements were brittle and error-prone with variations in formatting, import order, and code
structure. Using
ts-morphprovides:Adapter configuration centralization
Database and storage adapter configs are now centralized in
adapter-config.tsrather than scattered acrosstemplate files and replacement logic. This reduces duplication and makes adding new adapters
straightforward.
Template cleanup
Removed comment markers (e.g.,
// database-adapter-import-start) from templates since AST can locateinsertion points structurally. Templates now serve as clean, production-ready code without scaffolding
artifacts.
Overall Flow
sequenceDiagram participant CLI as create-payload-app participant AST as AST Engine participant TS as ts-morph participant Template as Template Files CLI->>Template: Copy template CLI->>AST: configurePayloadConfig(options) AST->>TS: Parse payload.config.ts AST->>TS: Transform config structure Note over AST,TS: Replace DB/storage adapters, add/remove plugins, update imports TS->>AST: Modified AST AST->>AST: Format with Prettier AST->>Template: Write updated file AST->>Template: Update package.json