-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Introduce reverse generation engine for Typescript #496
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
feat: Introduce reverse generation engine for Typescript #496
Conversation
🦋 Changeset detectedLatest commit: 284e7cb The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThis set of changes introduces a major refactor and enhancement to the template extraction, configuration, and code generation systems across the monorepo. The TypeScript template extraction pipeline is overhauled with the addition of a schema-driven extractor, improved import organization, and more robust template metadata handling. The configuration service for Fastify generators is modularized and migrated to a new generator file, with corresponding updates to all dependent generators. Utility functions for field mapping and provider tasks are added to the sync package, leveraging task context via AsyncLocalStorage. The runner system is updated to propagate and access task IDs, ensuring dynamic context is available throughout generator execution. Numerous import paths are corrected for clarity and specificity. Tests are updated or added to validate new behaviors, especially around template extraction, formatting, and configuration. Several internal APIs are streamlined, and utility exports are reorganized to improve maintainability. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI/Server
participant TemplateExtractor
participant TsTemplateFileExtractor
participant FileSystem
participant Prettier
participant Generator
CLI/Server->>TemplateExtractor: runTemplateExtractorsForProject(directory, app, context, logger)
TemplateExtractor->>TsTemplateFileExtractor: extractTemplateFiles(files)
TsTemplateFileExtractor->>FileSystem: read template files
TsTemplateFileExtractor->>Prettier: formatGeneratedTemplateContents(contents, filePath)
Prettier-->>TsTemplateFileExtractor: formatted contents
TsTemplateFileExtractor->>FileSystem: write processed template files and import maps
TsTemplateFileExtractor-->>TemplateExtractor: extraction complete
TemplateExtractor-->>CLI/Server: extraction complete
sequenceDiagram
participant Generator
participant Runner
participant Task
participant RunnerContext
Generator->>Runner: executeGeneratorEntry(entry, ...)
Runner->>RunnerContext: runInRunnerContext({taskId}, () => ...)
RunnerContext->>Task: task.run(...), task.build(...)
Task-->>RunnerContext: result
RunnerContext-->>Runner: result
Runner-->>Generator: result
sequenceDiagram
participant FastifyGenerator
participant ConfigServiceGenerator
participant FileSystem
participant TemplateRenderer
FastifyGenerator->>ConfigServiceGenerator: run (setup/build)
ConfigServiceGenerator->>TemplateRenderer: renderTemplateFile / renderTemplateGroup
TemplateRenderer->>FileSystem: write config.ts, .env, .env.example
FileSystem-->>ConfigServiceGenerator: files written
ConfigServiceGenerator-->>FastifyGenerator: config provider ready
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (34)
packages/fastify-generators/src/generators/core/error-handler-service/templates/utils/zod.ts (1)
1-1: Type checking disabled for template utility file.Adding
// @ts-nocheckis acceptable for template files where type errors are expected due to dynamic code generation. Consider documenting the rationale for future maintainers.packages/sync/src/templates/utils/formatter.ts (1)
18-25: Global caching approach is straightforward.
Be aware that if.prettierrcfiles are changed during runtime, the cache won't auto-refresh. Consider adding invalidation logic if live updates to Prettier configurations are required.packages/core-generators/src/generators/node/node/package-dependencies-container.ts (1)
30-34: Constructor extension to handle dynamic source.
StoringgetDynamicSourcein a field is straightforward. Be sure to handle cases where it may beundefined.packages/fastify-generators/src/generators/core/fastify-sentry/index.ts (1)
104-111: Appending Sentry-based logging tologgerActions.
The code fragment precisely referenceslogErrorToSentry. Ensure that thecontextvariable is accessible in the final compiled environment.packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts (2)
68-101: Unclear test name for import preservation.The test name suggests it should "clean up unused imports" but the expected behavior shown in the snapshot is to preserve all imports, including the unused one. This mismatch between the test name and actual behavior could cause confusion.
Consider renaming this test to "should preserve all imports including unused ones" to better reflect the expected behavior:
- it('should clean up unused imports using ts-morph', () => { + it('should preserve all imports including unused ones', () => {
1-147: Consider adding tests for nested or overlapping template blocks.The test suite covers basic template variable stripping, hoisted block removal, import preservation, and error handling, but doesn't explicitly test how the function handles nested or overlapping template blocks.
Consider adding a test case that verifies the behavior with nested template blocks:
it('should handle nested template blocks correctly', () => { const metadata: TsTemplateFileMetadata = { type: TS_TEMPLATE_TYPE, name: 'test-template', generator: 'test-generator', template: 'test-template.ts', variables: { TPL_OUTER: { description: 'Outer variable' }, TPL_INNER: { description: 'Inner variable' }, }, }; const content = ` /* TPL_OUTER:START */ const outer = "Outer"; /* TPL_INNER:START */ const inner = "Inner"; /* TPL_INNER:END */ const afterInner = "After Inner"; /* TPL_OUTER:END */ `; const result = stripTsTemplateVariables(metadata, content); expect(result).toMatchInlineSnapshot(); // Update snapshot after implementation });packages/sync/src/templates/metadata/write-generators-metadata.ts (1)
10-41: Update JSDoc to reflect parameter changes.The JSDoc comment still mentions the removed
filesparameter which is no longer part of the function signature.Update the JSDoc comment to reflect the current parameter list:
/** * Writes the generator metadata map to the project root that * contains the information about the generators that were used to generate the project * * @param generatorEntry - The generator bundle that was used to generate the project - * @param files - Map of file paths to file data * @param outputDirectory - Base directory where files are being written * @returns Promise that resolves when all metadata files are written */packages/core-generators/src/renderers/typescript/extractor/templates/imports-file.ts (2)
1-34: Add documentation to explain template usage.The template lacks documentation explaining its purpose, usage, and the meaning of the placeholders. Given the complexity of the import map provider pattern, documentation would help developers understand how to use and modify the generated code.
Consider adding JSDoc comments to the template string:
export const IMPORTS_FILE_TEMPLATE = ` +/** + * This file defines a typed import map provider for the generated TypeScript code. + * It provides type-safe access to imports across the generated code. + */ import { createReadOnlyProviderType } from '@halfdomelabs/sync'; import type { TsImportMapProviderFromSchema } from 'TPL_TS_IMPORTS'; import { createTsImportMapProvider, createTsImportMapSchema, } from 'TPL_TS_IMPORTS'; +/** + * Schema defining the structure of the import map. + */ const TPL_IMPORTS_SCHEMA_VAR = createTsImportMapSchema(TPL_IMPORTS_SCHEMA); +/** + * Type representing the import map provider based on the schema. + */ type TPL_IMPORTS_PROVIDER_TYPE_VAR = TsImportMapProviderFromSchema< typeof TPL_IMPORTS_SCHEMA_VAR >; +/** + * Read-only provider instance for accessing the import map. + */ export const TPL_IMPORTS_PROVIDER_VAR = createReadOnlyProviderType<TPL_IMPORTS_PROVIDER_TYPE_VAR>( 'TPL_PROVIDER_NAME', ); +/** + * Creates an import map provider instance for the given import base. + * @param importBase - The base path for imports, must start with '@/' + * @returns A typed import map provider instance + */ export function TPL_CREATE_IMPORT_MAP_FUNCTION( importBase: string, ): TPL_IMPORTS_PROVIDER_TYPE_VAR { if (!importBase.startsWith('@/')) { throw new Error('importBase must start with @/'); } return createTsImportMapProvider( TPL_IMPORTS_SCHEMA_VAR, TPL_IMPORT_MAP_CREATOR, ); }`;
26-28: Consider enhancing error message.The error message when
importBasedoesn't start with '@/' could be more informative by including the actual value provided.Enhance the error message to include the actual value:
- throw new Error('importBase must start with @/'); + throw new Error(`importBase must start with @/, got: \${importBase}`);packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts (1)
147-149: Import map creation updated to use fixed path.The import path is now hardcoded to
'@/src/services'. This aligns with the validation in thecreateLoggerServiceImportsfunction that requires paths to start with'@/', but might be less flexible for projects using different import aliases.Consider making the import base path configurable if projects might use different import alias structures.
packages/core-generators/src/renderers/typescript/ts-code-utils.ts (2)
120-123: Ensure consistency of key naming patterns vs. earlier checks.
You’re allowing[A-Z0-9_a-z]+$here, but in earlier logic (e.g., line 8) the allowed pattern differs (it includes a dash-but not a lowercase range). Confirm you truly intend to permit different patterns or unify them for consistent key validation throughout the code.
186-198: Consider providing documentation for the newtemplateWithImportsmethod.
This is a helpful addition, but it’s not immediately clear how the returned function behaves outside your utility context, especially regardingthis.template. A short docstring clarifying usage and the interplay with thetemplatemethod would improve maintainability.packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts (4)
7-7: Consider referencing package paths without explicitly including 'node_modules'Importing directly from
'node_modules/@halfdomelabs/utils/dist/...'can hinder portability if the library structure changes. It's usually safer to import via the published package name or an alias rather than referencing thenode_modulesdirectory.
59-67: Add explicit return type for function clarityThe function implicitly returns a shaped object. While this is valid, an explicit return type interface or type alias can improve maintainability and provide clearer API documentation for future contributors.
100-104: Improve error handling for duplicate exportsThrowing a generic
Erroris acceptable, but consider a custom error class (e.g.,DuplicateExportError) or additional file path details to simplify debugging large projects with many files.
124-165: Consider modularizing the rendering logicThe code to construct and render the import map file is somewhat lengthy. Extracting the rendering logic into a helper function or class can improve readability and testability.
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (2)
139-246: Robust checks for project export import mapThe test comprehensively verifies import map generation for type-only vs. value exports. Good coverage of path transformation. Ideally, add a case for duplicate export detection to ensure the test suite covers error behavior.
248-477: Comprehensive multi-generator resolution testingVerifying cross-generator imports and distinct import maps ensures modular correctness. The approach of referencing one generator’s exports in another is well-tested. As a future enhancement, consider testing cyclical references or partial name collisions for completeness.
packages/core-generators/src/renderers/typescript/extractor/organize-ts-template-imports.ts (1)
16-24: Refine type naming for clarity
Consider renamingProjectExportLookupMapto something more descriptive (e.g.,ProjectExportsByPathMap) for improved readability. This can help new contributors quickly understand its contents and usage.packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.ts (2)
13-46: Complex generics for template definition
These mapped and conditional types can be quite powerful, yet they might become difficult for future contributors to maintain. Adding a short explanatory comment or an example usage snippet can help.
73-125: Assess potential batch rendering performance
Processing each template sequentially ensures predictable ordering but may become a bottleneck if hundreds of templates are grouped. Consider adding an option for concurrency if the underlying rendering is safe to parallelize.packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts (2)
3-10: Remove unused imports
Ensure each imported symbol from@halfdomelabs/core-generatorsis actually needed. If not, remove them to maintain a cleaner codebase and shorter dependency graphs.
41-45: Refine naming
Names likeconfigTaskanderrorHandlerServiceConfigProvidermight be more explicit if they included the term "error" or "handler." This can help future maintainers quickly recognize their responsibilities.packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts (3)
39-41: Enhance descriptor schema usage or remove if unneeded.
ThedescriptorSchemais fairly minimal, only specifying an optionalplaceholder. If it’s not intended for expansion, consider removing it to reduce boilerplate. Otherwise, provide a more explicit description of how to useplaceholder.
46-63: Add inline comments or dev docs for new config field properties.
TheConfigFieldinterface has multiple optional properties (seedValue,exampleValue) which directly affect.envfiles. A short docstring or reference to a usage guide would make the workflow clearer to future maintainers.
155-219: Verify.envgeneration behavior for existing environments.
The builder logic writes.envand.env.examplefiles but prevents overwriting existing.envviashouldNeverOverwrite: true. This is good for preserving local credentials. However, ensure users understand they won’t get newly introduced fields automatically if.envalready exists.Do you want an automated script to prompt users about new env fields instead of silently ignoring them?
packages/core-generators/src/renderers/typescript/renderers/file.ts (2)
22-26: Add clarification for options interface.
RenderTsCodeFileTemplateOptionsextendsRenderTsTemplateOptionswith additional fields likeimportSortOptionsandresolveModule. Consider adding docstrings to ensure users know how these fields influence import transformations.
109-114: Consider validatingimportMapProvidersmore strictly.
Currently, the code checks only for animportMapproperty in providers. If other fields are needed in the future, ensure consistent validation to avoid subtle runtime errors.packages/core-generators/src/generators/node/typescript/index.ts (1)
262-306: Refactor for clearer separation of concerns.
Thefiletask sets uprenderTemplateFileandrenderTemplateGroup. While the logic is correct, consider extracting the import resolution logic into a helper for easier testing and reuse, especially since it’s repeated in both rendering methods.packages/core-generators/src/renderers/typescript/templates/types.ts (2)
46-63: Enhance doc forvariablesusage in templates.
Thoughvariablesis documented, detailing how each variable type is resolved in the resulting code (string vsTsCodeFragment) could reduce confusion for new contributors.
100-124: Enforce uniform naming or grouping in template group definitions.
createTsTemplateGrouplumps templates under a single interface but does not strongly enforce consistent naming conventions. Consider optional validations or docs.packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts (3)
81-85: Confirm validity of@src/renderers/typescript/index.jsimport.Returning
'@src/renderers/typescript/index.js'as an import path might require a custom alias or mapping in your TypeScript build configuration. If this alias is not properly set up, it may break import resolution. Consider providing an explicit.tsextension or ensuring your build config fully supports.jsoutputs for local modules.
135-135: Evaluate necessity of// @ts-nocheck.While disabling type checking can expedite generation, it reduces type coverage in the generated file. If possible, consider a more granular approach (e.g.,
@ts-expect-error) for specific known issues to avoid concealing real errors in the generated output.
254-257: Enhance generator name validation.Currently checking
generatorName.includes('#')helps prevent incorrect formatting, but consider adding a more descriptive or stricter validation method (possibly a regex) to provide clearer error messages and provide better future-proofing.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite
⛔ Files ignored due to path filters (11)
packages/fastify-generators/src/generators/core/config-service/generated/import-maps.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/config-service/generated/ts-import-maps.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/config-service/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/error-handler-service/generated/templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/error-handler-service/generated/ts-import-maps.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/error-handler-service/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/import-maps.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/ts-import-maps.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/ts-templates.tsis excluded by!**/generated/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (107)
packages/core-generators/package.json(1 hunks)packages/core-generators/src/__mocks__/fs.cts(1 hunks)packages/core-generators/src/__mocks__/fs/promises.cts(1 hunks)packages/core-generators/src/generators/node/node/node.generator.ts(3 hunks)packages/core-generators/src/generators/node/node/package-dependencies-container.ts(5 hunks)packages/core-generators/src/generators/node/typescript/index.ts(9 hunks)packages/core-generators/src/renderers/typescript/actions/index.ts(1 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts(1 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.ts(1 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/index.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/organize-ts-template-imports.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/organize-ts-template-imports.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/templates/imports-file.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/imports/builder.ts(1 hunks)packages/core-generators/src/renderers/typescript/imports/merge-ts-import-declarations.ts(1 hunks)packages/core-generators/src/renderers/typescript/imports/merge-ts-import-declarations.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/index.ts(1 hunks)packages/core-generators/src/renderers/typescript/renderers/file.ts(5 hunks)packages/core-generators/src/renderers/typescript/renderers/file.unit.test.ts(7 hunks)packages/core-generators/src/renderers/typescript/renderers/template.ts(3 hunks)packages/core-generators/src/renderers/typescript/renderers/template.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/templates/creators.ts(1 hunks)packages/core-generators/src/renderers/typescript/templates/types.ts(2 hunks)packages/core-generators/src/renderers/typescript/ts-code-utils.ts(2 hunks)packages/core-generators/src/renderers/typescript/ts-code-utils.unit.test.ts(1 hunks)packages/core-generators/src/utils/index.ts(0 hunks)packages/core-generators/src/utils/string.ts(0 hunks)packages/fastify-generators/src/generators/auth0/auth0-module/index.ts(3 hunks)packages/fastify-generators/src/generators/bull/bull-mq/index.ts(1 hunks)packages/fastify-generators/src/generators/bull/fastify-bull-board/index.ts(1 hunks)packages/fastify-generators/src/generators/core/_composers/fastify-composer.ts(1 hunks)packages/fastify-generators/src/generators/core/axios/index.ts(3 hunks)packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/config-service/index.ts(0 hunks)packages/fastify-generators/src/generators/core/config-service/templates/config.ts(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts(4 hunks)packages/fastify-generators/src/generators/core/error-handler-service/templates/plugins/error-handler.ts(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/templates/services/error-logger.ts(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/templates/utils/http-errors.ts(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/templates/utils/zod.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/index.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-redis/index.ts(3 hunks)packages/fastify-generators/src/generators/core/fastify-sentry/index.ts(5 hunks)packages/fastify-generators/src/generators/core/fastify-server/index.ts(3 hunks)packages/fastify-generators/src/generators/core/fastify/index.ts(1 hunks)packages/fastify-generators/src/generators/core/index.ts(1 hunks)packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts(3 hunks)packages/fastify-generators/src/generators/core/logger-service/templates/logger.ts(1 hunks)packages/fastify-generators/src/generators/email/fastify-postmark/index.ts(3 hunks)packages/fastify-generators/src/generators/email/fastify-sendgrid/index.ts(3 hunks)packages/fastify-generators/src/generators/pothos/pothos-auth/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-prisma-crud-mutation/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-prisma-enum/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-prisma-find-query/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-prisma-list-query/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-prisma-object/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-scalar/index.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-sentry/index.ts(1 hunks)packages/fastify-generators/src/generators/prisma/_shared/crud-method/primary-key-input.ts(1 hunks)packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts(1 hunks)packages/fastify-generators/src/generators/prisma/prisma/index.ts(3 hunks)packages/fastify-generators/src/generators/stripe/fastify-stripe/index.ts(3 hunks)packages/fastify-generators/src/generators/yoga/yoga-plugin/index.ts(2 hunks)packages/fastify-generators/src/writers/pothos/helpers.ts(1 hunks)packages/fastify-generators/src/writers/pothos/input-types.ts(1 hunks)packages/fastify-generators/src/writers/pothos/object-types.ts(1 hunks)packages/fastify-generators/src/writers/pothos/scalar-fields.ts(1 hunks)packages/project-builder-cli/src/commands/extract-templates.ts(1 hunks)packages/project-builder-server/src/sync/index.ts(1 hunks)packages/project-builder-server/src/template-extractor/run-template-extractor.ts(4 hunks)packages/react-generators/src/generators/admin/admin-crud-enum-input/index.ts(1 hunks)packages/react-generators/src/generators/admin/admin-crud-foreign-input/index.ts(1 hunks)packages/react-generators/src/generators/admin/admin-layout/index.ts(1 hunks)packages/react-generators/src/generators/auth/auth-login-page/index.ts(1 hunks)packages/react-generators/src/generators/core/_utils/render-routes.ts(1 hunks)packages/react-generators/src/generators/core/react-datadog/index.ts(1 hunks)packages/react-generators/src/generators/core/react/index.ts(1 hunks)packages/sync/src/providers/providers.ts(1 hunks)packages/sync/src/runner/generator-runner.ts(3 hunks)packages/sync/src/runner/generator-runner.unit.test.ts(5 hunks)packages/sync/src/runner/index.ts(1 hunks)packages/sync/src/runner/runner-context.ts(1 hunks)packages/sync/src/templates/extractor/index.ts(1 hunks)packages/sync/src/templates/extractor/run-template-file-extractors.ts(2 hunks)packages/sync/src/templates/extractor/run-template-file-extractors.unit.test.ts(14 hunks)packages/sync/src/templates/extractor/template-file-extractor-test-utils.ts(3 hunks)packages/sync/src/templates/extractor/template-file-extractor.ts(5 hunks)packages/sync/src/templates/index.ts(1 hunks)packages/sync/src/templates/metadata/write-generators-metadata.ts(3 hunks)packages/sync/src/templates/metadata/write-generators-metadata.unit.test.ts(4 hunks)packages/sync/src/templates/raw-template/render-raw-template-action.ts(1 hunks)packages/sync/src/templates/text-template/render-text-template-file-action.ts(1 hunks)packages/sync/src/templates/utils/formatter.ts(1 hunks)packages/sync/src/templates/utils/index.ts(1 hunks)packages/sync/src/templates/utils/read-template-file-source.ts(1 hunks)packages/sync/src/utils/create-config-field-map.ts(1 hunks)packages/sync/src/utils/create-config-provider-task.ts(2 hunks)packages/sync/src/utils/create-provider-task.ts(1 hunks)packages/sync/src/utils/index.ts(1 hunks)
⛔ Files not processed due to max files limit (17)
- packages/sync/src/utils/parse-generator-name.ts
- packages/sync/src/utils/parse-generator-name.unit.test.ts
- packages/utils/src/field-map/field-map.ts
- packages/utils/src/index.ts
- packages/utils/src/maps/index.ts
- packages/utils/src/maps/key-by.ts
- packages/utils/src/maps/key-by.unit.test.ts
- packages/utils/src/maps/safe-merge-map.ts
- packages/utils/src/maps/safe-merge-map.unit.test.ts
- packages/utils/src/paths/get-common-path-prefix.ts
- packages/utils/src/paths/get-common-path-prefix.unit.test.ts
- packages/utils/src/string/index.ts
- packages/utils/src/string/quot.ts
- packages/utils/src/string/quot.unit.test.ts
- plugins/baseplate-plugin-storage/package.json
- plugins/baseplate-plugin-storage/src/generators/fastify/prisma-file-transformer/index.ts
- plugins/baseplate-plugin-storage/src/generators/fastify/storage-module/index.ts
💤 Files with no reviewable changes (3)
- packages/core-generators/src/utils/string.ts
- packages/core-generators/src/utils/index.ts
- packages/fastify-generators/src/generators/core/config-service/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (25)
packages/project-builder-server/src/sync/index.ts (1)
packages/sync/src/templates/metadata/write-generators-metadata.ts (1)
writeGeneratorsMetadata(52-64)
packages/fastify-generators/src/generators/email/fastify-sendgrid/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/fastify-generators/src/generators/yoga/yoga-plugin/index.ts (1)
packages/sync/src/utils/create-config-field-map.ts (1)
createConfigFieldMap(14-20)
packages/fastify-generators/src/generators/stripe/fastify-stripe/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/sync/src/utils/create-config-field-map.ts (2)
packages/utils/src/field-map/field-map.ts (4)
FieldMapSchema(184-184)FieldMapSchemaBuilder(197-249)FieldMap(192-194)createFieldMap(264-284)packages/sync/src/runner/runner-context.ts (1)
getRunnerContext(33-35)
packages/sync/src/runner/generator-runner.ts (3)
packages/sync/src/runner/runner-context.ts (1)
runInRunnerContext(21-23)packages/sync/src/generators/generators.ts (1)
GeneratorTaskResult(102-116)packages/sync/src/providers/providers.ts (1)
Provider(11-11)
packages/fastify-generators/src/generators/core/fastify-server/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/fastify-generators/src/generators/email/fastify-postmark/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/sync/src/runner/generator-runner.unit.test.ts (3)
packages/sync/src/providers/providers.ts (1)
Provider(11-11)packages/sync/src/runner/runner-context.ts (1)
getRunnerContext(33-35)packages/sync/src/runner/generator-runner.ts (1)
executeGeneratorEntry(53-318)
packages/sync/src/templates/extractor/run-template-file-extractors.ts (3)
packages/sync/src/utils/evented-logger.ts (1)
Logger(3-8)packages/sync/src/templates/extractor/create-generator-info-map.ts (1)
createGeneratorInfoMap(21-64)packages/sync/src/templates/constants.ts (1)
TEMPLATE_METADATA_FILENAME(2-2)
packages/core-generators/src/generators/node/node/package-dependencies-container.ts (1)
packages/utils/src/field-map/field-map.ts (2)
FieldContainerDynamicSourceGetter(1-1)FieldContainerOptions(3-10)
packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.unit.test.ts (6)
packages/core-generators/src/renderers/typescript/templates/types.ts (2)
createTsTemplateGroup(120-124)createTsTemplateFile(88-98)packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.ts (1)
renderTsTemplateGroupAction(73-124)packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)packages/sync/src/output/builder-action-test-helpers.ts (1)
testAction(35-42)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(69-77)packages/core-generators/src/renderers/typescript/import-maps/ts-import-map.ts (2)
createTsImportMapSchema(9-13)createTsImportMap(23-67)
packages/sync/src/templates/extractor/template-file-extractor.ts (1)
packages/sync/src/templates/utils/formatter.ts (1)
formatGeneratedTemplateContents(56-67)
packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.ts (1)
packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateFileMetadata(38-40)
packages/fastify-generators/src/generators/core/axios/index.ts (3)
packages/core-generators/src/generators/node/typescript/index.ts (1)
typescriptProvider(87-88)packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(69-77)
packages/fastify-generators/src/generators/core/fastify-sentry/index.ts (2)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(69-77)
packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts (3)
packages/fastify-generators/src/generators/core/logger-service/generated/ts-templates.ts (1)
CORE_LOGGER_SERVICE_TS_TEMPLATES(10-10)packages/core-generators/src/renderers/typescript/ts-code-utils.ts (1)
TsCodeUtils(38-199)packages/fastify-generators/src/generators/core/logger-service/generated/ts-import-maps.ts (1)
createLoggerServiceImports(21-31)
packages/fastify-generators/src/generators/prisma/prisma/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/fastify-generators/src/generators/auth0/auth0-module/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/fastify-generators/src/generators/core/fastify-redis/index.ts (1)
packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(30-44)
packages/core-generators/src/generators/node/node/node.generator.ts (2)
packages/core-generators/src/generators/node/node/package-dependencies-container.ts (1)
createNodePackageDependenciesContainer(140-144)packages/sync/src/utils/create-config-field-map.ts (1)
createConfigFieldMap(14-20)
packages/core-generators/src/renderers/typescript/templates/creators.ts (2)
packages/core-generators/src/renderers/typescript/templates/types.ts (2)
TsTemplateVariableMap(46-46)TsTemplateFile(48-72)packages/sync/src/providers/providers.ts (1)
ProviderType(17-40)
packages/core-generators/src/renderers/typescript/templates/types.ts (4)
packages/sync/src/templates/metadata/metadata.ts (1)
templateFileMetadataBaseSchema(3-20)packages/sync/src/providers/providers.ts (2)
ProviderType(17-40)InferProviderType(42-42)packages/sync/src/templates/types.ts (1)
TemplateFileBase(21-34)packages/core-generators/src/renderers/typescript/fragments/types.ts (1)
TsCodeFragment(45-62)
packages/core-generators/src/renderers/typescript/renderers/file.ts (6)
packages/core-generators/src/renderers/typescript/renderers/template.ts (2)
RenderTsTemplateOptions(6-15)renderTsTemplateToTsCodeFragment(24-97)packages/core-generators/src/renderers/typescript/imports/sort-imports/sort-import-declarations.ts (1)
SortImportDeclarationsOptions(12-28)packages/core-generators/src/renderers/typescript/imports/types.ts (1)
TsImportDeclaration(22-43)packages/core-generators/src/renderers/typescript/fragments/types.ts (1)
TsHoistedFragment(16-36)packages/core-generators/src/renderers/typescript/import-maps/types.ts (1)
TsImportMap(30-30)packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateFileVariableValue(74-74)
packages/core-generators/src/renderers/typescript/ts-code-utils.ts (2)
packages/core-generators/src/renderers/typescript/imports/types.ts (1)
TsImportDeclaration(22-43)packages/core-generators/src/renderers/typescript/fragments/types.ts (1)
TsCodeFragment(45-62)
🔇 Additional comments (205)
packages/fastify-generators/src/generators/core/logger-service/templates/logger.ts (1)
2-2: Whitespace addition improves readability.Adding a blank line after the file-level comment is a minor but positive readability improvement.
packages/sync/src/templates/text-template/render-text-template-file-action.ts (1)
13-13: Import path update improves maintainability.Switching to a centralized utility import path is a best practice and aligns with the broader codebase refactor.
packages/sync/src/templates/raw-template/render-raw-template-action.ts (1)
4-4: Import path update improves maintainability.Centralizing utility imports is a best practice and this change is consistent with the codebase refactor.
packages/fastify-generators/src/writers/pothos/helpers.ts (1)
5-5: Importingquotfrom utils improves modularity.Moving utility imports to a dedicated package is a best practice for separation of concerns and code reuse.
packages/fastify-generators/src/generators/pothos/pothos-prisma-crud-mutation/index.ts (1)
12-12: Importingquotfrom utils improves modularity.This change aligns with best practices for utility separation and code reuse.
packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/index.ts (1)
9-9: Import path update improves clarity.The import path update for
errorHandlerServiceProviderto explicitly reference the generator file is correct and aligns with best practices for modularity and maintainability.packages/react-generators/src/generators/admin/admin-layout/index.ts (1)
12-12: Utility import source update is correct.Switching the
quotimport to@halfdomelabs/utilsis a positive modularization step and maintains consistency across the codebase.packages/react-generators/src/generators/core/react-datadog/index.ts (1)
15-15: Utility import modularization is correct.Importing
quotfrom@halfdomelabs/utilsis consistent with the codebase's modularization goals.packages/react-generators/src/generators/auth/auth-login-page/index.ts (1)
13-13: Utility import modularization is correct.Switching the
quotimport to@halfdomelabs/utilsis a positive modularization step and maintains consistency across the codebase.packages/fastify-generators/src/generators/core/error-handler-service/templates/utils/http-errors.ts (1)
1-1: Addition of// @ts-nocheckis appropriate for template files.Disabling TypeScript checking is standard for code templates that may be transformed or interpolated. No issues found.
packages/sync/src/templates/utils/read-template-file-source.ts (1)
5-5: Import path update improves consistency.The import path change is correct and aligns with the refactor for utility standardization.
packages/fastify-generators/src/generators/pothos/pothos-auth/index.ts (1)
15-15: Import path update forerrorHandlerServiceProviderimproves clarity.Switching to the explicit generator file path is a good practice for maintainability.
packages/fastify-generators/src/generators/bull/bull-mq/index.ts (1)
17-17: Import path update forerrorHandlerServiceProviderimproves clarity.Switching to the explicit generator file path is a good practice for maintainability.
packages/fastify-generators/src/generators/bull/fastify-bull-board/index.ts (1)
18-18: Import path update forerrorHandlerServiceProviderimproves clarity.Switching to the explicit generator file path is a good practice for maintainability.
packages/fastify-generators/src/generators/pothos/pothos-scalar/index.ts (1)
12-12: Import path update improves clarity and modularity.The import path for
errorHandlerServiceProvideris now more explicit and aligns with best practices for modular imports. No issues found.packages/fastify-generators/src/generators/pothos/pothos-sentry/index.ts (1)
13-13: Import path update improves clarity and modularity.The import path for
errorHandlerServiceProvideris now more explicit and aligns with best practices for modular imports. No issues found.packages/fastify-generators/src/writers/pothos/scalar-fields.ts (1)
3-4: Utility import modularization is correct.Importing
quotfrom@halfdomelabs/utilsimproves clarity and modularity. No issues found.packages/fastify-generators/src/writers/pothos/input-types.ts (1)
1-2: Utility import modularization is correct.Importing
quotfrom@halfdomelabs/utilsimproves clarity and modularity. No issues found.packages/fastify-generators/src/generators/prisma/_shared/crud-method/primary-key-input.ts (1)
3-4: Utility import modularization is correct.Importing
quotfrom@halfdomelabs/utilsimproves clarity and modularity. No issues found.packages/react-generators/src/generators/core/react/index.ts (1)
24-24: Approve import standardization from @halfdomelabs/utils.The change to import
quotdirectly from@halfdomelabs/utilsinstead of from@halfdomelabs/core-generatorsaligns with the project's effort to standardize utility imports.packages/fastify-generators/src/writers/pothos/object-types.ts (1)
1-2: Approve consistent utility import pattern.Separating
TypescriptCodeUtilsandquotimports improves modularization by sourcing utilities from the appropriate packages.packages/fastify-generators/src/generators/pothos/pothos-prisma-object/index.ts (1)
13-13: Approve import standardization.Moving the
quotimport to come from@halfdomelabs/utilsmaintains consistency with the pattern applied across the codebase.packages/fastify-generators/src/generators/pothos/pothos-prisma-enum/index.ts (1)
1-3: Approve consistent utility import refactoring.Separating the imports to source
TypescriptCodeUtilsfrom core-generators andquotfrom utils package improves organization and consistency.packages/fastify-generators/src/generators/pothos/pothos-prisma-list-query/index.ts (1)
9-9: Import path refactor is correct.The import of
quotfrom@halfdomelabs/utilsis consistent with the modularization objective and does not affect functionality.packages/fastify-generators/src/generators/pothos/pothos-prisma-find-query/index.ts (1)
9-9: Utility import refactor is correct.Switching the
quotimport to@halfdomelabs/utilsis a safe modularization step and does not impact logic.packages/sync/src/templates/index.ts (1)
7-7: Export path update is correct.Changing the utils export to
'./utils/index.js'aligns with the new utility module structure and is non-breaking.packages/react-generators/src/generators/core/_utils/render-routes.ts (1)
4-4: Utility import refactor is correct.Importing
quotfrom@halfdomelabs/utilsis consistent with the modularization effort and does not affect logic.packages/react-generators/src/generators/admin/admin-crud-enum-input/index.ts (1)
3-3: Utility import refactor is correct.Switching the
quotimport to@halfdomelabs/utilsis a safe modularization step and does not impact logic.packages/core-generators/package.json (1)
41-47: New dependencies are appropriate and justified.The additions of
change-case,memfs,oxc-resolver, andp-limitare well-justified for the new template extraction and rendering features. No issues found.packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts (1)
8-8: Import source forquotis now correct.Switching the import of
quotto@halfdomelabs/utilsimproves modularity and separation of concerns. No issues.packages/fastify-generators/src/generators/core/error-handler-service/templates/plugins/error-handler.ts (1)
3-3: Import path forconfigis now explicit and modular.The update to import
configfrom%configServiceImportsaligns with the new modular provider structure. No issues.packages/fastify-generators/src/generators/core/fastify/index.ts (1)
76-76: SimplifiednodeConfig.isEsm.setcall is correct.Removing the explicit
taskIdargument is correct and matches the new internal context management. No issues.packages/react-generators/src/generators/admin/admin-crud-foreign-input/index.ts (1)
3-3: Import source forquotis now correct.Switching the import of
quotto@halfdomelabs/utilsimproves modularity and separation of concerns. No issues.packages/project-builder-server/src/sync/index.ts (1)
170-170: Function signature updated correctly.The call to
writeGeneratorsMetadatahas been updated to match the new function signature, removing theoutput.filesparameter. This aligns with the changes in thepackages/sync/src/templates/metadata/write-generators-metadata.tsfile where the function was simplified to only require the generator entry and output directory.packages/sync/src/runner/index.ts (1)
2-2: Public API extended to include runner context.This addition exposes the context management utilities from
runner-context.js, which implement context management for generator runners using Node.js AsyncLocalStorage. This is a good enhancement that enables task ID tracking during generator execution.packages/core-generators/src/__mocks__/fs/promises.cts (1)
1-2: Good mock implementation for testing.This mock correctly exports the
promisesproperty from thememfspackage'sfsobject, providing an in-memory mock of the Node.jsfs.promisesAPI. This is a good practice for testing file operations without affecting the real file system.packages/core-generators/src/renderers/typescript/ts-code-utils.unit.test.ts (1)
112-120: Good test case for handling invalid identifier keys.This test validates that object keys containing special characters (like hyphens) are properly escaped as string literals in the generated TypeScript code. This ensures that the
mergeFragmentsAsObjectmethod correctly handles object keys that are not valid JavaScript identifiers.packages/core-generators/src/renderers/typescript/extractor/index.ts (1)
1-1: Clean re-export pattern implementedThe re-export pattern is well-implemented, providing a clean public API for the TypeScript extractor functionality. This approach enhances maintainability by centralizing the exports through a single entry point.
packages/fastify-generators/src/generators/core/_composers/fastify-composer.ts (1)
8-9: Improved import specificityThe imports have been updated to reference specific generator files directly, rather than importing from index files. This makes dependencies more explicit and helps prevent potential circular dependencies.
packages/fastify-generators/src/generators/core/error-handler-service/templates/services/error-logger.ts (1)
19-21: Template placeholders standardized with TPL_ prefixThe placeholder tokens have been updated with a clear
TPL_prefix, making it more evident that these are template placeholders to be replaced during code generation. This convention improves clarity in template files.packages/core-generators/src/__mocks__/fs.cts (1)
1-2: Good mock implementation using memfsThe implementation of an in-memory filesystem mock using
memfsis a good practice for isolating tests from the actual filesystem. This approach allows for predictable and repeatable test scenarios.packages/sync/src/providers/providers.ts (1)
98-103: Well-designed type utility for provider inferenceThis new conditional type
InferProviderDependency<T>elegantly abstracts away the complexity of extracting provider types from different interfaces. It creates a unified way to infer the underlying provider type from either aProviderDependencyorProviderType, which will improve type safety and inference in code that works with providers.The implementation properly follows TypeScript's type inference patterns with the nested conditional type approach.
packages/core-generators/src/renderers/typescript/actions/index.ts (1)
1-2: Clean index exports for the new action modulesThis barrel file provides a clean, centralized export point for the TypeScript template rendering actions. This pattern simplifies imports for consumers and helps maintain a clear API boundary.
packages/sync/src/templates/utils/index.ts (1)
1-2: Good organizational pattern for template utilitiesThis index file follows the module aggregation pattern for centralizing exports. It provides a convenient single import point for accessing template utilities, which improves maintainability and import organization throughout the codebase.
packages/sync/src/templates/extractor/index.ts (1)
2-2: Clean addition of test utilities to the public APIAdding test utilities to the extractor package's public API is a good practice that will facilitate testing for consumers of this module. The placement between the existing exports maintains alphabetical order.
packages/fastify-generators/src/generators/yoga/yoga-plugin/index.ts (3)
18-18: Good migration to context-aware field map creationReplacing
createFieldMapwithcreateConfigFieldMapaligns with the PR's broader goal of making generators context-aware.
29-30: Improved import path specificityUpdating import paths to explicitly reference
.generator.jsfiles rather than directory indexes improves code clarity and helps avoid potential circular dependencies. This is consistent with similar import path refinements across the codebase.
93-93: Successfully upgraded to context-aware field mapThis change implements the migration from
createFieldMaptocreateConfigFieldMap, which will enable the field map to access the current task ID via the runner context. This is crucial for the reverse generation engine functionality being introduced.packages/core-generators/src/renderers/typescript/index.ts (1)
1-2: New exports enhance TypeScript generation capabilitiesThese new exports integrate the action-based rendering model and TypeScript template file extractor into the core TypeScript renderer package. This aligns well with the PR objective of introducing a reverse generation engine for TypeScript.
packages/fastify-generators/src/generators/core/config-service/templates/config.ts (2)
3-3: Improved template-driven configuration approachThe change from inline schema creation to using a predefined schema constant makes the template more flexible and aligns with the template-based code generation architecture.
7-7: Standardized template variable namingRenaming to
TPL_ADDITIONAL_VERIFICATIONSfollows the convention of prefixing template placeholders withTPL_, making the code generation process more consistent.packages/core-generators/src/renderers/typescript/imports/merge-ts-import-declarations.ts (1)
51-51: Simplified type-only import logicThe logic for determining the
isTypeOnlyproperty has been simplified while maintaining the same behavior. This is more readable and aligns with TypeScript's behavior where a type-only import declaration makes all its contained imports type-only.packages/core-generators/src/renderers/typescript/renderers/template.unit.test.ts (1)
47-49: Improved template variable metadata formatThe test now expects a more explicit format with distinct start and end comments wrapping template variable replacements. This provides clearer boundaries for template variable replacements, especially for complex replacements that might span multiple lines.
packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
69-76: Nice enhancement adding support for initial named imports.This is a good enhancement to the
tsImportBuilderfunction that allows it to be initialized with a set of named imports. This makes the API more flexible for consumers who need to start with a predefined set of imports.The implementation correctly handles the optional nature of the parameter with the
namedImports?.map()optional chaining syntax.packages/core-generators/src/generators/node/node/node.generator.ts (3)
4-12: Good integration with the context-aware field map system.The import changes correctly align with the new dynamic source tracking system, replacing
createFieldMapwith the context-awarecreateConfigFieldMaputility.
42-42: Proper propagation of options to the dependencies container.This change correctly passes
t.optionsto the dependencies container, allowing it to access the task context and dynamic source information.
130-132: Well-implemented migration to context-aware field maps.The switch from
createFieldMaptocreateConfigFieldMapensures that the node generator's package JSON fields properly track their sources via the runner context task IDs.packages/sync/src/utils/create-config-provider-task.ts (2)
20-20: Good modularization of the context-aware field map utility.The import change correctly references the new local module containing the context-aware field map creation utility.
109-109: Excellent integration with runner context for source tracking.Using
createConfigFieldMapinstead ofcreateFieldMapensures that configuration fields are properly associated with the current task ID from the runner context, improving traceability.packages/project-builder-cli/src/commands/extract-templates.ts (2)
20-20: Updated parameter type to match new required behavior.The function signature correctly reflects that
appis now a required string parameter instead of optional.This change aligns with the command definition update and the corresponding server-side changes in the template extraction workflow.
16-16:Details
❓ Verification inconclusive
Breaking change:
appparameter is now required.This change makes the
appparameter mandatory in the CLI command, which is a breaking change for existing users who might be running the command without specifying an app.Make sure this change is documented in the release notes/changelog. Also, verify that the error message when not providing the app parameter is clear and helpful for users.
🏁 Script executed:
#!/bin/bash # Verify the error message displayed when the app parameter is missing pbcli extract-templates . 2>&1 | grep -E "error|required|missing"Length of output: 62
Action Required: Verify Clear Error Message for Missing
appParameterThe change that makes the
appparameter mandatory is critical and may affect existing users. However, our initial verification did not yield any error output when running the command without theappparameter:pbcli extract-templates . 2>&1 | grep -E "error|required|missing"No error message was detected, which prevents us from confirming that users will see a clear, helpful error when the parameter is omitted. Please manually verify that:
- Running
pbcli extract-templateswithout theappparameter prompts a clear and informative error message.- The breaking change is appropriately documented in the release notes/changelog.
packages/core-generators/src/renderers/typescript/imports/merge-ts-import-declarations.unit.test.ts (2)
110-110: Explicit isTypeOnly property improves test clarity.The addition of
isTypeOnly: falsemakes the test more explicit about the behavior being tested. This clarifies that the import keeps its type-only status based on the parent declaration, not the individual import.
114-114: Consistent property usage in test case.Adding
isTypeOnly: falsehere maintains consistency with the type-only import declaration above, making the test more explicit and easier to understand.packages/sync/src/runner/generator-runner.ts (3)
28-28: Added new context management import.This import allows for task context propagation during generator execution.
156-162: Enhanced task execution with runner context.Wrapping the task.run call with
runInRunnerContextenables dynamic context propagation while maintaining the original functionality. This allows the taskId to be accessible throughout the execution flow.
205-209: Added context propagation for the build step.Similar to the change in the init step, this wraps the generator.build method call with
runInRunnerContextto ensure the taskId is available in the context during the build phase.packages/fastify-generators/src/generators/prisma/prisma/index.ts (3)
12-12: Added import for tsCodeFragment utility.This import will be used to create TypeScript code fragments for configuration validators, improving code generation.
35-35: Updated import path for better module resolution.The import path was changed to reference the specific generator file rather than the directory index, improving clarity and stability of imports.
144-147: Updated configuration field definition approach.The code now:
- Uses
configFields.setinstead ofgetConfigEntries().set- Uses
validatorproperty instead ofvalue- Applies
tsCodeFragmentfor the schema validatorThis aligns with the new pattern for defining configuration fields across Fastify generators.
packages/sync/src/utils/create-config-field-map.ts (1)
14-20: Well-designed utility for task-aware configuration field maps.This new utility function elegantly bridges configuration fields with the task execution context. By providing a
getDynamicSourcecallback that retrieves the current task ID, it enables dynamic context awareness in configuration field maps.This is a good abstraction that centralizes the pattern of creating field maps with task context awareness.
packages/fastify-generators/src/generators/email/fastify-sendgrid/index.ts (3)
5-5: Import added for code fragment support.The addition of
tsCodeFragmentimport enables type-safe creation of TypeScript code fragments with proper import handling, which is used for the validation schema below.
16-16: Improved import specificity.Updated import path to reference the specific generator file rather than the directory index. This makes dependencies more explicit and improves build tooling's ability to track dependencies.
44-49: Updated config field API with code fragment validation.The configuration service API has been updated to use
configFields.setinstead ofgetConfigEntries().set, and the validation schema is now defined usingtsCodeFragmentinstead of a string literal. This provides better type safety and enables IDE support for the schema definition.packages/sync/src/utils/index.ts (1)
1-2: Added exports for new utility modules.These new utility exports provide important functionality:
concurrency.js- Likely contains utilities for managing concurrent operationscreate-config-field-map.js- Creates field maps with dynamic source trackingcreate-provider-task.js- Facilitates creating generator tasks with type-safe inferenceparse-generator-name.js- Utilities for parsing generator namesThese additions support the broader refactoring effort across the monorepo.
Also applies to: 7-7, 12-12
packages/fastify-generators/src/generators/core/fastify-redis/index.ts (3)
8-8: Import added for code fragment support.The addition of
tsCodeFragmentimport enables type-safe creation of TypeScript code fragments with proper import handling, consistent with other generator files.
22-22: Improved import specificity.Updated import path to reference the specific generator file rather than the directory index, making dependencies more explicit and improving build tooling's ability to track dependencies.
67-71: Updated config field API with code fragment validation.The configuration service API has been updated to use
configFields.setinstead ofgetConfigEntries().set, and the validation schema is now defined usingtsCodeFragmentinstead ofTypescriptCodeUtils.createExpression. This provides better type safety and enables IDE support for the schema definition.packages/fastify-generators/src/generators/core/fastify-server/index.ts (3)
9-9: Import added for code fragment support.The addition of
tsCodeFragmentimport enables type-safe creation of TypeScript code fragments with proper import handling, consistent with other generator files.
25-25: Improved import specificity.Updated import path to reference the specific generator file rather than the directory index, making dependencies more explicit and improving build tooling's ability to track dependencies.
123-134: Updated config field API with advanced validation schemas.The configuration service API has been updated to use
configFields.mergeObj()instead ofgetConfigEntries().merge(), with validation schemas now defined usingtsCodeFragment. This provides:
- Better type safety for config fields
- More expressive validation schemas (with defaults, min/max values)
- Consistent approach to configuration handling across generators
The port validation properly coerces input to numbers and sets appropriate min/max constraints.
packages/fastify-generators/src/generators/auth0/auth0-module/index.ts (6)
24-24: Dependency import path updated to specific generator file.Import has been updated to reference the specific generator file instead of index. This matches the pattern used in other files and improves clarity by making the exact source explicitly visible.
83-88: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for AUTH0_DOMAIN has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation. This approach provides better type safety and consistency with other generator modules.
90-95: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for AUTH0_AUDIENCE has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation.
110-116: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for AUTH0_TENANT_DOMAIN has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation.
118-124: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for AUTH0_CLIENT_ID has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation.
126-131: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for AUTH0_CLIENT_SECRET has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation.packages/fastify-generators/src/generators/email/fastify-postmark/index.ts (3)
5-5: Added import fortsCodeFragment.Added the import for
tsCodeFragmentwhich is now used for configuration validation.
16-16: Dependency import path updated to specific generator file.Import has been updated to reference the specific generator file instead of index. This improves clarity by making the exact source explicitly visible.
42-47: Configuration API updated to useconfigFields.setwith typed validators.The configuration setup for POSTMARK_API_TOKEN has been updated to use the newer configuration API with
configFields.setandtsCodeFragmentfor validation. This approach provides better type safety and consistency with other generator modules.packages/sync/src/runner/generator-runner.unit.test.ts (4)
21-21: Added import for the runner context accessor.Imported
getRunnerContextfrom the new runner-context module to access the current task context during testing.
59-59: Added optional run parameter to test helper function.Extended the
buildGeneratorEntryhelper to accept an optionalruncallback, allowing tests to execute custom logic during the run phase of generator execution.Also applies to: 73-74
90-96: Updated test helper to incorporate run callback.Modified the test helper to execute the optional run callback before returning providers and build function, allowing tests to verify behavior during the run phase.
141-157: Added test to verify task ID propagation.Added a new test that verifies the task ID is correctly set and accessible in the runner context during both the
runandbuildphases of generator execution. This ensures that task context is properly propagated throughout the generation process.packages/fastify-generators/src/generators/core/index.ts (1)
4-5: Updated exports to reference specific generator files.Modified the exports to point directly to specific generator files rather than directory indexes. This makes the export sources more explicit and aligns with the import pattern used across the codebase.
packages/sync/src/utils/create-provider-task.ts (1)
11-32: Clean, type-safe abstraction for provider-dependent tasksThis utility function elegantly simplifies the creation of generator tasks that depend on a single provider. The implementation is well-documented with JSDoc comments and uses generics to ensure strong type safety.
packages/fastify-generators/src/generators/stripe/fastify-stripe/index.ts (3)
5-5: Import addition aligns with updated validation patternAdding the
tsCodeFragmentutility supports the transition to typed code fragments for validators.
17-18: Explicit import paths improve clarityThe updated import paths directly reference the specific generator files, making dependencies more explicit and easier to track.
60-69: Enhanced type safety in config validationThe switch from string literal validators to typed code fragments using
tsCodeFragmentimproves type safety and consistency. This change aligns with the broader refactoring pattern across generators.packages/project-builder-server/src/template-extractor/run-template-extractor.ts (4)
4-4: New TypeScript template extractor integrationAdding the
TsTemplateFileExtractorimport introduces enhanced TypeScript template extraction capabilities.
24-24: Extended template extraction supportAdding the TypeScript template file extractor to the creators list enables enhanced template extraction for TypeScript files.
76-84: Improved validation prevents ambiguous app selectionThis validation ensures a single app directory is selected, preventing ambiguity when multiple directories match the app name. The update to pass only a single directory to
runTemplateFileExtractorsaligns with this change.
53-53:Details
✅ Verification successful
Stricter app parameter typing might impact backward compatibility
The
appparameter is now required as a string, removing its optionality. Verify that all calling code provides this parameter.
🏁 Script executed:
#!/bin/bash # Check for places where runTemplateExtractorsForProject is called rg -A 3 'runTemplateExtractorsForProject\(' --type tsLength of output: 859
Verification Complete – Backward Compatibility Confirmed
The change to require the
appparameter as a string has been verified. All call sites, including the one inpackages/project-builder-cli/src/commands/extract-templates.ts, provide this argument, so there is no backward compatibility issue.packages/core-generators/src/renderers/typescript/renderers/file.unit.test.ts (4)
4-7: Updated imports for new import map functionalityThese imports support the enhanced import map handling capabilities being tested.
12-28: Simplified test case for synchronous renderingThis test has been updated to use the new synchronous API of
renderTsCodeFileTemplate, passing template contents directly rather than using an async file-based approach.
52-55: Consistent API updates across test casesAll test cases have been consistently updated to use the new synchronous rendering API, improving test readability and maintainability.
Also applies to: 84-91, 130-133
149-197: Comprehensive test for multiple import mapsThis new test verifies an important capability - handling multiple import maps correctly. The test creates separate import maps and confirms they are properly merged and resolved during rendering.
packages/sync/src/templates/extractor/run-template-file-extractors.unit.test.ts (6)
24-25: Correctly updates to single output directory pattern.The refactoring from multiple output directories to a single
outputDirectoryvariable aligns with the function signature change in the implementation. This simplification makes the code easier to maintain and understand.
58-92: Test data setup properly updated for single directory pattern.The file system mock has been successfully updated to use the single output directory, maintaining test coverage while aligning with the new implementation.
100-105: Function call signature correctly updated.The call to
runTemplateFileExtractorsnow passes a single output directory instead of an array, matching the updated function signature.
114-148: Expectations properly updated to use single output directory.The tests now correctly verify that the extractor is called with file paths based on the single output directory.
151-223: Successfully refactored duplicate template test case.This test has been properly updated to use the single output directory while still testing the important behavior of selecting the most recently modified template file when duplicates exist.
225-256: Error handling test successfully updated.The test for the error scenario has been properly updated to use the single output directory.
packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.ts (4)
3-6: Well-structured regular expressions for template variable handling.The regular expressions are clearly defined to match template variable blocks and hoisted code blocks with appropriate naming conventions.
8-19: Clear documentation of function purpose and behavior.The JSDoc comments effectively explain the function's purpose, behavior, and parameters.
20-37: Robust template variable processing with error handling.The code correctly extracts declared variables, processes the template content, and provides meaningful error messages for unknown variables.
38-46: Thorough validation of template variables.The code ensures all declared variables are present in the content, providing a safeguard against metadata-content inconsistencies.
packages/sync/src/runner/runner-context.ts (4)
1-13: Good use of AsyncLocalStorage for context management.The implementation uses Node.js's AsyncLocalStorage appropriately to maintain context across asynchronous operations. The interface is well-defined with proper documentation.
14-23: Clean implementation of context wrapper function.The
runInRunnerContextfunction provides a clear API for executing functions within a specific runner context.
25-35: Correctly documented getter with usage warning.The
getRunnerContextfunction is properly documented with a clear warning about its intended use for debugging and testing only, which helps prevent misuse in production code.
1-35:Details
✅ Verification successful
Verify integration with task execution flow.
Since this is a new module that provides context management for generator runners, ensure it's properly integrated with the task execution flow in the generator runner.
🏁 Script executed:
#!/bin/bash # Check how the runner context is used in the generator runner rg -A 3 -B 2 "runInRunnerContext|getRunnerContext" "packages/sync/src/runner"Length of output: 3697
Integration Confirmed: Runner Context Management in Task Execution Flow
The new context module is properly integrated:
- The functions
runInRunnerContextandgetRunnerContextare used in the main generator runner (packages/sync/src/runner/generator-runner.ts) to manage task execution contexts.- Unit tests in
packages/sync/src/runner/generator-runner.unit.test.tscorrectly verify that the task context (e.g.,taskId) is captured and accessible viagetRunnerContext.No further modifications are necessary.
packages/sync/src/templates/metadata/write-generators-metadata.unit.test.ts (3)
25-52: Successfully simplified test for single generator.The test has been updated to remove the
filesparameter from the call towriteGeneratorsMetadata, aligning with the implementation changes.
54-98: Updated nested generators test with correct paths.The nested generators test has been properly updated with the new base directory path and expected output format. The mock implementations have been adjusted to match the new structure.
54-98:Details
❓ Verification inconclusive
Verify calculation of relative paths in implementation.
The test expects the metadata to contain relative paths like
'src/test'and'src/child', but it's not immediately clear how the implementation derives these paths from the base directories.
🏁 Script executed:
#!/bin/bash # Examine how write-generators-metadata.ts calculates relative paths cat packages/sync/src/templates/metadata/write-generators-metadata.ts | grep -A 20 "writeGeneratorsMetadata"Length of output: 519
Action Required: Please verify how
buildGeneratorInfoMapRecursivederives relative paths.The
writeGeneratorsMetadatafunction delegates the path calculation tobuildGeneratorInfoMapRecursive, and the test expects generator paths like'src/test'and'src/child'derived from the provided absolutebaseDirectoryvalues. However, it's not immediately clear from the snippet how these relative paths (with an injected"src"directory) are computed.
- Please confirm that
buildGeneratorInfoMapRecursivecalculates the relative path by:
- Using the package root (obtained via
findNearestPackageJson)- Converting the absolute base directory to a path relative to that package root, with necessary transformations (e.g., replacing
"dist"with"src").If the current implementation performs these calculations accurately, no changes are needed. Otherwise, please adjust the logic in
buildGeneratorInfoMapRecursiveaccordingly.packages/sync/src/templates/utils/formatter.ts (4)
1-6: Imports from Prettier look good.
They provide all the necessary utilities for formatting.
8-16: ALLOWED_EXTENSIONS enhances clarity and maintainability.
Defining a set of supported extensions prevents accidental formatting of unsupported files.
27-44: Robust fallback logic for Prettier config.
The function properly returns the default config ifresolveConfigFileorresolveConfigfails, ensuring consistent formatting.
56-67: Well-structured format function.
Usingfilepathin the Prettier options ensures correct parser selection.packages/core-generators/src/generators/node/node/package-dependencies-container.ts (4)
1-5: New imports align with usage of dynamic source.
They integrate cleanly with the field container concept from@halfdomelabs/utils.
15-15: Optional 'source' field clarifies dependency origin.
This addition helps trace dependencies. No issues found.
74-82: Assigning 'source' with conditional calls.
Gracefully handles undefined sources. This is consistent with the new optional property.
140-143: Factory function upgrade.
Providingoptionsfor dynamic sources maintains consistency with the container constructor.packages/fastify-generators/src/generators/core/fastify-sentry/index.ts (4)
14-15: Switch totsCodeFragmentandtsImportBuilder.
This change follows the new builder-based approach for generating TypeScript code and imports.
30-34: Refined imports for config service and error handler.
Consolidating imports in generator files improves clarity and maintainability.
84-86: Dependency injection forerrorHandlerServiceConfig.
This is a clean extension to integrate Sentry with error handling routines.
148-152: AddingSENTRY_DSNas a config field.
Registering the field with an optional string validator is a sensible default approach.packages/sync/src/templates/extractor/run-template-file-extractors.ts (4)
29-31: Function signature simplified to use a single output directoryThe function has been refactored to accept a single
outputDirectorystring instead of an array of directories, which simplifies the interface and aligns with the project's evolution toward a more focused template extraction approach.
35-38: Simplified generator info map creationThe generator info map creation is now streamlined to work with a single output directory, removing the previous complexity of merging multiple maps.
43-43: Added baseDirectory property to extractor creator contextThis change properly propagates the output directory as the base directory for extractors, ensuring they have the correct context for template extraction.
49-49: Simplified glob pattern for template metadata filesThe glob pattern has been updated to reflect the single output directory approach, making the code more straightforward and efficient.
packages/fastify-generators/src/generators/core/axios/index.ts (4)
6-8: Updated imports to use TypeScript fragment utilitiesReplaced the previous
TypescriptCodeUtilsimport with more specific utilities (tsCodeFragmentandtsImportBuilder), which aligns with the project's move toward a more modular approach to code generation.
13-13: Updated error handler service import pathThe import has been updated to use the new
errorHandlerServiceConfigProviderfrom the dedicated generator file, reflecting the modularization of the error handler service.
27-30: Updated dependency injection to use the new config providerThe dependencies and parameter names have been updated to use the new configuration provider pattern, ensuring compatibility with the refactored error handler service.
44-49: Refactored error handler integration to use declarative code fragmentsInstead of directly manipulating files with imperative code, the generator now pushes a code fragment to the error handler's context actions array. This is a significant improvement that:
- Makes the code more declarative and easier to understand
- Improves testability by reducing side effects
- Follows the new pattern of using typed code fragments
- Supports the modular architecture of the generator system
packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.unit.test.ts (4)
1-19: Well-structured test setup with proper imports and mocksThe test file correctly imports the necessary utilities and sets up filesystem mocking using
memfs, which is essential for isolated unit testing of file operations. ThebeforeEachhook ensures a clean state for each test.
24-91: Comprehensive test for rendering multiple templates with variablesThis test thoroughly verifies that the template group action can:
- Process a template group with multiple templates
- Apply different variables to each template
- Correctly output files with transformed content
- Maintain the expected directory structure
The test structure is clear, with a good setup-execute-verify pattern.
93-134: Proper testing of import resolution with custom module resolverThis test verifies the advanced capability to resolve import paths using a custom resolver function, which is crucial for maintaining correct module references in generated code. The test properly asserts both that the file was created and that its contents match the expected transformed output.
136-212: Thorough testing of import map handling in template groupsThis test correctly verifies that import maps are properly processed across multiple templates in a group, ensuring that placeholder imports are replaced with actual package paths. The test uses snapshots to verify the exact content formatting, which is appropriate for this use case.
packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.unit.test.ts (5)
1-19: Well-structured test setup with proper imports and mockingSimilar to the template group tests, this file correctly sets up the testing environment with appropriate imports and filesystem mocks to ensure isolated tests.
21-70: Comprehensive test for template file rendering with metadataThis test thoroughly verifies that the template file action:
- Correctly reads from template paths
- Replaces template variables with provided values
- Includes template metadata in the output when requested
- Sets the correct file ID based on generator and template information
The assertions are comprehensive and cover all aspects of the expected functionality.
72-101: Properly tests inline template content with importsThis test verifies that templates defined with inline content (rather than file paths) work correctly, especially when introducing imports for variables. This is an important use case for programmatically generated templates.
103-130: Robust error handling test for mismatched variablesThis test ensures that the action correctly validates that all required template variables are provided before rendering, preventing silent failures or incomplete template substitution. The explicit error testing is a good practice.
132-192: Thorough testing of multiple import mapsThis test correctly verifies that the template file action can handle multiple import maps simultaneously, replacing different placeholders with their respective mapped imports. The snapshot assertion provides a comprehensive check of the final formatted output.
packages/sync/src/templates/extractor/template-file-extractor.ts (5)
15-15: Good addition of formatGeneratedTemplateContents import.This change replaces direct Prettier calls with a centralized formatting utility, which will improve consistency and maintainability across template files.
50-53: Good addition of baseDirectory property.This property improves the context awareness of extractors by providing access to the project's root directory, which is essential for resolving relative paths correctly.
72-74: Well-designed accessor method for baseDirectory.The protected
getProjectBaseDirectory()method provides a clean way for subclasses to access the project root directory without directly accessing the context property.
108-115: Good refactoring of formatting logic.Replacing inline formatting with the centralized
formatGeneratedTemplateContentsutility improves consistency and maintainability. The type checking is preserved correctly.
147-150: Good refactoring of TypeScript file formatting.This change consistently applies the new formatting approach to TypeScript files as well, ensuring uniform formatting across all generated templates.
packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts (5)
1-8: Good test setup with appropriate imports.The imports are well-organized, including the necessary testing utilities and the types/functions being tested.
9-40: Well-structured test for basic template variable stripping.This test correctly verifies that template variable blocks are replaced with their variable names, using appropriate metadata setup and snapshot testing.
42-66: Comprehensive test for hoisted block removal.The test properly verifies that HOISTED blocks are completely removed from the template content, which is important for the template generation process.
103-123: Good error handling test for unknown template variables.This test correctly verifies that the function throws an appropriate error when encountering template variables not defined in the metadata.
125-147: Good error handling test for missing template variables.This test correctly verifies that the function throws an appropriate error when template variables defined in metadata are missing from the content.
packages/sync/src/templates/metadata/write-generators-metadata.ts (3)
16-16: Good simplification of condition.The simplified condition checks only if the generator name is already in the map, removing unnecessary complexity.
39-39: Good simplification of recursive call.Removed the unnecessary parameter from the recursive method call, consistent with the simplified approach.
52-57: Good simplification of method signature and implementation.Removing the
filesparameter simplifies the API and implementation, focusing only on the essential generator entry and output directory parameters.packages/core-generators/src/renderers/typescript/extractor/templates/imports-file.ts (1)
1-34: Well-structured template for import map provider generation.The template provides a consistent structure for generating TypeScript modules that create and export typed import map providers. It includes appropriate imports, type definitions, validation, and exports.
packages/core-generators/src/renderers/typescript/templates/creators.ts (1)
2-2: Types updated to align with schema-validated template system.The function has been updated to use the new
TsTemplateVariableMapandTsTemplateFiletypes instead of the older loosely-typed templates. This is part of the broader refactoring to improve type safety across the template creation, rendering, and extraction workflows.Also applies to: 4-4, 12-12, 18-19
packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts (1)
1-227: Well-structured test suite with comprehensive coverage.The tests thoroughly validate the
writeTsProjectExportsfunction's behavior, including:
- Handling empty project exports
- Processing various export types (regular and type-only)
- Path resolution differences between core and external generators
- Error handling for duplicate exports
- Proper path mapping generation
All test cases have clear assertions and good setup code.
packages/core-generators/src/renderers/typescript/extractor/organize-ts-template-imports.unit.test.ts (1)
1-136: Good test coverage for import organization functionality.This test suite effectively validates the
organizeTsTemplateImportsfunction, covering:
- Successful consolidation of imports and removal of unused ones
- Error handling for unsupported namespace imports
- Error handling for imports not found in project exports
The mock resolver pattern is well implemented and the test assertions are thorough.
packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts (3)
26-29: Import paths updated to use new TypeScript-specific modules.The imports have been updated to use the new modules with "ts-" prefixes, aligning with the TypeScript template rendering infrastructure introduced in this PR.
126-144: Template rendering refactored to use the new action-based approach.The implementation has been updated from the older async file writing method to the new action-based rendering system with
renderTemplateFile. However, the destination path is now hardcoded to'src/services/logger.ts', which might reduce flexibility for projects with different directory structures.Was hardcoding the destination path intentional? Consider if this path should be configurable based on project needs or derived from some configuration.
157-157: Export path updated to match new module structure.The export statement has been updated to match the new file structure with TypeScript-specific modules.
packages/core-generators/src/renderers/typescript/renderers/template.ts (7)
2-2: No issues with the new import.
This import helps define the type for template variable values. All good.
24-26: Exported function signature is appropriate.
Exporting the function with a clear param type ensures proper usage of template variables. No points of concern here.
44-63: Block template metadata handling looks solid.
The logic neatly inserts commented metadata blocks whenincludeMetadatais true, removing variables fromvariableKeys. This ensures correct detection of used variables. No major issues found.
65-66: Regex-based variable replacement approach is fine.
Using a capturing group with lookahead to match the prefix is a sound solution for variable substitution.
74-75: Variable tracking is properly updated.
Removing the key fromvariableKeyshelps ensure leftover variables are flagged later.
76-78: Inline metadata comment insertion is correct.
You are consistently wrapping replaced segments withSTART/ENDmarkers, promoting reliable reverse generation.
82-87: Unused variable detection is well-implemented.
Throwing an error for any leftover variables clarifies if references are missing in the template.packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (1)
34-137: Thorough test of variable logic and import cleanupThis test method provides solid coverage of variable replacement, hoisted block removal, and unused import cleanup. Great approach using in-memory FS; you might also consider a negative test that confirms behavior with malformed or missing variables.
packages/sync/src/templates/extractor/template-file-extractor-test-utils.ts (4)
10-13: Addition of second generator constantsThese constants facilitate testing multiple generators in parallel. Makes sense for broader coverage of multi-generator scenarios, improving test realism.
26-32: Great extension of generatorInfoMapIncluding the second generator in
generatorInfoMapbroadens the test context. This helps robustly verify cross-generator references and import resolution.
46-50: Expanded exports for second generatorExposing new constants for the second generator aligns with multi-generator testing. This fosters uniform naming and easy reference in tests.
63-80: Addition of outputPath utilityThe
outputPathutility centralizes path generation for test outputs, reducing potential path-handling bugs and improving readability.packages/core-generators/src/renderers/typescript/extractor/organize-ts-template-imports.ts (4)
1-14: Consider verifying module versions
While these imports are essential for code transformations, confirm that the current versions ofoxc-resolverandts-morphare compatible with the rest of your toolchain.Would you like me to provide a script to confirm the package versions used in the codebase?
26-37: Comprehensive docstring
The documentation is thorough and clearly outlines the function's purpose, steps, and return value. This level of clarity will benefit maintainers and foster readability.
38-63: Be cautious withorganizeImports()
The call tosourceFile.organizeImports()may remove imports perceived as unused but still needed in certain circumstances (e.g., for type augmentation). Ensure you have robust test coverage around tricky or borderline cases.
64-148: Efficient concurrency withPromise.all()
Resolving imports concurrently is a sensible design choice, but be mindful of scaling to large codebases. If performance becomes an issue, consider caching resolution results or introducing streaming mechanisms to handle massive imports.packages/core-generators/src/renderers/typescript/actions/render-ts-template-group-action.ts (2)
1-12: Avoid naming conflicts
All imported types appear valid. Double-check for potential naming collisions with other modules in the codebase or third-party libraries.
47-72: Flexible interface design
Allowing partial or required template variables based on the presence of generics strikes a good balance between strict typing and usability. This is a neat approach to type safety.packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts (3)
15-29: Well-structured config provider task
The separation of error-handler config creation into its own provider task is both clean and maintainable, ensuring each concern is neatly isolated.
71-125: Confirm plugin and template registration
Check that each newly introduced generator task consistently renders or registers the TypeScript files for the error handler, ensuring the plugin is properly integrated and discoverable at runtime.
127-172: Validate dynamic error logging merges
CombiningcontextActionsandloggerActionsviaTsCodeUtils.mergeFragmentsis a neat pattern. Confirm the final expansions function as intended under various runtime conditions.packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts (1)
120-153: Confirm default environment variable coverage.
Here, onlyAPP_ENVIRONMENTis defined, with defaults like'development'or'production'. For more robust setups, consider adding standard fields (e.g.,PORT,DATABASE_URL) or ensuring that user-defined fields can be appended easily.Would you like to add more environment variables or clarify how users should add them?
packages/core-generators/src/renderers/typescript/renderers/file.ts (2)
79-92: Hoisted fragments writing approach looks solid.
This utility functionwriteHoistedFragmentsneatly handles metatagging withHOISTED:${h.key}:START/END. It’s a clean solution for controlling fragment placement.
117-118: Retain partial, minimal duplication checks.
renderTsTemplateToTsCodeFragmentalready handles unused variables. If there’s any chance of re-invoking it with the same variables, confirm that no duplication occurs across calls.packages/core-generators/src/generators/node/typescript/index.ts (2)
19-23: Good introduction of typed render payloads.
These new types (RenderTsTemplateFileActionInputand friends) standardize the template rendering approach, improving maintainability.
151-152: No immediate concerns with setup task usage.
Thesetup: createGeneratorTask(setupTask)pattern is consistent with the rest of the code, ensuring typed configuration merges.packages/core-generators/src/renderers/typescript/templates/types.ts (3)
12-36: Leverage the template metadata for robust type safety.
The extended schema properly requirestype: z.literal(TS_TEMPLATE_TYPE). This approach locks in strong correctness guarantees for TypeScript-based templates. No issues at a glance.
74-80: Check runtime edge cases for variable naming.
InferTsTemplateVariablesFromMapexpects uppercase, prefix-based replacements from upstream. If users supply lowercased or unpredictable keys, they may hit errors. A warning or fallback might help.
88-98: Factory function usage is helpful.
createTsTemplateFilecentralizes file creation logic. The typed approach is straightforward, guaranteeing correct inference for variables and providers.packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts (4)
67-70: Scrutinize extension aliases for potential coverage gaps.The extension alias covers a variety of TS/JS extensions, but you might want to confirm usage scenarios for
.tsx,.cts,.mts, etc. Specifically, consider whether the existing.replace(/\.ts$/, '.js')logic aligns with all mapped extensions in these aliases or if additional transformations for.tsxor others might be necessary.
113-133: Validate import source rewriting logic and potential multi-extension scenarios.The block generating
usedImportProvidersrewrites the.tsextension to.jsfor import sources. Ensure that this step remains consistent with your extension alias strategy. If you need to handle.tsxor other variants, consider broadening the replacement to avoid resolution issues for template files with non-.tsextensions.
223-224: Appreciate concurrency limit usage.Applying
pLimitto manage the extraction concurrency is a prudent choice for large codebases, preventing excessive resource consumption. This design ensures stable performance under heavy loads and is a well-structured approach.
319-375: Overall code structure and maintainability.The top-level logic in
extractTemplateFiles—grouping by generator, generating import files, checking for duplicate providers, and proceeding with extraction—is well-organized. It cleanly separates concerns and makes the workflow easy to follow.
| // Remove HOISTED blocks | ||
| processedContent = processedContent.replaceAll(HOISTED_REGEX, ''); | ||
|
|
||
| return processedContent; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Consider adding unit tests for edge cases.
The implementation handles the happy path and basic error cases, but consider adding tests for edge cases such as:
- Multiple occurrences of the same variable
- Variable blocks with nested content
- Malformed variable blocks (missing END tags)
🏁 Script executed:
#!/bin/bash
# Check if unit tests exist for strip-ts-template-variables.ts
fd --type f "strip-ts-template-variables.unit.test.ts" -x cat {} \; | grep -E "describe|it|test"Length of output: 1126
Add Additional Edge Case Unit Tests for Template Variable Extraction
The current unit tests cover the basic functionality (e.g., stripping template variables and removing HOISTED blocks) as evidenced by the test output. However, it appears that the following edge cases are not explicitly tested:
- Multiple occurrences of the same variable
- Variable blocks with nested content
- Malformed variable blocks (e.g., missing END tags)
Please consider adding targeted tests to cover these scenarios in the unit test file (packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts).
packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (1)
19-31: Mock resolver could be improved with more comprehensive testing scenarios.The mock resolver implementation is simplistic and only handles the happy path. Consider extending it to simulate resolution failures to test error handling.
function createMockResolver(): ResolverFactory { return { async: vi.fn().mockImplementation((folder: string, source: string) => Promise.resolve({ path: source.startsWith('./') ? path.join(folder, source.slice(2)) : source, error: null, }), ), + // Add cases to simulate resolution failures + // For example, to test specific import paths: + // if (source.includes('non-existent')) { + // return Promise.resolve({ path: null, error: new Error('Cannot find module') }); + // } sync: vi.fn(), } as unknown as ResolverFactory; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite
📒 Files selected for processing (4)
.changeset/witty-keys-relate.md(1 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .changeset/witty-keys-relate.md
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/core-generators/src/renderers/typescript/extractor/strip-ts-template-variables.unit.test.ts
- packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (3)
packages/sync/src/templates/extractor/template-file-extractor-test-utils.ts (2)
TemplateFileExtractorTestUtils(40-81)templatePath(63-74)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts (1)
TsTemplateFileExtractor(52-375)packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TS_TEMPLATE_TYPE(10-10)
🔇 Additional comments (5)
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (5)
1-13: Well structured imports and mocking setup.The file correctly imports the necessary dependencies, including mocking the filesystem modules with
memfs. Good separation between external libraries, internal modules, and Node.js built-ins.
14-17: Appropriate test lifecycle hooks.Good practice to reset the virtual filesystem and clear mocks before each test to ensure test isolation.
33-137: The first test case comprehensively validates core template extraction functionality.The test successfully verifies that the extractor:
- Properly removes hoisted code blocks
- Replaces template variables with their placeholder names
- Cleans up unused imports
- Generates correct template definition files
The snapshot assertions provide strong guarantees against regressions.
139-246: Strong verification of import map generation.This test thoroughly validates that the generated import maps:
- Include the correct schema definitions
- Generate proper provider types
- Create appropriate path mappings for exports
- Handle type-only exports correctly
The detailed assertions and snapshots will catch any regressions in import map generation.
248-477: Great cross-generator import resolution test.This test effectively verifies that imports between different generators are properly resolved, which is a key feature for a modular template system. It confirms:
- Import maps are generated for both generators
- Cross-generator imports are transformed to use provider imports
- Generator-local imports remain as relative paths
The transformation of
import { FirstComponent } from './first-component.ts'toimport { FirstComponent } from '%testGeneratorImports'is a critical validation of the import resolution mechanism.
| import type { ResolverFactory } from 'oxc-resolver'; | ||
|
|
||
| import { TemplateFileExtractorTestUtils } from '@halfdomelabs/sync'; | ||
| import { vol } from 'memfs'; | ||
| import path from 'node:path'; | ||
| import { beforeEach, describe, expect, it, vi } from 'vitest'; | ||
|
|
||
| import { TS_TEMPLATE_TYPE } from '../templates/types.js'; | ||
| import { TsTemplateFileExtractor } from './ts-template-file-extractor.js'; | ||
|
|
||
| vi.mock('node:fs/promises'); | ||
| vi.mock('node:fs'); | ||
|
|
||
| beforeEach(() => { | ||
| vol.reset(); | ||
| vi.clearAllMocks(); | ||
| }); | ||
|
|
||
| function createMockResolver(): ResolverFactory { | ||
| return { | ||
| async: vi.fn().mockImplementation((folder: string, source: string) => | ||
| Promise.resolve({ | ||
| path: source.startsWith('./') | ||
| ? path.join(folder, source.slice(2)) | ||
| : source, | ||
| error: null, | ||
| }), | ||
| ), | ||
| sync: vi.fn(), | ||
| } as unknown as ResolverFactory; | ||
| } | ||
|
|
||
| describe('TsTemplateFileExtractor', () => { | ||
| it('should extract TS template file, replace variables, remove hoisted, and clean imports', async () => { | ||
| const context = | ||
| TemplateFileExtractorTestUtils.createTestTemplateFileExtractorContext(); | ||
| const mockResolver = createMockResolver(); | ||
| const extractor = new TsTemplateFileExtractor(context, { | ||
| pathResolver: mockResolver, | ||
| }); | ||
|
|
||
| const inputFilePath = | ||
| TemplateFileExtractorTestUtils.outputPath('my-component.ts'); | ||
| const templatePath = 'my-component.ts'; // Relative path for metadata/output | ||
|
|
||
| vol.fromJSON({ | ||
| [inputFilePath]: ` | ||
| import { A, B, C, D } from 'external-package'; | ||
| import { Z } from './unused-import.ts'; | ||
|
|
||
| /* HOISTED:HELPER_FN:START */ | ||
| function helper() { | ||
| console.log('This should be removed'); | ||
| } | ||
| /* HOISTED:HELPER_FN:END */ | ||
|
|
||
| export function /* TPL_COMPONENT_NAME:START */MyComponent/* TPL_COMPONENT_NAME:END */() { | ||
| const msg = /* TPL_MESSAGE:START */'hello'/* TPL_MESSAGE:END */; | ||
| const x: A = new A(); | ||
| const y: B = { prop: /* TPL_PROP_VALUE:START */123/* TPL_PROP_VALUE:END */ }; | ||
| return \`\${msg} \${x} \${y}\`; | ||
| } | ||
|
|
||
| // Another hoisted block | ||
| /* HOISTED:ANOTHER:START */ | ||
| const removedVar = 1; | ||
| /* HOISTED:ANOTHER:END */ | ||
| `, | ||
| }); | ||
|
|
||
| await extractor.extractTemplateFiles([ | ||
| { | ||
| path: inputFilePath, | ||
| metadata: { | ||
| name: 'myComponentTemplate', // Camelcase name for the template object | ||
| type: TS_TEMPLATE_TYPE, | ||
| generator: TemplateFileExtractorTestUtils.TEST_GENERATOR_NAME, | ||
| template: templatePath, // Path relative to templates dir | ||
| variables: { | ||
| TPL_COMPONENT_NAME: {}, | ||
| TPL_MESSAGE: {}, | ||
| TPL_PROP_VALUE: {}, | ||
| }, | ||
| }, | ||
| }, | ||
| ]); | ||
|
|
||
| const result = vol.toJSON(); | ||
| const generatedTemplatePath = | ||
| TemplateFileExtractorTestUtils.templatePath(templatePath); | ||
| const generatedDefinitionPath = | ||
| TemplateFileExtractorTestUtils.generatedPath('ts-templates.ts'); | ||
|
|
||
| // 1. Check the generated template file content | ||
| expect(result[generatedTemplatePath]).toBeDefined(); | ||
| expect(result[generatedTemplatePath]).toContain('TPL_COMPONENT_NAME'); | ||
| expect(result[generatedTemplatePath]).toContain('TPL_MESSAGE'); | ||
| expect(result[generatedTemplatePath]).toContain('TPL_PROP_VALUE'); | ||
| expect(result[generatedTemplatePath]).not.toContain('/* HOISTED:'); | ||
| expect(result[generatedTemplatePath]).not.toContain('helper()'); | ||
| expect(result[generatedTemplatePath]).not.toContain('unused-import'); // Import should be removed | ||
| expect(result[generatedTemplatePath]).not.toContain(' C, D'); // Unused named import C | ||
| expect(result[generatedTemplatePath]).toContain(' A, B '); // Used named imports A and B | ||
|
|
||
| // Snapshot the template file for detailed verification | ||
| expect(result[generatedTemplatePath]).toMatchInlineSnapshot(` | ||
| "// @ts-nocheck | ||
|
|
||
| import { A, B } from 'external-package'; | ||
|
|
||
| export function TPL_COMPONENT_NAME() { | ||
| const msg = TPL_MESSAGE; | ||
| const x: A = new A(); | ||
| const y: B = { prop: TPL_PROP_VALUE }; | ||
| return \`\${msg} \${x} \${y}\`; | ||
| } | ||
|
|
||
| // Another hoisted block | ||
| " | ||
| `); | ||
|
|
||
| // 2. Check the generated definition file content | ||
| expect(result[generatedDefinitionPath]).toBeDefined(); | ||
| expect(result[generatedDefinitionPath]).toMatchInlineSnapshot(` | ||
| "import { createTsTemplateFile } from '@halfdomelabs/core-generators'; | ||
|
|
||
| const myComponentTemplate = createTsTemplateFile({ | ||
| name: 'myComponentTemplate', | ||
| source: { path: 'my-component.ts' }, | ||
| variables: { TPL_COMPONENT_NAME: {}, TPL_MESSAGE: {}, TPL_PROP_VALUE: {} }, | ||
| projectExports: {}, | ||
| }); | ||
|
|
||
| export const TEST_GENERATOR_TS_TEMPLATES = { myComponentTemplate }; | ||
| " | ||
| `); | ||
| }); | ||
|
|
||
| it('should generate import maps file for project exports', async () => { | ||
| const context = | ||
| TemplateFileExtractorTestUtils.createTestTemplateFileExtractorContext(); | ||
| const mockResolver = createMockResolver(); | ||
| const extractor = new TsTemplateFileExtractor(context, { | ||
| pathResolver: mockResolver, | ||
| }); | ||
| const inputFilePath = TemplateFileExtractorTestUtils.outputPath( | ||
| 'components/test-component.ts', | ||
| ); | ||
|
|
||
| vol.fromJSON({ | ||
| [inputFilePath]: ` | ||
| export const TestComponent = () => {}; | ||
| export type TestComponentProps = {}; | ||
| `, | ||
| }); | ||
|
|
||
| await extractor.extractTemplateFiles([ | ||
| { | ||
| path: inputFilePath, | ||
| metadata: { | ||
| type: TS_TEMPLATE_TYPE, | ||
| name: 'testComponent', | ||
| generator: 'test-package#test-generator', | ||
| template: 'test-component.ts', | ||
| variables: {}, | ||
| projectExports: { | ||
| TestComponent: { isTypeOnly: false }, | ||
| TestComponentProps: { isTypeOnly: true }, | ||
| }, | ||
| }, | ||
| }, | ||
| ]); | ||
|
|
||
| const result = vol.toJSON(); | ||
| const generatedImportsPath = | ||
| TemplateFileExtractorTestUtils.generatedPath('ts-import-maps.ts'); | ||
|
|
||
| // Check that the import maps file was generated | ||
| expect(result[generatedImportsPath]).toBeDefined(); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| 'testGeneratorImportsSchema', | ||
| ); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| 'TestGeneratorImportsProvider', | ||
| ); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| 'testGeneratorImportsProvider', | ||
| ); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| 'createTestGeneratorImports', | ||
| ); | ||
|
|
||
| // Check that the exports are included | ||
| expect(result[generatedImportsPath]).toContain('TestComponent: {}'); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| 'TestComponentProps: { isTypeOnly: true }', | ||
| ); | ||
|
|
||
| // Check the path mapping | ||
| expect(result[generatedImportsPath]).toContain( | ||
| "TestComponent: path.join(importBase, 'test-component.js')", | ||
| ); | ||
| expect(result[generatedImportsPath]).toContain( | ||
| "TestComponentProps: path.join(importBase, 'test-component.js')", | ||
| ); | ||
|
|
||
| // Snapshot the imports file for detailed verification | ||
| expect(result[generatedImportsPath]).toMatchInlineSnapshot(` | ||
| "import type { TsImportMapProviderFromSchema } from '@halfdomelabs/core-generators'; | ||
|
|
||
| import { | ||
| createTsImportMapProvider, | ||
| createTsImportMapSchema, | ||
| } from '@halfdomelabs/core-generators'; | ||
| import { createReadOnlyProviderType } from '@halfdomelabs/sync'; | ||
| import path from 'node:path/posix'; | ||
|
|
||
| const testGeneratorImportsSchema = createTsImportMapSchema({ | ||
| TestComponent: {}, | ||
| TestComponentProps: { isTypeOnly: true }, | ||
| }); | ||
|
|
||
| type TestGeneratorImportsProvider = TsImportMapProviderFromSchema< | ||
| typeof testGeneratorImportsSchema | ||
| >; | ||
|
|
||
| export const testGeneratorImportsProvider = | ||
| createReadOnlyProviderType<TestGeneratorImportsProvider>( | ||
| 'test-generator-imports', | ||
| ); | ||
|
|
||
| export function createTestGeneratorImports( | ||
| importBase: string, | ||
| ): TestGeneratorImportsProvider { | ||
| if (!importBase.startsWith('@/')) { | ||
| throw new Error('importBase must start with @/'); | ||
| } | ||
|
|
||
| return createTsImportMapProvider(testGeneratorImportsSchema, { | ||
| TestComponent: path.join(importBase, 'test-component.js'), | ||
| TestComponentProps: path.join(importBase, 'test-component.js'), | ||
| }); | ||
| } | ||
| " | ||
| `); | ||
| }); | ||
|
|
||
| it('should handle import provider resolution across multiple generators', async () => { | ||
| const context = | ||
| TemplateFileExtractorTestUtils.createTestTemplateFileExtractorContext(); | ||
| const mockResolver = createMockResolver(); | ||
| const extractor = new TsTemplateFileExtractor(context, { | ||
| pathResolver: mockResolver, | ||
| }); | ||
|
|
||
| // Set up first generator files | ||
| const firstGeneratorName = | ||
| TemplateFileExtractorTestUtils.TEST_GENERATOR_NAME; | ||
| const firstComponentPath = TemplateFileExtractorTestUtils.outputPath( | ||
| 'components/first-component.ts', | ||
| ); | ||
| const firstUtilPath = TemplateFileExtractorTestUtils.outputPath( | ||
| 'components/first-util.ts', | ||
| ); | ||
|
|
||
| vol.fromJSON({ | ||
| [firstComponentPath]: ` | ||
| import { FirstUtil } from './first-util.ts'; | ||
|
|
||
| export function FirstComponent() { | ||
| return FirstUtil(); | ||
| } | ||
| `, | ||
| [firstUtilPath]: ` | ||
| export function FirstUtil() { | ||
| return 'first'; | ||
| } | ||
| `, | ||
| }); | ||
|
|
||
| // Set up second generator files | ||
| const secondGeneratorName = | ||
| TemplateFileExtractorTestUtils.TEST_GENERATOR_2_NAME; | ||
| const secondComponentPath = TemplateFileExtractorTestUtils.outputPath( | ||
| 'components/second-component.ts', | ||
| ); | ||
| const secondUtilPath = TemplateFileExtractorTestUtils.outputPath( | ||
| 'components/second-util.ts', | ||
| ); | ||
|
|
||
| vol.fromJSON({ | ||
| [secondComponentPath]: ` | ||
| import { SecondUtil } from './second-util.ts'; | ||
| import { FirstComponent } from './first-component.ts'; | ||
|
|
||
| export function SecondComponent() { | ||
| return FirstComponent() + SecondUtil(); | ||
| } | ||
| `, | ||
| [secondUtilPath]: ` | ||
| export function SecondUtil() { | ||
| return 'second'; | ||
| } | ||
| `, | ||
| }); | ||
|
|
||
| // Extract files from both generators | ||
| await extractor.extractTemplateFiles([ | ||
| { | ||
| path: firstComponentPath, | ||
| metadata: { | ||
| type: TS_TEMPLATE_TYPE, | ||
| name: 'firstComponent', | ||
| generator: firstGeneratorName, | ||
| template: 'first-component.ts', | ||
| variables: {}, | ||
| projectExports: { | ||
| FirstComponent: { isTypeOnly: false }, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| path: firstUtilPath, | ||
| metadata: { | ||
| type: TS_TEMPLATE_TYPE, | ||
| name: 'firstUtil', | ||
| generator: firstGeneratorName, | ||
| template: 'first-util.ts', | ||
| variables: {}, | ||
| projectExports: { | ||
| FirstUtil: { isTypeOnly: false }, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| path: secondComponentPath, | ||
| metadata: { | ||
| type: TS_TEMPLATE_TYPE, | ||
| name: 'secondComponent', | ||
| generator: secondGeneratorName, | ||
| template: 'second-component.ts', | ||
| variables: {}, | ||
| projectExports: { | ||
| SecondComponent: { isTypeOnly: false }, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| path: secondUtilPath, | ||
| metadata: { | ||
| type: TS_TEMPLATE_TYPE, | ||
| name: 'secondUtil', | ||
| generator: secondGeneratorName, | ||
| template: 'second-util.ts', | ||
| variables: {}, | ||
| projectExports: { | ||
| SecondUtil: { isTypeOnly: false }, | ||
| }, | ||
| }, | ||
| }, | ||
| ]); | ||
|
|
||
| const result = vol.toJSON(); | ||
| const firstGeneratorImportsPath = | ||
| TemplateFileExtractorTestUtils.generatedPath( | ||
| 'ts-import-maps.ts', | ||
| firstGeneratorName, | ||
| ); | ||
| const secondGeneratorImportsPath = | ||
| TemplateFileExtractorTestUtils.generatedPath( | ||
| 'ts-import-maps.ts', | ||
| secondGeneratorName, | ||
| ); | ||
|
|
||
| // Check that import maps were generated for both generators | ||
| expect(result[firstGeneratorImportsPath]).toBeDefined(); | ||
| expect(result[secondGeneratorImportsPath]).toBeDefined(); | ||
|
|
||
| // Check first generator imports | ||
| expect(result[firstGeneratorImportsPath]).toContain('FirstComponent'); | ||
| expect(result[firstGeneratorImportsPath]).toContain('FirstUtil'); | ||
|
|
||
| // Check second generator imports | ||
| expect(result[secondGeneratorImportsPath]).toContain('SecondComponent'); | ||
| expect(result[secondGeneratorImportsPath]).toContain('SecondUtil'); | ||
|
|
||
| expect(result[firstGeneratorImportsPath]).toMatchInlineSnapshot(` | ||
| "import type { TsImportMapProviderFromSchema } from '@halfdomelabs/core-generators'; | ||
|
|
||
| import { | ||
| createTsImportMapProvider, | ||
| createTsImportMapSchema, | ||
| } from '@halfdomelabs/core-generators'; | ||
| import { createReadOnlyProviderType } from '@halfdomelabs/sync'; | ||
| import path from 'node:path/posix'; | ||
|
|
||
| const testGeneratorImportsSchema = createTsImportMapSchema({ | ||
| FirstComponent: {}, | ||
| FirstUtil: {}, | ||
| }); | ||
|
|
||
| type TestGeneratorImportsProvider = TsImportMapProviderFromSchema< | ||
| typeof testGeneratorImportsSchema | ||
| >; | ||
|
|
||
| export const testGeneratorImportsProvider = | ||
| createReadOnlyProviderType<TestGeneratorImportsProvider>( | ||
| 'test-generator-imports', | ||
| ); | ||
|
|
||
| export function createTestGeneratorImports( | ||
| importBase: string, | ||
| ): TestGeneratorImportsProvider { | ||
| if (!importBase.startsWith('@/')) { | ||
| throw new Error('importBase must start with @/'); | ||
| } | ||
|
|
||
| return createTsImportMapProvider(testGeneratorImportsSchema, { | ||
| FirstComponent: path.join(importBase, 'first-component.js'), | ||
| FirstUtil: path.join(importBase, 'first-util.js'), | ||
| }); | ||
| } | ||
| " | ||
| `); | ||
|
|
||
| // Check that the generated template files have the correct imports | ||
| const firstComponentTemplatePath = | ||
| TemplateFileExtractorTestUtils.templatePath( | ||
| 'first-component.ts', | ||
| firstGeneratorName, | ||
| ); | ||
| const secondComponentTemplatePath = | ||
| TemplateFileExtractorTestUtils.templatePath( | ||
| 'second-component.ts', | ||
| secondGeneratorName, | ||
| ); | ||
|
|
||
| expect(result[firstComponentTemplatePath]).toContain( | ||
| "import { FirstUtil } from './first-util.ts'", | ||
| ); | ||
| expect(result[secondComponentTemplatePath]).toContain( | ||
| "import { SecondUtil } from './second-util.ts'", | ||
| ); | ||
| expect(result[secondComponentTemplatePath]).toContain( | ||
| "import { FirstComponent } from '%testGeneratorImports'", | ||
| ); | ||
|
|
||
| expect(result[secondComponentTemplatePath]).toMatchInlineSnapshot(` | ||
| "// @ts-nocheck | ||
|
|
||
| import { FirstComponent } from '%testGeneratorImports'; | ||
|
|
||
| import { SecondUtil } from './second-util.ts'; | ||
|
|
||
| export function SecondComponent() { | ||
| return FirstComponent() + SecondUtil(); | ||
| } | ||
| " | ||
| `); | ||
|
|
||
| // Check that the template definitions are correct | ||
| const firstGeneratorTemplatesPath = | ||
| TemplateFileExtractorTestUtils.generatedPath( | ||
| 'ts-templates.ts', | ||
| firstGeneratorName, | ||
| ); | ||
| const secondGeneratorTemplatesPath = | ||
| TemplateFileExtractorTestUtils.generatedPath( | ||
| 'ts-templates.ts', | ||
| secondGeneratorName, | ||
| ); | ||
|
|
||
| expect(result[firstGeneratorTemplatesPath]).toContain('firstComponent'); | ||
| expect(result[firstGeneratorTemplatesPath]).toContain('firstUtil'); | ||
| expect(result[secondGeneratorTemplatesPath]).toContain('secondComponent'); | ||
| expect(result[secondGeneratorTemplatesPath]).toContain('secondUtil'); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding error case tests.
The test suite thoroughly covers the happy path, but lacks tests for error conditions that could occur in real usage. Adding tests for the following scenarios would improve robustness:
- Duplicate export names across files
- Invalid template variable syntax
- Missing required metadata fields
- Import resolution failures
- Circular dependencies between generators
it('should throw error when detecting duplicate export names', async () => {
const context = TemplateFileExtractorTestUtils.createTestTemplateFileExtractorContext();
const extractor = new TsTemplateFileExtractor(context, {
pathResolver: createMockResolver(),
});
// Set up files with duplicate export names
const file1Path = TemplateFileExtractorTestUtils.outputPath('file1.ts');
const file2Path = TemplateFileExtractorTestUtils.outputPath('file2.ts');
vol.fromJSON({
[file1Path]: `export const DuplicateExport = () => {};`,
[file2Path]: `export const DuplicateExport = () => {};`,
});
// Expect the extraction to throw due to duplicate export names
await expect(extractor.extractTemplateFiles([
{
path: file1Path,
metadata: {
type: TS_TEMPLATE_TYPE,
name: 'file1',
generator: TemplateFileExtractorTestUtils.TEST_GENERATOR_NAME,
template: 'file1.ts',
variables: {},
projectExports: { DuplicateExport: { isTypeOnly: false } },
},
},
{
path: file2Path,
metadata: {
type: TS_TEMPLATE_TYPE,
name: 'file2',
generator: TemplateFileExtractorTestUtils.TEST_GENERATOR_NAME,
template: 'file2.ts',
variables: {},
projectExports: { DuplicateExport: { isTypeOnly: false } },
},
},
])).rejects.toThrow(/Duplicate project export/);
});
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
quotto a dedicated package.Tests
Chores