-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Implement Typescript v2 extractors #571
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: Implement Typescript v2 extractors #571
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
WalkthroughThis change introduces a comprehensive new "extractor-v2" system for TypeScript template extraction and code generation. It adds new extractor implementations, plugins for barrel export management, utilities for organizing imports, and project export mapping. The update includes new configuration files, test utilities, and integration points, while refactoring or removing legacy extractor logic. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ProjectBuilder
participant FileIdMap
participant ExtractorV2
participant Plugins
participant BarrelExport
participant ImportProvider
participant TypedTemplates
User->>ProjectBuilder: Initiate code generation
ProjectBuilder->>FileIdMap: getPreviousGeneratedFileIdMap()
FileIdMap-->>ProjectBuilder: Map<fileId, relativePath>
ProjectBuilder->>ExtractorV2: runTemplateFileExtractors(..., fileIdMap)
ExtractorV2->>Plugins: initialize and run hooks
ExtractorV2->>ExtractorV2: Extract template metadata
ExtractorV2->>Plugins: afterExtract hooks
ExtractorV2->>ExtractorV2: Write template files
ExtractorV2->>BarrelExport: Register barrel exports
ExtractorV2->>ImportProvider: Render import providers
ExtractorV2->>TypedTemplates: Render typed templates
ExtractorV2->>Plugins: afterWrite hooks
ExtractorV2->>FileIdMap: writeGeneratedFileIdMap()
FileIdMap-->>ProjectBuilder: Done
ProjectBuilder-->>User: Generation complete
Possibly related PRs
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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: 10
🔭 Outside diff range comments (1)
packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.ts (1)
35-41:⚠️ Potential issueHandle missing
templatessection to avoid a runtime crash
generatorConfig.configmay legitimately omit thetemplateskey on first extraction.
When that happensObject.entries(templates)will receive undefined and throw.-const { name, templates, extractors, ...rest } = generatorConfig.config; +const { + name, + templates = {}, // ✅ default to empty object + extractors, + ...rest +} = generatorConfig.config;A defensive default prevents the whole merge from failing on an empty config.
🧹 Nitpick comments (43)
packages/fastify-generators/src/generators/core/readme/extractor.json (1)
9-9: Ensure missing default is handled & consider marking as required
The"default"field was removed fromTPL_PROJECT, so consumers must now supply this value at generation time.
- Verify that the extractor framework gracefully handles a missing
default(i.e., doesn’t error or fall back incorrectly).- Optionally, add a
"required": trueflag to the variable definition to make intent explicit.packages/fastify-generators/src/generators/prisma/prisma/prisma.generator.ts (1)
33-33: Consider simplifying the import by dropping the explicitindex.jssuffix.Node/TypeScript will resolve
indexfiles automatically. For consistency and brevity, you could use:-import { configServiceProvider } from '#src/generators/core/config-service/index.js'; +import { configServiceProvider } from '#src/generators/core/config-service';packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts (1)
21-34: Heavy repetition – extract a helper to build test filesEvery test now repeats the same
fileOptions,type,generator, etc. Consider introducing a small factory, e.g.function testFile( override: Partial<TsTemplateOutputTemplateMetadata> = {}, path = '/test/path/file1.ts', ): TemplateFileExtractorFile<TsTemplateOutputTemplateMetadata> { return { path, metadata: { type: 'ts', generator: TEST_GENERATOR_NAME, name: 'test', template: '', fileOptions: { kind: 'singleton' }, ...override, }, }; }This keeps each test focused on what it actually varies.
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts (1)
70-91: Deduplicate the repeated{ kind: 'singleton' }literalThe identical
fileOptionsobject is inlined in every test case. Consider extracting it to aconst SINGLETON_FILE_OPTIONS = { kind: 'singleton' } as const;near the top of the file and re-using it. This keeps the test DRY and reduces maintenance if the option shape ever changes.- fileOptions: { kind: 'singleton' }, + fileOptions: SINGLETON_FILE_OPTIONS,Apply the same replacement for the other occurrences (lines 90-91, 178-179, 330-331, 343-344, 356-357, 369-370, 533-534, 547-548, 685-686, 699-700).
packages/core-generators/src/utils/ts-paths.ts (1)
1-10: Edge-case:.d.tsand non-TS/JS extensions remain untouchedIf you later feed a
.d.tsor.mtspath into this helper it will fall through unmodified, producing mixed.d.ts/.mtsimports. At minimum add a JSDoc note clarifying that only.ts/.tsx/.js/.jsxfiles are expected, or extend the regex.- * @param filePath - The file path to normalize with a *.ts or *.tsx extension. + * @param filePath - The file path to normalize (expects *.ts, *.tsx, *.js or *.jsx).A unit test covering these edge extensions would also lock behaviour.
packages/core-generators/src/renderers/typescript/extractor-v2/get-resolver-factory.ts (1)
9-14: Consider memoising resolver factories per working directory
ResolverFactoryconstruction is relatively expensive (it parses the referencedtsconfig.json).
If callers invokegetResolverFactory()repeatedly for the same directory during a single extraction run, caching the instance will save a noticeable amount of CPU.A simple Map-based memoisation keyed by the canonicalised
workingDirectorywould suffice and keeps the public API unchanged.packages/project-builder-server/src/template-extractor/run-template-extractor-v2.ts (2)
98-105: Gracefully handle corrupted or mismatched file-ID maps
getPreviousGeneratedFileIdMapalready wraps JSON-parse errors, but if the returned map contains stale paths (e.g., files manually deleted),runTemplateFileExtractorsmay throw later when it attempts to read those files.Consider pruning entries whose target no longer exists before passing the map downstream:
- const fileIdMap = await getPreviousGeneratedFileIdMap(appDirectories[0]); + const fileIdMap = await getPreviousGeneratedFileIdMap(appDirectories[0]); + // Remove IDs pointing at vanished files to avoid cascade failures + for (const [id, relPath] of fileIdMap) { + if (!fs.existsSync(path.join(appDirectories[0], relPath))) { + fileIdMap.delete(id); + } + }(This requires an additional
import fs from 'node:fs';)
24-28: Extractor order: ensureTsTemplateFileExtractorprecedes fallback extractors if overlap is possible
TextTemplateFileExtractormay accept.tsfiles if mis-configured, leading to double processing.
If that risk exists, placeTsTemplateFileExtractorbefore more generic extractors or add an explicit file-type guard inside each extractor.packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts (1)
107-108: Consider adding a generic to tighten thefilesparameterYou could make the function generic and propagate the metadata subtype:
export function writeTsProjectExports< TMeta extends TsTemplateOutputTemplateMetadata, >( files: TemplateFileExtractorFile<TMeta>[], ... )It costs nothing and prevents accidental misuse with a looser metadata shape.
packages/core-generators/src/renderers/typescript/extractor-v2/preprocess-code-for-extraction-hack.test.ts (2)
1-4: Import path extension may back-fire undermoduleResolution: node16
Importing a sibling TypeScript file using the.jsextension relies on TS’ “import as JS” allowance. If this repo ever switches to the strictermoduleResolution: nodenext+verbatimModuleSyntax, the compiler will refuse to resolve./preprocess-code-for-extraction-hack.jsbecause the emitted file will actually be.cjs/.mjs. Consider keeping the specifier extensionless or.tsand let build-time tools rewrite it.
8-26: String-equality assertions are brittle – consider trimming leading indent
The currenttoBecomparison will fail if an extra indent or trailing newline sneaks in. Using a helper such asstripIndent/dedentorexpect(result.trim()).toBe(expected.trim())makes the test intention (marker relocation) independent of whitespace noise.packages/project-builder-server/src/sync/file-id-map.unit.test.ts (2)
10-12: Redundant manual mocks
vitest.configalready automocksnode:fsandnode:fs/promisesvia memfs (see past PR-510). Re-declaringvi.mockhere is unnecessary noise and can accidentally shadow different mock implementations in the future.
45-47:vol.fromJSON({ 'dir/': null })creates a file, not a folder
memfsinterprets a key ending with/and valuenullas an empty file. IfwriteGeneratedFileIdMapexpects the directory to exist, the test passes only because the implementation callsmkdir -pinternally. Prefer creating the directory explicitly to reflect real-world usage:- vol.fromJSON({ - 'test-project/baseplate/': null, - }); + vol.mkdirSync('test-project/baseplate', { recursive: true });packages/core-generators/src/renderers/typescript/extractor-v2/extract-ts-template-variables.ts (1)
45-48:TsTemplateFileVariabletype ignored
discoveredVariables[fullName] = {};relies on the type having no required fields. If the interface ever grows mandatory properties the compiler will silently acceptas anyhere. Consider instantiating viaas const satisfies TsTemplateFileVariableor a factory helper to retain type-safety.packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.unit.test.ts (1)
62-66: Prefernew Map()over redundant generic & arg
new Map<string, string>([])adds unnecessary verbosity (and an empty array allocation).
Usenew Map<string, string>()or simplynew Map()to improve readability.Also applies to: 150-154, 216-220, 267-271, 324-328, 407-411, 483-487
packages/core-generators/src/renderers/text/utils.ts (1)
41-43: RegExp is case-sensitive
getTextTemplateVariableRegExpuses a plaingflag. If template replacement should be case-insensitive, addi.packages/core-generators/src/generators/node/ts-utils/ts-utils.generator.ts (2)
16-18: Task name collision:pathsYou now have
• a task calledpaths(NODE_TS_UTILS_GENERATED.paths.task)
• a dependency calledpaths(NODE_TS_UTILS_GENERATED.paths.provider)Although
synckeeps task and dependency namespaces separate, re-using the same identifier is confusing. Consider renaming one of them (pathsProvideretc.) to improve readability.
26-33: Avoid double casting ofkeyCasting twice clutters the loop:
-for (const key of Object.keys(NODE_TS_UTILS_GENERATED.templates)) { - const template = NODE_TS_UTILS_GENERATED.templates[key as TsUtilKey]; +for (const [key, template] of Object.entries( + NODE_TS_UTILS_GENERATED.templates, +) as [TsUtilKey, unknown][]) {This keeps type-safety without repetitive
asnoise.packages/core-generators/src/renderers/typescript/extractor-v2/default-import-providers.ts (1)
38-43: Placeholder specifier consistency
placeholderModuleSpecifieruses camelCase whereasproviderNameuses kebab-case. Double-check downstream code (e.g.render-ts-import-providers) expects this exact%camelCaseImportsform; otherwise mismatches will occur.packages/core-generators/src/generators/node/typescript/typescript.generator.ts (3)
18-32: Prefer clearer alias names for v2 importsImporting the type and the function from the same module and aliasing both to something ending in “V2” is fine, but using the original
RenderTsTemplateGroupActionInputidentifier for the alias (RenderTsTemplateGroupActionInputV2) while simultaneously alias-renaming the function torenderTsTemplateGroupActionV2makes the code harder to scan.
A more explicit alias such asRenderTsTemplateGroupActionInput_V2(or keeping the original name and aliasing the v1 version instead) would reduce the mental load when jumping between v1/v2 implementations.
120-131:addLazyTemplateGrouphas no v2 counterpartYou introduced
renderTemplateGroupV2, but there is still noaddLazyTemplateGroupV2.
If downstream generators start emitting template groups with the newRecord<string, TsTemplateFile>signature they cannot be queued lazily, which breaks the “render-on-demand” optimisation the rest of the provider relies on.Consider adding:
addLazyTemplateGroupV2<T extends Record<string, TsTemplateFile>>( payload: RenderTsTemplateGroupActionInputV2<T> & { generatorInfo: GeneratorInfo }, options?: Omit<LazyTemplateFileEntry, 'payload'>, ): void;and piping it through the same
lazyTemplatesmechanism.
354-366: Common render-options block duplicated – extract helperThe bodies of
renderTemplateGroupandrenderTemplateGroupV2differ only in the callee (renderTsTemplateGroupActionvs…V2). Duplicating the entire options object inflates the provider and risks config drift.- renderTemplateGroupV2: (payload) => - renderTsTemplateGroupActionV2({ - ...payload, - renderOptions: { - resolveModule(moduleSpecifier, sourceDirectory) { - return resolveModuleSpecifier( - moduleSpecifier, - sourceDirectory, - ); - }, - ...sharedRenderOptions, - }, - }), + renderTemplateGroupV2: (payload) => + renderTemplateGroupGeneric(renderTsTemplateGroupActionV2, payload),where
renderTemplateGroupGenericis a small local helper. This keeps the two paths perfectly in sync.packages/core-generators/src/renderers/extractor/plugins/barrel-export.unit.test.ts (2)
9-15: Type-only import should reference the.tsfile, not the built.jsimport type { TemplateExtractorGeneratedBarrelExport } from './barrel-export.js';When compiling the test suite with TypeScript, importing a type from a
.jspath forcesallowImportingTsExtensionsor ends up asany. Point the compiler at the real source:-import type { TemplateExtractorGeneratedBarrelExport } from './barrel-export.js'; +import type { TemplateExtractorGeneratedBarrelExport } from './barrel-export';(At runtime Vitest resolves to the transpiled
.jsanyway.)
24-49: Inline snapshots are brittleAll snapshot assertions use
toMatchInlineSnapshot(). Any innocuous refactor (different prettier, line-ending, trailing comma) will break the snapshot and create noisy diffs. Prefer semantic assertions:expect(result.trim()).toBe( "export { quux, qux } from './bar';\n" + "export * from './baz';\n" + "export { baz } from './foo';", );This still guarantees exact output while avoiding the maintenance overhead of inline snapshots.
packages/core-generators/src/renderers/typescript/extractor-v2/preprocess-code-for-extraction-hack.ts (1)
49-55:replaceAllrequires Node v15+. Guard or polyfill if older LTS is supportedIf the toolchain still needs to run on Node 14 (or on browsers without
String.prototype.replaceAll), switch tocode.replace(regex, …).packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.ts (1)
46-50: Duplicate-removal logic only checks by nameYou drop existing templates when a name collides, but keep duplicates when
generatorTemplatePathis reused under a different name.
Depending on downstream assumptions this may re-introduce the same file twice.Consider also de-duplicating on
generatorTemplatePath, or assert uniqueness earlier in the pipeline.packages/core-generators/src/renderers/raw/raw-template-file-extractor.ts (1)
53-70: Minor: avoid per-file try/catch for common I/O failuresWrapping every limited task with an identical
try / catchadds noise and slightly
hurts performance. You could instead:
- Pull
readOutputFile+writeTemplateFileinto a small helper that already
includes the error context, or- Catch at the
Promise.alllevel—p-limitwill surface the original stack.Not blocking, just a simplification suggestion.
packages/sync/src/templates/extractor-v2/test-utils/file-system-utils.ts (1)
36-41: Usepath.posixjoin for OS-agnostic test pathsHard-coding
/works on POSIX but breaks on Windows when tests run there.-import { join as joinPath } from 'path'; ... -files[`${generatorPath}/templates/${templatePath}`] = templateContent; +files[joinPath(generatorPath, 'templates', templatePath)] = templateContent;Not critical if your CI is Unix-only, but makes the helper truly cross-platform.
packages/sync/src/templates/extractor-v2/utils/group-template-files-by-type.ts (1)
6-13: Update JSDoc – description &@throwsare now misleadingThe implementation no longer performs duplicate-name detection or throws an error, yet the comment still claims it does. This will confuse maintainers and consumers of the utility.
Remove the outdated information or re-introduce validation.packages/core-generators/src/renderers/extractor/plugins/typed-templates-file.ts (1)
41-47: Minor: capture dependency on barrel plugin via the returned instance, not name
context.getPlugin(templateExtractorBarrelExportPlugin.name)hinges on the plugin being registered exactly once and by that name.
Passing the actual plugin reference frompluginDependencies(returned in the same order) avoids string coupling and is less error-prone.packages/core-generators/src/renderers/typescript/extractor-v2/extract-ts-template-variables.unit.test.ts (1)
22-30: Inline snapshots with large whitespace blocks are brittleTiny formatting changes in the implementation will force snapshot updates that add no semantic value.
Consider asserting with.toContain()/.replace(/\s+/g,'')or explicit substrings for the placeholders instead.packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts (1)
117-118: Track the migration TODOs to ensure completion.There are two TODO comments indicating incomplete migration work. Please ensure these are tracked in your issue tracker with a clear migration plan and timeline.
Would you like me to create GitHub issues to track these migration tasks?
Also applies to: 129-131
packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-template-group-action.ts (1)
78-148: Well-structured template group rendering with strong typing.The implementation demonstrates excellent TypeScript practices with complex type inference and proper error handling. The validation of import map providers prevents runtime errors.
Consider extracting the type assertion logic on lines 119-123 to a helper function for better readability:
+ const getTemplateVariables = ( + variables: unknown, + key: string + ): Record<never, string> | undefined => { + if (!variables || typeof variables !== 'object') return undefined; + return (variables as Record<string, unknown>)[key] as Record<never, string>; + }; + variables: - variables && typeof variables === 'object' - ? (variables[key as keyof typeof variables] as Record< - never, - string - >) - : undefined, + getTemplateVariables(variables, key),packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-import-providers.ts (2)
56-57: Simplify the conditional assignmentThe ternary operator with
undefinedas the false case is redundant.- isTypeOnly: projectExport.isTypeOnly ? true : undefined, + isTypeOnly: projectExport.isTypeOnly,
194-198: Enhance error message with template informationThe error message could be more helpful by including which templates contain the duplicate exports.
if (duplicateProjectExports.length > 0) { + const duplicateDetails = duplicateProjectExports.map(dup => { + const template = templates.find(t => + Object.keys(t.config.projectExports ?? {}).includes(dup.name) + ); + return `${dup.name} (in template: ${template?.config.name ?? 'unknown'})`; + }); throw new Error( - `Duplicate project exports found in template files for generator ${generatorName}: ${duplicateProjectExports.map((fileExport) => fileExport.name).join(', ')}`, + `Duplicate project exports found in template files for generator ${generatorName}: ${duplicateDetails.join(', ')}`, ); }packages/core-generators/src/renderers/typescript/extractor-v2/organize-ts-template-imports.ts (2)
93-104: Consider tracking the known limitationThe documented limitation about incorrectly identifying used imports when identifiers are redeclared in different scopes is a valid trade-off for performance. Consider creating a tracking issue for this limitation in case it becomes problematic in practice.
Would you like me to create an issue to track this known limitation for future improvement?
185-188: Fix grammatical error in error messagethrow new Error( - `Import ${moduleSpecifier} in ${filePath} cannot be a namespace import since it are not supported currently + `Import ${moduleSpecifier} in ${filePath} cannot be a namespace import since they are not supported currently for template extraction.`, );packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-typed-templates.ts (1)
78-78: Consider compatibility for ES2023toSorted()methodThe
toSorted()method is an ES2023 feature that may not be available in all environments. Consider using the traditionalsort()method with array spread for better compatibility.- const renderedTemplates = templates - .map(({ path, config }) => renderTsTypedTemplate(path, config, context)) - .toSorted((a, b) => a.exportName.localeCompare(b.exportName)); + const renderedTemplates = templates + .map(({ path, config }) => renderTsTypedTemplate(path, config, context)) + .sort((a, b) => a.exportName.localeCompare(b.exportName));packages/sync/src/templates/extractor-v2/test-utils/mock-context.ts (2)
32-37: Remove redundant type assertionsThe type assertions for
packageMapandfileIdMapare unnecessary as they're already typed correctly from the function parameters.const configLookup = new TemplateExtractorConfigLookup( - packageMap as Map<string, string>, - fileIdMap as Map<string, string>, + packageMap, + fileIdMap, ); const fileContainer = new TemplateExtractorFileContainer([ - ...packageMap.values(), - ] as string[]); + ...packageMap.values(), + ]);
67-71: Document the private property access patternWhile accessing private properties is acceptable in test utilities, consider adding a comment explaining why this approach is necessary.
// Access the private cache directly for testing + // This is necessary to bypass the normal initialization flow and inject test data directly // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment const configLookup = context.configLookup as any;packages/sync/src/templates/extractor-v2/test-utils/plugin-test-utils.ts (1)
68-70: Add comment to clarify no-op behaviorThe empty async function serves as a no-op for external APIs. Consider adding a comment for clarity.
: async () => { - // No-op for external APIs + // No-op for external APIs that don't support hook execution };packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (1)
322-351: Consider documenting the in-place mutation behavior.The
updateExtractorTemplateConfigmethod correctly updates the template configuration, but it mutates the cached config object directly. While this is acceptable for a cache service, consider adding a JSDoc comment to clarify this behavior for users of the API.Add documentation about the mutation behavior:
/** * Update the template config for a generator + * Note: This mutates the cached configuration in place * @param generatorName - The name of the generator * @param config - The template config to update */packages/core-generators/src/renderers/typescript/templates/types.ts (1)
34-40: Address the overdue TODO comment.The TODO comment indicates that
exportNameshould be renamed toexportedName. Since the due date (2025-06-10) has passed, this should be addressed now.Would you like me to create an issue to track this renaming task or generate a PR to implement the change?
🧰 Tools
🪛 ESLint
[error] 34-38: There is a TODO that is past due date: 2025-06-10. Rename this to exportedName
(unicorn/expiring-todo-comments)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (37)
packages/core-generators/src/generators/node/ts-utils/generated/index.tsis excluded by!**/generated/**packages/core-generators/src/generators/node/ts-utils/generated/template-paths.tsis excluded by!**/generated/**packages/core-generators/src/generators/node/ts-utils/generated/ts-import-providers.tsis excluded by!**/generated/**packages/core-generators/src/generators/node/ts-utils/generated/ts-templates.tsis excluded by!**/generated/**packages/core-generators/src/generators/node/ts-utils/generated/typed-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/auth/auth-context/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/bull/bull-mq/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/bull/fastify-bull-board/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/config-service/generated/index.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/config-service/generated/template-paths.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-import-providers.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/config-service/generated/typed-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/error-handler-service/generated/index.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/error-handler-service/generated/template-paths.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-import-providers.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/error-handler-service/generated/typed-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/fastify-redis/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/fastify-scripts/generated/index.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/fastify-sentry/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/fastify-server/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/index.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/template-paths.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-import-providers.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/logger-service/generated/typed-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/core/readme/generated/index.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/email/fastify-postmark/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/pothos/pothos-auth/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/pothos/pothos-scalar/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/stripe/fastify-stripe/generated/ts-templates.tsis excluded by!**/generated/**packages/fastify-generators/src/generators/yoga/yoga-plugin/generated/ts-templates.tsis excluded by!**/generated/**
📒 Files selected for processing (107)
packages/core-generators/package.json(1 hunks)packages/core-generators/src/generators/metadata/path-roots/path-roots.generator.ts(1 hunks)packages/core-generators/src/generators/node/index.ts(1 hunks)packages/core-generators/src/generators/node/ts-utils/extractor.json(1 hunks)packages/core-generators/src/generators/node/ts-utils/index.ts(1 hunks)packages/core-generators/src/generators/node/ts-utils/ts-extractor.json(0 hunks)packages/core-generators/src/generators/node/ts-utils/ts-utils.generator.ts(1 hunks)packages/core-generators/src/generators/node/typescript/typescript.generator.ts(4 hunks)packages/core-generators/src/renderers/extractor/plugins/barrel-export.ts(1 hunks)packages/core-generators/src/renderers/extractor/plugins/barrel-export.unit.test.ts(1 hunks)packages/core-generators/src/renderers/extractor/plugins/index.ts(1 hunks)packages/core-generators/src/renderers/extractor/plugins/template-paths/paths-file.ts(5 hunks)packages/core-generators/src/renderers/extractor/plugins/template-paths/template-paths.plugin.ts(7 hunks)packages/core-generators/src/renderers/extractor/plugins/typed-templates-file.ts(4 hunks)packages/core-generators/src/renderers/extractor/utils/package-path-specifier.ts(1 hunks)packages/core-generators/src/renderers/index.ts(1 hunks)packages/core-generators/src/renderers/raw/raw-template-file-extractor.ts(2 hunks)packages/core-generators/src/renderers/raw/render-raw-template-action.ts(1 hunks)packages/core-generators/src/renderers/raw/types.ts(1 hunks)packages/core-generators/src/renderers/schemas/template-file-options.ts(1 hunks)packages/core-generators/src/renderers/templates/plugins/barrel-import.ts(0 hunks)packages/core-generators/src/renderers/templates/plugins/barrel-import.unit.test.ts(0 hunks)packages/core-generators/src/renderers/templates/plugins/index.ts(0 hunks)packages/core-generators/src/renderers/text/text-template-file-extractor.ts(2 hunks)packages/core-generators/src/renderers/text/utils.ts(2 hunks)packages/core-generators/src/renderers/text/utils.unit.test.ts(2 hunks)packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts(4 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/build-ts-project-export-map.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/default-import-providers.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/extract-ts-template-variables.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/extract-ts-template-variables.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/get-resolver-factory.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/index.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/organize-ts-template-imports.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/organize-ts-template-imports.unit.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/preprocess-code-for-extraction-hack.test.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/preprocess-code-for-extraction-hack.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-import-providers.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-template-file.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-template-group-action.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-typed-templates.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor-v2/ts-template-file-extractor.ts(1 hunks)packages/core-generators/src/renderers/typescript/extractor/extract-ts-template-variables.ts(3 hunks)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts(8 hunks)packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.unit.test.ts(11 hunks)packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts(2 hunks)packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts(8 hunks)packages/core-generators/src/renderers/typescript/import-maps/types.ts(1 hunks)packages/core-generators/src/renderers/typescript/templates/types.ts(4 hunks)packages/core-generators/src/utils/index.ts(1 hunks)packages/core-generators/src/utils/ts-paths.ts(1 hunks)packages/fastify-generators/src/generators/auth/auth-context/auth-context.generator.ts(1 hunks)packages/fastify-generators/src/generators/bull/bull-mq/bull-mq.generator.ts(1 hunks)packages/fastify-generators/src/generators/bull/fastify-bull-board/fastify-bull-board.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/_composers/fastify-composer.ts(1 hunks)packages/fastify-generators/src/generators/core/axios/axios.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts(4 hunks)packages/fastify-generators/src/generators/core/config-service/extractor.json(1 hunks)packages/fastify-generators/src/generators/core/config-service/index.ts(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts(5 hunks)packages/fastify-generators/src/generators/core/error-handler-service/extractor.json(1 hunks)packages/fastify-generators/src/generators/core/error-handler-service/index.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/fastify-graceful-shutdown.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-redis/fastify-redis.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-scripts/fastify-scripts.generator.ts(3 hunks)packages/fastify-generators/src/generators/core/fastify-sentry/fastify-sentry.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/fastify-server/fastify-server.generator.ts(1 hunks)packages/fastify-generators/src/generators/core/index.ts(2 hunks)packages/fastify-generators/src/generators/core/logger-service/extractor.json(1 hunks)packages/fastify-generators/src/generators/core/logger-service/index.ts(1 hunks)packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts(3 hunks)packages/fastify-generators/src/generators/core/readme/extractor.json(1 hunks)packages/fastify-generators/src/generators/core/request-context/request-context.generator.ts(1 hunks)packages/fastify-generators/src/generators/email/fastify-postmark/fastify-postmark.generator.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-auth/pothos-auth.generator.ts(1 hunks)packages/fastify-generators/src/generators/pothos/pothos-scalar/pothos-scalar.generator.ts(1 hunks)packages/fastify-generators/src/generators/prisma/prisma/prisma.generator.ts(1 hunks)packages/fastify-generators/src/generators/stripe/fastify-stripe/fastify-stripe.generator.ts(1 hunks)packages/fastify-generators/src/generators/yoga/yoga-plugin/yoga-plugin.generator.ts(1 hunks)packages/project-builder-server/src/sync/file-id-map.ts(1 hunks)packages/project-builder-server/src/sync/file-id-map.unit.test.ts(1 hunks)packages/project-builder-server/src/sync/generate-for-directory.ts(2 hunks)packages/project-builder-server/src/template-extractor/run-template-extractor-v2.ts(3 hunks)packages/react-generators/src/generators/apollo/react-apollo/react-apollo.generator.ts(2 hunks)packages/sync/package.json(1 hunks)packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts(6 hunks)packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.unit.test.ts(13 hunks)packages/sync/src/templates/extractor-v2/constants/directories.ts(1 hunks)packages/sync/src/templates/extractor-v2/constants/index.ts(1 hunks)packages/sync/src/templates/extractor-v2/index.ts(1 hunks)packages/sync/src/templates/extractor-v2/run-template-file-extractors.ts(7 hunks)packages/sync/src/templates/extractor-v2/runner/initialize-template-extractor-plugins.unit.test.ts(1 hunks)packages/sync/src/templates/extractor-v2/runner/template-extractor-api.ts(3 hunks)packages/sync/src/templates/extractor-v2/runner/template-extractor-plugin.ts(2 hunks)packages/sync/src/templates/extractor-v2/runner/template-file-extractor.ts(5 hunks)packages/sync/src/templates/extractor-v2/test-utils/file-system-utils.ts(1 hunks)packages/sync/src/templates/extractor-v2/test-utils/index.ts(1 hunks)packages/sync/src/templates/extractor-v2/test-utils/mock-context.ts(1 hunks)packages/sync/src/templates/extractor-v2/test-utils/plugin-test-utils.ts(1 hunks)packages/sync/src/templates/extractor-v2/utils/group-template-files-by-type.ts(1 hunks)packages/sync/src/templates/extractor-v2/utils/group-template-files-by-type.unit.test.ts(0 hunks)packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.ts(2 hunks)packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.unit.test.ts(14 hunks)packages/sync/src/templates/extractor-v2/utils/write-extractor-template-jsons.ts(1 hunks)packages/sync/src/templates/metadata/metadata.ts(1 hunks)packages/sync/src/templates/utils/read-template-file-source.ts(1 hunks)packages/sync/src/utils/parse-generator-name.ts(1 hunks)
💤 Files with no reviewable changes (5)
- packages/core-generators/src/generators/node/ts-utils/ts-extractor.json
- packages/core-generators/src/renderers/templates/plugins/index.ts
- packages/sync/src/templates/extractor-v2/utils/group-template-files-by-type.unit.test.ts
- packages/core-generators/src/renderers/templates/plugins/barrel-import.unit.test.ts
- packages/core-generators/src/renderers/templates/plugins/barrel-import.ts
🧰 Additional context used
🧠 Learnings (3)
packages/core-generators/src/renderers/extractor/utils/package-path-specifier.ts (1)
Learnt from: kingston
PR: halfdomelabs/baseplate#521
File: packages/react-generators/src/generators/admin/admin-crud-edit/admin-crud-edit.generator.ts:90-94
Timestamp: 2025-05-05T06:36:50.687Z
Learning: In this codebase, import paths can include `.ts` extensions, and the `resolveModuleSpecifier` function will handle them appropriately. There's no need to strip file extensions before passing paths to functions like `TsCodeUtils.importFragment`.
packages/project-builder-server/src/sync/file-id-map.unit.test.ts (3)
Learnt from: kingston
PR: halfdomelabs/baseplate#510
File: packages/project-builder-server/src/sync/conflict-file-monitor.test.ts:19-24
Timestamp: 2025-04-23T06:44:30.952Z
Learning: When testing file operations in this codebase, the pattern is to use Vitest automocks for 'node:fs' and 'node:fs/promises' (without explicit implementation replacement) while populating a virtual filesystem with vol.fromJSON() from memfs. File operations in tests are performed directly via vol.promises methods.
Learnt from: kingston
PR: halfdomelabs/baseplate#510
File: packages/project-builder-server/src/sync/conflict-file-monitor.test.ts:19-24
Timestamp: 2025-04-23T06:44:30.952Z
Learning: In this codebase, when testing file operations, Vitest's automocks for 'node:fs' and 'node:fs/promises' are used in conjunction with memfs, but without replacing the mock implementation explicitly in each test file. The virtual filesystem is populated using vol.fromJSON or similar methods, which works seamlessly with the automocks.
Learnt from: kingston
PR: halfdomelabs/baseplate#510
File: packages/project-builder-server/src/sync/conflict-file-monitor.test.ts:19-24
Timestamp: 2025-04-23T06:44:30.952Z
Learning: In the project-builder-server test suite, Vitest automocks for 'node:fs' and 'node:fs/promises' are already configured to use memfs without needing explicit implementation replacement in each test file.
packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.unit.test.ts (1)
Learnt from: kingston
PR: halfdomelabs/baseplate#510
File: packages/project-builder-server/src/sync/conflict-file-monitor.test.ts:19-24
Timestamp: 2025-04-23T06:44:30.952Z
Learning: When testing file operations in this codebase, the pattern is to use Vitest automocks for 'node:fs' and 'node:fs/promises' (without explicit implementation replacement) while populating a virtual filesystem with vol.fromJSON() from memfs. File operations in tests are performed directly via vol.promises methods.
🧬 Code Graph Analysis (25)
packages/core-generators/src/renderers/typescript/extractor/extract-ts-template-variables.ts (1)
packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateFileVariable(130-130)
packages/sync/src/templates/extractor-v2/runner/initialize-template-extractor-plugins.unit.test.ts (1)
packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (1)
TemplateExtractorConfigLookup(43-352)
packages/react-generators/src/generators/apollo/react-apollo/react-apollo.generator.ts (1)
packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateOutputTemplateMetadata(126-128)
packages/sync/src/templates/extractor-v2/runner/template-extractor-api.ts (1)
packages/sync/src/templates/extractor-v2/constants/directories.ts (2)
TEMPLATE_EXTRACTOR_TEMPLATES_DIRECTORY(2-2)TEMPLATE_EXTRACTOR_GENERATED_DIRECTORY(1-1)
packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts (2)
packages/sync/src/templates/extractor/template-file-extractor.ts (1)
TemplateFileExtractorFile(17-28)packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateOutputTemplateMetadata(126-128)
packages/fastify-generators/src/generators/core/fastify-scripts/fastify-scripts.generator.ts (3)
packages/fastify-generators/src/generators/core/fastify-scripts/generated/index.ts (1)
CORE_FASTIFY_SCRIPTS_GENERATED(4-7)packages/sync/src/generators/generators.ts (1)
createGeneratorTask(196-204)packages/fastify-generators/src/generators/core/fastify/fastify.generator.ts (1)
fastifyOutputProvider(77-78)
packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts (2)
packages/sync/src/templates/extractor/template-file-extractor.ts (1)
TemplateFileExtractorFile(17-28)packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateOutputTemplateMetadata(126-128)
packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-typed-templates.ts (6)
packages/core-generators/src/renderers/extractor/plugins/typed-templates-file.ts (1)
TemplateExtractorTypedTemplate(26-29)packages/core-generators/src/renderers/typescript/utils/ts-code-utils.ts (2)
TsCodeUtils(85-580)tsTemplate(583-583)packages/utils/src/string/quot.ts (1)
quot(6-8)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(74-82)packages/core-generators/src/renderers/extractor/utils/package-path-specifier.ts (1)
resolvePackagePathSpecifier(36-46)packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (1)
TemplateExtractorTemplateEntry(33-38)
packages/core-generators/src/renderers/extractor/plugins/barrel-export.unit.test.ts (1)
packages/core-generators/src/renderers/extractor/plugins/barrel-export.ts (4)
mergeBarrelExports(22-121)mergeGeneratedBarrelExports(123-202)TemplateExtractorGeneratedBarrelExport(16-20)templateExtractorBarrelExportPlugin(204-315)
packages/core-generators/src/generators/node/ts-utils/ts-utils.generator.ts (4)
packages/core-generators/src/generators/node/ts-utils/generated/index.ts (1)
NODE_TS_UTILS_GENERATED(5-9)packages/sync/src/utils/create-generator.ts (1)
createGenerator(96-123)packages/sync/src/generators/generators.ts (1)
createGeneratorTask(196-204)packages/core-generators/src/generators/node/typescript/typescript.generator.ts (1)
typescriptFileProvider(148-149)
packages/core-generators/src/renderers/typescript/extractor-v2/default-import-providers.ts (1)
packages/sync/src/utils/parse-generator-name.ts (1)
parseGeneratorName(28-41)
packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts (1)
packages/fastify-generators/src/generators/core/config-service/generated/index.ts (1)
CORE_CONFIG_SERVICE_GENERATED(5-9)
packages/core-generators/src/generators/node/typescript/typescript.generator.ts (1)
packages/core-generators/src/renderers/typescript/templates/types.ts (1)
TsTemplateFile(134-168)
packages/project-builder-server/src/sync/generate-for-directory.ts (1)
packages/project-builder-server/src/sync/file-id-map.ts (1)
writeGeneratedFileIdMap(47-58)
packages/project-builder-server/src/template-extractor/run-template-extractor-v2.ts (3)
packages/core-generators/src/renderers/typescript/extractor-v2/ts-template-file-extractor.ts (1)
TsTemplateFileExtractor(31-183)packages/project-builder-server/src/sync/file-id-map.ts (1)
getPreviousGeneratedFileIdMap(18-39)packages/sync/src/templates/extractor-v2/run-template-file-extractors.ts (1)
runTemplateFileExtractors(37-176)
packages/core-generators/src/renderers/raw/types.ts (2)
packages/core-generators/src/renderers/schemas/template-file-options.ts (1)
TemplateFileOptions(24-24)packages/sync/src/templates/types.ts (1)
TemplateFileBase(21-34)
packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts (2)
packages/core-generators/src/renderers/typescript/templates/types.ts (2)
TsTemplateFileVariable(130-130)TsTemplateOutputTemplateMetadata(126-128)packages/sync/src/utils/canonical-path.ts (1)
normalizePathToProjectPath(16-21)
packages/sync/src/templates/extractor-v2/test-utils/file-system-utils.ts (2)
packages/sync/src/templates/extractor-v2/test-utils/index.ts (1)
createTestFiles(5-5)packages/sync/src/templates/extractor/template-file-extractor-test-utils.ts (1)
templatePath(66-77)
packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts (9)
packages/fastify-generators/src/generators/core/error-handler-service/generated/index.ts (1)
CORE_ERROR_HANDLER_SERVICE_GENERATED(5-9)packages/sync/src/generators/generators.ts (1)
createGeneratorTask(196-204)packages/fastify-generators/src/generators/core/fastify-server/fastify-server.generator.ts (1)
fastifyServerConfigProvider(72-72)packages/core-generators/src/generators/node/typescript/typescript.generator.ts (1)
typescriptFileProvider(148-149)packages/fastify-generators/src/generators/core/config-service/index.ts (1)
configServiceImportsProvider(3-3)packages/fastify-generators/src/generators/core/error-handler-service/generated/ts-import-providers.ts (1)
errorHandlerServiceImportsProvider(30-33)packages/fastify-generators/src/generators/core/error-handler-service/index.ts (1)
errorHandlerServiceImportsProvider(3-3)packages/core-generators/src/renderers/typescript/fragments/creators.ts (1)
tsCodeFragment(73-83)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(74-82)
packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-template-file.ts (4)
packages/core-generators/src/renderers/typescript/extractor-v2/organize-ts-template-imports.ts (2)
TsTemplateImportLookupContext(21-38)organizeTsTemplateImports(73-265)packages/core-generators/src/renderers/typescript/templates/types.ts (2)
TsTemplateVariableMap(132-132)TsTemplateFileImportProvider(25-27)packages/utils/src/maps/map-values-of-map.ts (1)
mapValuesOfMap(11-20)packages/utils/src/maps/key-by.ts (1)
mapKeyBy(13-23)
packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts (2)
packages/core-generators/src/renderers/typescript/templates/types.ts (3)
tsTemplateOutputTemplateMetadataSchema(97-124)TS_TEMPLATE_TYPE(16-16)TsTemplateOutputTemplateMetadata(126-128)packages/sync/src/templates/extractor/template-file-extractor.ts (1)
TemplateFileExtractorFile(17-28)
packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (1)
packages/sync/src/templates/extractor-v2/configs/extractor-config.schema.ts (1)
TemplateConfig(46-46)
packages/sync/src/templates/extractor-v2/test-utils/mock-context.ts (4)
packages/sync/src/templates/extractor-v2/runner/template-extractor-context.ts (1)
TemplateExtractorContext(13-73)packages/sync/src/tests/logger.test-utils.ts (1)
createTestLogger(10-32)packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (1)
TemplateExtractorConfigLookup(43-352)packages/sync/src/templates/extractor-v2/runner/template-extractor-file-container.ts (1)
TemplateExtractorFileContainer(10-73)
packages/core-generators/src/renderers/extractor/plugins/template-paths/paths-file.ts (3)
packages/utils/src/paths/posix-join.ts (1)
posixJoin(10-12)packages/sync/src/templates/extractor-v2/constants/directories.ts (1)
TEMPLATE_EXTRACTOR_GENERATED_DIRECTORY(1-1)packages/core-generators/src/renderers/extractor/utils/generated-template-file-names.ts (1)
getGeneratedTemplateConstantName(11-16)
packages/sync/src/templates/extractor-v2/runner/template-file-extractor.ts (2)
packages/sync/src/templates/extractor-v2/runner/template-extractor-context.ts (1)
TemplateExtractorContext(13-73)packages/sync/src/templates/extractor-v2/runner/template-extractor-api.ts (1)
TemplateExtractorApi(16-107)
🪛 ESLint
packages/core-generators/src/renderers/typescript/templates/types.ts
[error] 10-10: Expected "@baseplate-dev/sync/extractor-v2" to come before "@baseplate-dev/utils".
(perfectionist/sort-imports)
[error] 11-14: Imports "TemplateFileOptions" are only used as type.
(@typescript-eslint/consistent-type-imports)
[error] 11-14: Missed spacing between "@baseplate-dev/sync/extractor-v2" and "#src/renderers/schemas/template-file-options.js".
(perfectionist/sort-imports)
[error] 34-38: There is a TODO that is past due date: 2025-06-10. Rename this to exportedName
(unicorn/expiring-todo-comments)
[error] 130-130: An empty interface declaration allows any non-nullish value, including literals like 0 and "".
- If that's what you want, disable this lint rule with an inline comment or configure the 'allowInterfaces' rule option.
- If you want a type meaning "any object", you probably want
objectinstead. - If you want a type meaning "any value", you probably want
unknowninstead.
(@typescript-eslint/no-empty-object-type)
🪛 Biome (1.9.4)
packages/core-generators/src/renderers/typescript/templates/types.ts
[error] 130-130: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: test
- GitHub Check: Lint
- GitHub Check: Test E2E
🔇 Additional comments (99)
packages/sync/src/templates/utils/read-template-file-source.ts (1)
33-33: Update confirmed: TODO date reflects latest plan.
The updated TODO comment date (“2025-06-12”) correctly aligns with the migration schedule.packages/sync/src/templates/metadata/metadata.ts (1)
17-17: Non‐functional comment update
This change only updates the TODO date; there’s no impact on behavior.packages/fastify-generators/src/generators/core/request-context/request-context.generator.ts (1)
19-19: Align import to consolidated index module
Switching to import from../logger-service/index.jscentralizes exports per the refactoring. Ensure thatindex.jsre‐exportsloggerServiceConfigProvider.packages/core-generators/src/renderers/typescript/import-maps/types.ts (1)
9-10: Document planned rename for clarity
The TODO marks a future rename ofnametoexportedName, aligning with extractor-v2 naming conventions.packages/fastify-generators/src/generators/core/fastify-redis/fastify-redis.generator.ts (1)
23-23: Use consolidated config-service index
Importing from../config-service/index.jscentralizes both providers. Confirm thatindex.jsexportsconfigServiceImportsProviderandconfigServiceProvider.packages/fastify-generators/src/generators/pothos/pothos-auth/pothos-auth.generator.ts (1)
17-17: Centralize import to core error-handler-service index
Updating the import path toindex.jsaligns with the barrel-file refactoring. Verifyindex.jsre-exportserrorHandlerServiceImportsProvider.packages/fastify-generators/src/generators/pothos/pothos-scalar/pothos-scalar.generator.ts (1)
17-17: Import path update for errorHandlerServiceImportsProvider
Refactors import to the new centralizedindex.jsexport.packages/fastify-generators/src/generators/auth/auth-context/auth-context.generator.ts (1)
15-15: Standardize errorHandlerServiceImportsProvider import source
Switches to the generatedts-import-providers.jsfor centralized imports.packages/fastify-generators/src/generators/bull/fastify-bull-board/fastify-bull-board.generator.ts (1)
23-23: Consolidate errorHandlerServiceImportsProvider import
Updated to import fromcore/error-handler-service/index.jsfor consistency.packages/fastify-generators/src/generators/core/axios/axios.generator.ts (1)
12-12: Update import for errorHandlerServiceConfigProvider
Aligns import path with the newindex.jscentral exporter.packages/fastify-generators/src/generators/email/fastify-postmark/fastify-postmark.generator.ts (1)
21-21: Refactor config-service imports to index module
Imports bothconfigServiceImportsProviderandconfigServiceProviderfrom the consolidatedindex.js.packages/fastify-generators/src/generators/bull/bull-mq/bull-mq.generator.ts (1)
13-17: Import path consolidation looks correct – please double-check re-exportThe switch to
index.jspaths should improve modularity, but make sureerrorHandlerServiceImportsProviderandloggerServiceImportsProviderare actually re-exported from those indexes – otherwise you’ll get a runtime “export not found” error once compiled.
A quickgrepacross the repo (or runningtsc --noEmit) will surface any missing re-exports.packages/core-generators/src/generators/metadata/path-roots/path-roots.generator.ts (1)
9-13: Updated extractor-plugin imports look goodThe new paths reference the extractor plugin that now owns the
TemplatePathRoottype andTEMPLATE_PATHS_METADATA_FILEconstant. The change is cohesive with the plugin refactor and should compile cleanly.packages/fastify-generators/src/generators/core/_composers/fastify-composer.ts (1)
10-12: Index-based service imports improve encapsulationMoving the Fastify service generators behind
index.jsbarrels reduces deep-path coupling and simplifies future refactors. No further action needed.Also applies to: 18-18
packages/fastify-generators/src/generators/yoga/yoga-plugin/yoga-plugin.generator.ts (1)
32-37: Provider import paths updated – verify names remain unchangedThe providers are now imported via their package indexes. If any of those indexes renamed or aliased the individual exports, update the local identifiers here to match; otherwise compilation will fail late in the build. A quick
ts-node -O '{\"module\":\"esnext\"}' --swc ./scripts/verify-imports.tsor a plaintsc --noEmitin CI would catch it.packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/fastify-graceful-shutdown.generator.ts (1)
8-11: Import moved from maps to providers – ensure the file existsThe path now targets
generated/ts-import-providers.js. Confirm that the generator which produces this file was renamed accordingly in all places; otherwise this reference will break at runtime or during code-gen.packages/core-generators/src/utils/index.ts (1)
2-2: Re-export new TS path normalization utility
Adding thets-paths.jsbarrel export aligns with the existing exports and centralizes path normalization logic.packages/sync/src/templates/extractor-v2/constants/index.ts (1)
1-1: Expose directory constants via barrel export
Re-exporting from./directories.jsenables consumers to import directory names alongside the other constants in a single entry point.packages/sync/src/utils/parse-generator-name.ts (1)
8-9: ImproveParsedGeneratorNamedocumentation clarity
The added examples forpackageName,generatorPath, andgeneratorBasenameenhance understandability without altering behavior.Also applies to: 12-13, 16-17
packages/fastify-generators/src/generators/core/fastify-server/fastify-server.generator.ts (1)
29-30: Standardize service imports through index barrels
Switching to../config-service/index.jsand../logger-service/index.jsconsolidates imports and reduces coupling to individual generator files.packages/fastify-generators/src/generators/stripe/fastify-stripe/fastify-stripe.generator.ts (2)
20-21: Centralize config and error-handler service imports
MovingconfigServiceImportsProvider,configServiceProvider, anderrorHandlerServiceImportsProviderto their respectiveindex.jsbarrels improves consistency and maintainability.
23-23: Consolidate logger service import
ImportingloggerServiceImportsProviderfrom its index barrel aligns this module with the rest of the generator imports.packages/core-generators/src/generators/node/index.ts (1)
6-6:Details
✅ Verification successful
Ensure the barrel file re-exports the full public surface
Changing the path from
./ts-utils/ts-utils.generator.jsto./ts-utils/index.jsis fine as long as the new barrel keeps re-exporting every symbol that was previously reachable by consumers. Any omission will be a silent breaking change.
🏁 Script executed:
#!/usr/bin/env bash # List symbols re-exported by the old generator file vs the new barrel. rg --no-heading -n $'export .*' packages/core-generators/src/generators/node/ts-utils/ts-utils.generator.ts rg --no-heading -n $'export .*' packages/core-generators/src/generators/node/ts-utils/index.tsLength of output: 463
Barrel File Correctly Re-exports All Symbols
The comparison shows that the new
index.tsbarrel exports every symbol from the old generator plus additional imports providers, so no public API is lost:• Old exports in
ts-utils.generator.ts
–export const tsUtilsGenerator = createGenerator({...})• New barrel in
ts-utils/index.ts
export type { TsUtilsImportsProvider } from './generated/ts-import-providers.js';export { tsUtilsImportsProvider } from './generated/ts-import-providers.js';export * from './ts-utils.generator.js';(includestsUtilsGenerator)All previously reachable symbols remain available.
packages/fastify-generators/src/generators/core/fastify-sentry/fastify-sentry.generator.ts (1)
25-32: Import path convergence looks goodImporting from the neighbouring
index.jsbarrels simplifies path maintenance and avoids deep relative imports. Nice cleanup – no issues spotted.packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.unit.test.ts (1)
573-575: 👍 Correct metadata type enforcementUsing
satisfies TsTemplateOutputTemplateMetadataguarantees compile-time safety after the schema change. Looks solid.packages/react-generators/src/generators/apollo/react-apollo/react-apollo.generator.ts (2)
4-5: Updated metadata import aligns with extractor-v2Switching to
TsTemplateOutputTemplateMetadatais required after the schema overhaul. Good catch.
573-575: Singleton file option makes sense for generated artefactMarking the pseudo-file as a
singletonprevents accidental duplicates during extraction. No concerns.packages/core-generators/src/renderers/index.ts (1)
1-1: Potential breaking change:templatesexports removedReplacing the public export from
./templates/index.jswith./extractor/index.jswill break downstream consumers importing template helpers directly from@baseplate-dev/core-generators/renderers.Please double-check usage across the monorepo (and external docs) or keep the old path as a re-export to avoid a major version bump.
packages/sync/src/templates/extractor-v2/runner/template-extractor-api.ts (3)
8-11: Centralize directory constants for maintainability
The import replaces hardcoded strings withTEMPLATE_EXTRACTOR_TEMPLATES_DIRECTORYandTEMPLATE_EXTRACTOR_GENERATED_DIRECTORY. Ensure that the path (../constants/directories.js) is correct and that these constants are re-exported if needed elsewhere.
78-84: Use constant for templates directory inwriteTemplateFile
This replaces the literal'templates'segment withTEMPLATE_EXTRACTOR_TEMPLATES_DIRECTORY. Verify thatgeneratorTemplatePathis strictly a relative path (without leading directory segments) to avoid double inclusion.
100-106: Use constant for generated directory inwriteGeneratedFile
The'generated'segment is now driven byTEMPLATE_EXTRACTOR_GENERATED_DIRECTORY. Confirm thatrelativePathdoes not already contain that segment, preventing malformed file paths.packages/sync/src/templates/extractor-v2/runner/initialize-template-extractor-plugins.unit.test.ts (1)
17-20: Sync mock context with updated constructor signature
The test helper now correctly instantiatesTemplateExtractorConfigLookupwith bothpackageMapandfileIdMap. Ensure no other tests or code paths remain using the old single-argument constructor.packages/core-generators/src/renderers/typescript/extractor-v2/index.ts (1)
1-2: Add re-export for extractor-v2 TypeScript modules
Good consolidation of the new renderers under a single entry point. Confirm that the package’sexportsfield inpackage.jsonincludes the"./extractor-v2"subpath to make these available to consumers.packages/sync/src/templates/extractor-v2/index.ts (1)
1-3: Expose constants through public API
Re-exporting./constants/index.jsmakes the directory constants accessible downstream. Validate thatconstants/index.jsexports all intended values (e.g.,TEMPLATE_EXTRACTOR_TEMPLATES_DIRECTORY,TEMPLATE_EXTRACTOR_GENERATED_DIRECTORY).packages/fastify-generators/src/generators/core/index.ts (2)
5-6: Switch to index entry for config and error-handler services
Updating these exports to point at theirindex.jsentry points keeps paths consistent. Verify that bothconfig-service/index.jsanderror-handler-service/index.jscorrectly export their generators.
15-15: Switch to index entry for logger service
Similarly, ensurelogger-service/index.jsexposes the expected generator and matches the structure used elsewhere.packages/core-generators/src/renderers/extractor/plugins/index.ts (1)
1-5: Barrel index is clean and idiomatic
Re-exporting from a single entry-point simplifies downstream import paths. No issues spotted.packages/core-generators/src/renderers/extractor/utils/package-path-specifier.ts (1)
40-44: Reuse the newnormalizeTsPathToJsPathhelper instead of duplicating the regexThe same extension-stripping logic now lives in
utils/ts-paths.ts. Re-using it avoids divergent behaviour and makes future changes (e.g..mts/.ctssupport) one-liner.-import { normalizeTsPathToJsPath } from '../../../utils/ts-paths.js'; ... - return `#${parsed.filePath.replace(/\.(t|j)sx?$/, '.js')}`; + return `#${normalizeTsPathToJsPath(parsed.filePath)}`;[ suggest_essential_refactor ]
packages/core-generators/src/renderers/typescript/extractor/extract-ts-template-variables.ts (1)
16-19: Type alias update looks correctSwitching to
TsTemplateFileVariablealigns with the new metadata model; no functional concerns.packages/sync/src/templates/extractor-v2/constants/directories.ts (1)
1-2: Constants for directory names look good
Centralizing these string literals improves maintainability and consistency across modules.packages/fastify-generators/src/generators/core/error-handler-service/index.ts (1)
1-3: Re-export structure is clear and consistent
Consolidating exports in this index file simplifies imports for consumers.packages/sync/package.json (1)
26-30: Expose new extractor-v2 test-utils export
The added./extractor-v2/test-utilsentry correctly points to the built declarations and JS. This aligns with the new utilities and ensures they're consumable externally.packages/fastify-generators/src/generators/core/fastify-scripts/fastify-scripts.generator.ts (4)
1-5: Update imports to centralized core-generators package
ImportingrenderRawTemplateFileActionfrom@baseplate-dev/core-generatorsand consolidating provider imports here aligns with the refactoring pattern.
13-14: Use unified generated index for fastify-scripts
Switching toCORE_FASTIFY_SCRIPTS_GENERATEDreplaces two separate import sources and improves maintainability.
29-35: Reference generated paths in buildTasks
Updatingpathsdependency and initialpathsfield to use the generatedpaths.taskandpaths.provideris correct and consistent with other generators.
58-61: Render raw template using generated templates
UtilizingCORE_FASTIFY_SCRIPTS_GENERATED.templates.tsconfigfor the template source ensures template consistency.packages/core-generators/package.json (1)
26-30: Expose extractor-v2 subpath in core-generators
Adding the./extractor-v2export correctly points to the new TypeScript v2 extractor artifacts, enabling external consumers to import them.packages/core-generators/src/renderers/typescript/extractor-v2/get-resolver-factory.ts (1)
15-22:Details
❌ Incorrect review comment
Extension aliases reference extensions that are not in the allowed‐extensions list
extensionAliasmaps.cjs → .cts/.mjs → .mts, yet neither.ctsnor.mtsappear in theextensionsarray (line 15).
If the underlying resolver respects theextensionswhitelist when traversing aliases, any import ending up with.cts/.mtswill fail to resolve.- extensions: ['.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json', '.node'], + extensions: [ + '.ts', + '.tsx', + '.d.ts', + '.js', + '.jsx', + '.json', + '.node', + '.cts', + '.mts', + ],Alternatively, remove the alias entries if they are not needed.
Please verify againstoxc-resolverbehaviour and add a regression test.
🏁 Script executed:
#!/bin/bash set -e # Locate the get-resolver-factory.ts file file=$(fd --full-path 'get-resolver-factory.ts' -c ts -0 | head -n1) echo "Found file: $file" # Print the relevant section around extensions & extensionAlias sed -n '1,200p' "$file"Length of output: 306
🏁 Script executed:
#!/bin/bash set -e # Search for extensionAlias and extensions definitions in TypeScript files rg -n "extensionAlias" -A5 -C2 --type ts rg -n "extensions:" -A8 -C2 --type tsLength of output: 5413
🏁 Script executed:
#!/bin/bash set -e file="packages/core-generators/src/renderers/typescript/extractor-v2/get-resolver-factory.ts" echo "Showing extensionAlias block for verification:" rg -n "extensionAlias" -A20 -C2 "$file"Length of output: 564
Ignore outdated extensionAlias concern
TheextensionAliasblock in
packages/core-generators/src/renderers/typescript/extractor-v2/get-resolver-factory.ts
only contains mappings for.jsand.jsx, and there are no.cjsor.mjsentries. The missing.cts/.mtsissue does not apply to the current code. No changes required.Likely an incorrect or invalid review comment.
packages/fastify-generators/src/generators/core/config-service/extractor.json (1)
1-16: Looks good – schema aligns with v2 extractor expectationsThe singleton template definition is consistent and no issues are apparent.
packages/fastify-generators/src/generators/core/logger-service/extractor.json (1)
1-16: Configuration JSON is valid and follows the new structureNo functional concerns.
packages/core-generators/src/renderers/typescript/extractor/write-ts-project-exports.ts (1)
11-12: EnsureTsTemplateOutputTemplateMetadatareally containsprojectExportsThe implementation relies on
file.metadata.projectExportsfurther down. If the new metadata type omits or renames that property, the call-site compiles (because it’s accessed throughany/unknown) but blows up at runtime.
Please double-check thattsTemplateOutputTemplateMetadataSchemaexposes the same shape as before.packages/fastify-generators/src/generators/core/logger-service/index.ts (1)
1-3: Re-export wrapper looks goodPath names and ordering are consistent with the other generators introduced in this PR.
packages/core-generators/src/renderers/raw/render-raw-template-action.ts (1)
20-24: Edge-case:idis always in scope but may beundefined
idis destructured unconditionally, yet absent for singleton templates.
The subsequent check guards against missingidforinstancekinds, so behaviour is fine.
Just ensure no downstream code assumesidis a string for the singleton branch.packages/sync/src/templates/extractor-v2/utils/write-extractor-template-jsons.ts (1)
25-31: ConfirmfileContainer.writeFileis synchronous or await the promise
writeExtractorTemplateJsonsis declaredvoidand does notawaitthewriteFilecall.
IfwriteFilereturns a promise (common in async FS abstractions) errors could be lost or the caller could exit before writes finish.- context.fileContainer.writeFile( + await context.fileContainer.writeFile(Update the function signature to
asyncif necessary.packages/fastify-generators/src/generators/core/config-service/index.ts (1)
1-3: Consistent export surfaceMatches the pattern used for
logger-service; promotes discoverability.packages/core-generators/src/generators/node/ts-utils/index.ts (1)
1-3: Barrel file is clean – nothing to change
Single-point re-exports are concise and correctly typed.packages/sync/src/templates/extractor-v2/test-utils/index.ts (1)
1-18: All good – barrel improves DX
The centralised re-export keeps test helpers discoverable and avoids deep import paths.packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.unit.test.ts (1)
94-95: Missingawaitmay swallow asynchronous errorsIf
mergeExtractorTemplateEntriesbecomes or already is async, these invocations drop the resulting promise and the test will pass even when the merge fails.
Safer pattern:-await mergeExtractorTemplateEntries(metadataEntries, context); +await mergeExtractorTemplateEntries(metadataEntries, context);Confirm the function’s signature; adjust accordingly.
Also applies to: 180-181, 237-238, 287-288, 345-346, 491-492
packages/core-generators/src/renderers/text/utils.ts (1)
65-83:extractTemplateVariables– edge-cases worth guarding
- Throwing when a variable value is not found is great for early failure, but it means a single optional variable breaks the whole extraction. Consider a non-throwing mode or a flag if optional variables are expected.
- The loop recreates a
RegExpfor every variable. For large variable sets this is fine, but if performance ever matters, pre-compiling could help.- For
.gqlfiles both delimiters are''; the replacement becomes${key}without any fence. That’s intentional, but double-check consumers expect the naked key.No action required if these behaviours are intentional; just flagging them.
packages/sync/src/templates/extractor-v2/runner/template-extractor-plugin.ts (1)
25-32: Docs & type additions look solidThe hook descriptions and the new
TemplateExtractorPluginInstanceutility type are clear and improve DX.packages/core-generators/src/renderers/typescript/extractor-v2/default-import-providers.ts (1)
36-43: Potential circular import with@baseplate-dev/sync
default-import-providers.tslives insidecore-generatorsbut importsparseGeneratorNamefrom@baseplate-dev/sync, which in turn depends oncore-generatorsin several places. Ensure the build graph doesn’t introduce a circular dependency (ESM cycles can break TS emit & Jest mocks).If detected, consider extracting
parseGeneratorNameinto a shared utility package.packages/core-generators/src/generators/node/ts-utils/extractor.json (1)
10-12: Verify special keynotEmptyinprojectExports
"projectExports": { "notEmpty": {} }is not a conventional export map entry (all other entries map an identifier to an options object).
IfnotEmptyis a sentinel for “this file must export something”, ensure the extractor knows about it; otherwise consumers trying to importnotEmptywill fail.packages/core-generators/src/renderers/typescript/extractor-v2/organize-ts-template-imports.unit.test.ts (1)
122-136: Test assumes default export can be merged into named import
import F from './default-module.ts'; … expect(result).toContain('import { A, B, F } from "%testImports"')Bundling a default export into a named list is only valid if
export { default as F }exists in the provider.
Ensure the organiser rewrites the default export accordingly; otherwise the generated code will not type-check.packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts (1)
84-86:importstask appears unused inside this generator
CORE_CONFIG_SERVICE_GENERATED.imports.taskis registered but never consumed in
dependencies.
If no other build task relies on it, consider dropping the task to keep the
pipeline minimal.Double-check before removal in case external generators depend on the side-effects.
packages/sync/src/templates/extractor-v2/utils/group-template-files-by-type.ts (1)
26-33: AvoidJSON.stringifyfor dedupe key – cheaper & clearer string concat works
uniqByonly needs a unique primitive key. Serialising an object on every iteration produces unnecessary allocations.-const uniqueTemplateFiles = uniqBy(files, (f) => - JSON.stringify({ - g: f.metadata.generator, - t: f.metadata.name, - }), -); +const uniqueTemplateFiles = uniqBy( + files, + (f) => `${f.metadata.generator}:${f.metadata.name}`, +);[ suggest_optional_refactor ]
packages/core-generators/src/renderers/text/utils.unit.test.ts (1)
86-96: Expected CSS replacement string looks suspicious
'./* className */ { color: red; }'keeps the leading dot but removes the class name entirely.
Should it be'./* className */ { … }'(dot + delimiter) or'/* className */ { … }'(no dot)?
Please verify the intended delimiter semantics.packages/core-generators/src/renderers/raw/types.ts (1)
47-51: LGTM! Good improvement to type safety.The addition of generic type parameters to
RawTemplateFileandcreateRawTemplateFileenhances type safety while maintaining backward compatibility through the default type parameter.Also applies to: 56-58
packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts (1)
134-139: Good validation for instance templates.The validation ensuring instance templates have an ID is a good defensive programming practice that will prevent runtime errors.
packages/project-builder-server/src/sync/file-id-map.ts (1)
1-58: Well-implemented file ID map management.The implementation demonstrates good practices:
- Comprehensive error handling with context
- Type-safe schema validation
- Graceful handling of missing files
- Deterministic output through sorting
packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-template-file.ts (1)
17-61: Clean implementation of template rendering.The function properly handles:
- Variable extraction and import organization
- Shebang preservation for executable scripts
- Addition of
@ts-nocheckto prevent type errors in generated codepackages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.unit.test.ts (3)
17-21: LGTM! Good test data structure.The mock file ID map follows a clear naming convention (
package#extractor:file->id) that makes the test cases easy to understand.
432-551: Comprehensive test coverage for the new method.The test suite for
updateExtractorTemplateConfigcovers all the important scenarios:
- Successfully updating an existing template
- Error handling when template doesn't exist
- Error handling when generator doesn't exist
Good job on the thorough test coverage!
553-589: Clear and focused tests for file ID lookup.The tests for
getOutputRelativePathForTemplateeffectively verify the lookup functionality with both existing and non-existent templates.packages/fastify-generators/src/generators/core/error-handler-service/extractor.json (1)
1-67: Well-structured extractor configuration.The configuration properly defines all required metadata for the error handling templates. The import provider references are correctly specified using package path specifiers.
Note: All
templatefields are empty strings (lines 8, 23, 39, 58). Ensure this is intentional and that the template content is managed elsewhere.packages/sync/src/templates/extractor-v2/run-template-file-extractors.ts (3)
145-146: Good architectural improvement separating merge from write operations.The refactoring to separate
mergeExtractorTemplateEntries(in-memory operation) fromwriteExtractorTemplateJsons(file I/O) improves the code structure and allows for better error handling and transactional behavior.Also applies to: 168-171
133-139: Good use of API pattern for extractor interface.Creating
TemplateExtractorApiinstances provides a clean, controlled interface for extractors to interact with the system.
93-97:Details
✅ Verification successful
Verify hook execution order aligns with plugin dependencies.
The hooks are now executed in reverse order. This typically makes sense for cleanup/finalization hooks where dependencies should be processed in reverse order.
🏁 Script executed:
#!/bin/bash # Description: Verify that the reverse hook execution order is documented and used consistently # Search for documentation about hook execution order rg -A 5 "hook.*reverse|reverse.*order" --type ts # Look for other hook executions to ensure consistency ast-grep --pattern 'for (const $_ of $_.toReversed()) { $$$ }'Length of output: 3928
Hook execution order is correct and consistent
The
runHooksimplementation usestoReversed()as documented in
sync/src/templates/extractor-v2/runner/template-extractor-plugin.ts(“Hooks are executed in reverse dependency order…”).
This matches other usages (e.g.,toposort-localtests, React wrapper application) and requires no changes.packages/core-generators/src/renderers/text/text-template-file-extractor.ts (2)
29-60: Excellent error handling improvements.The addition of try-catch blocks with detailed error messages including the file path and original error cause will greatly improve debugging when template extraction fails.
70-74:Details
✅ Verification successful
Clean refactoring using the variable extraction utility.
The use of
extractTemplateVariablesutility simplifies the code and centralizes the variable extraction logic.
🏁 Script executed:
#!/bin/bash # Description: Verify the extractTemplateVariables utility implementation and its test coverage # Check the utility implementation rg -A 10 "export.*extractTemplateVariables" packages/core-generators/src/renderers/text/utils.ts # Check test coverage for the utility fd "utils.*test" packages/core-generators/src/renderers/text/ --exec cat {}Length of output: 5405
extractTemplateVariables utility is well-covered and ready to ship
All edge cases—including empty variables, file-specific delimiters, overlapping values, word boundaries, and missing-value errors—are thoroughly tested in
packages/core-generators/src/renderers/text/utils.test.ts. No further changes needed.packages/core-generators/src/renderers/typescript/extractor/ts-template-file-extractor.ts (1)
24-24: Consistent metadata type refactoring.The replacement of
TsTemplateFileMetadatawithTsTemplateOutputTemplateMetadatais applied consistently throughout the file. The new type name better reflects its purpose as output template metadata.Also applies to: 105-108
packages/core-generators/src/renderers/typescript/extractor-v2/build-ts-project-export-map.ts (1)
1-124: LGTM!The implementation is well-structured with proper handling of edge cases. The function correctly:
- Filters for singleton templates only
- Skips templates without output paths
- Builds a comprehensive export map with all necessary metadata
packages/core-generators/src/renderers/typescript/extractor-v2/ts-template-file-extractor.ts (1)
31-183: Well-structured template extractor implementationThe extractor is well-designed with:
- Proper plugin dependencies management
- Good error handling with contextual information
- Efficient concurrent processing with limits
- Clean separation of concerns between metadata extraction, file writing, and generated files
packages/fastify-generators/src/generators/core/error-handler-service/error-handler-service.generator.ts (1)
17-21: Clean refactoring to use generated imports and pathsThe refactoring successfully replaces all hardcoded imports and paths with references to the centralized
CORE_ERROR_HANDLER_SERVICE_GENERATEDobject. This improves maintainability and consistency across the codebase.Also applies to: 46-47, 54-54, 61-61, 66-68, 82-84, 102-102, 108-108, 115-116, 137-137, 139-139, 143-146
packages/core-generators/src/renderers/typescript/extractor-v2/render-ts-typed-templates.ts (2)
97-120: Well-structured template rendering logicThe function cleanly separates grouped and ungrouped templates, processes them appropriately, and returns a combined result. Good use of functional programming patterns.
32-32:Details
✅ Verification successful
Verify ES2020+ compatibility for
import.meta.dirnameThe code uses
import.meta.dirnamewhich is an ES2020+ feature. Ensure that the target Node.js version and build configuration support this feature.Run the following script to check the minimum Node.js version requirement:
🏁 Script executed:
#!/bin/bash # Description: Check for Node.js version requirements and import.meta usage # Check package.json for engine requirements fd -e json -x grep -l "engines" {} \; | xargs grep -A2 "engines" | grep -E "node|npm" # Check for other import.meta usage in the codebase rg "import\.meta\." -A 2Length of output: 64956
import.meta.dirname is supported by our Node.js target (>=22.0.0)
All packages specify
"node": "^22.0.0"in theirenginesfield, andimport.meta.dirnameis fully supported in Node.js 22+. No changes needed.packages/sync/src/templates/extractor-v2/test-utils/plugin-test-utils.ts (1)
12-43: Well-implemented mock plugin APIThe mock API correctly handles hook registration and sequential execution. Good design for testing plugin behavior.
packages/core-generators/src/renderers/extractor/plugins/template-paths/paths-file.ts (2)
24-84: Good refactoring of path constants and export namesThe centralization of the generated paths file name and the addition of
rootExportNameto the interface improves consistency and maintainability.
207-257: Proper integration with barrel export systemThe function now correctly returns the export name for barrel export registration and uses centralized path constants.
packages/sync/src/templates/extractor-v2/runner/template-file-extractor.ts (2)
35-60: LGTM! Well-designed extraction context enhancement.The addition of the generic
TExtractionContextparameter with a default ofunknownis a clean way to allow extractors to pass temporary context data between extraction and writing phases without persisting it toextractor.json. The optionalextractionContextproperty maintains backward compatibility.
132-139: Good addition of async support for writeTemplateFiles.Allowing both synchronous and asynchronous return types provides flexibility for implementations that may need to perform async operations during template file writing.
packages/sync/src/templates/extractor-v2/configs/template-extractor-config-lookup.ts (2)
55-58: LGTM! Clean dependency injection for fileIdMap.The addition of
fileIdMapto the constructor enables tracking of file IDs across extraction runs, which is essential for maintaining stable references to generated files.
212-254: Well-implemented template type filtering and config retrieval.The
getGeneratorConfigsForExtractorTypemethod provides a flexible way to query generator configurations by template type with proper schema validation. The optional generator config schema handling and the structured return type make this a robust addition.packages/core-generators/src/renderers/extractor/plugins/barrel-export.ts (2)
22-121: Excellent implementation of barrel export merging.The
mergeBarrelExportsfunction handles the complexity of merging barrel exports well:
- Properly groups exports by module and type
- Handles star exports with correct precedence
- Maintains consistent sorting for deterministic output
- Separates type-only and regular exports appropriately
204-315: Well-structured barrel export plugin implementation.The plugin correctly:
- Accumulates exports during the extraction process
- Processes them in the
afterWritehook- Handles both regular and generated barrel exports
- Ensures the generator file is always exported with the wildcard export
The separation of concerns between regular and generated barrel exports is clean and maintainable.
packages/fastify-generators/src/generators/core/logger-service/logger-service.generator.ts (1)
20-20: Good refactoring to use centralized generated modules!The consolidation of imports, paths, and templates into
CORE_LOGGER_SERVICE_GENERATEDimproves maintainability and follows the consistent pattern established across other core generators. The functionality remains intact while reducing duplication.Also applies to: 50-51, 54-54, 58-58, 79-79, 86-86
packages/core-generators/src/renderers/extractor/plugins/template-paths/template-paths.plugin.ts (4)
34-38: LGTM! Clean utility function.The
getPathsRootExportNamefunction properly encapsulates the logic for retrieving the root export name from the paths file export names.
89-125: Excellent addition for centralizing template path resolution!The
resolveTemplatePathsfunction properly encapsulates the path resolution logic with clear error handling. The distinction between singleton and non-singleton templates is well-handled, and the error message provides useful context for debugging.
127-140: Well-integrated with the new barrel export system!The
afterWritehook properly registers generated path files with the barrel export plugin. Good use ofnormalizeTsPathToJsPathto ensure consistent path formats.
196-206: Good improvement to error handling!Throwing an explicit error when no template path root is found is better than silent failure. This will help catch configuration issues early and make debugging easier.
|
|
||
| import { FASTIFY_PACKAGES } from '#src/constants/fastify-packages.js'; | ||
| import { configServiceProvider } from '#src/generators/core/config-service/config-service.generator.js'; | ||
| import { configServiceProvider } from '#src/generators/core/config-service/index.js'; |
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
Validate updated import path for configServiceProvider.
The import path now points to index.js instead of the original generator file. Please ensure that:
packages/fastify-generators/src/generators/core/config-service/index.jsindeed exportsconfigServiceProvider.- Your TypeScript and Node resolution settings support importing
.jsmodules from TS source.
🏁 Script executed:
#!/bin/bash
# Verify that configServiceProvider is exported from the new index file
fd index.js packages/fastify-generators/src/generators/core/config-service/ | \
xargs grep -R "export.*configServiceProvider"Length of output: 250
Ensure configServiceProvider Is Re-exported from index.js
The search shows configServiceProvider is only exported in
packages/fastify-generators/src/generators/core/config-service/config-service.generator.ts
and not re-exported in index.js, so the import from index.js will fail at runtime.
To fix:
- In
packages/fastify-generators/src/generators/core/config-service/index.js, add:export { configServiceProvider } from './config-service.generator.js';
- Or change the import to point directly at the generator file:
import { configServiceProvider } from '#src/generators/core/config-service/config-service.generator';
- Also confirm your
tsconfig.jsonand Node resolution settings (allowJs,moduleResolution: "node") support importing.jsmodules from TS sources.
🤖 Prompt for AI Agents
In packages/fastify-generators/src/generators/prisma/prisma/prisma.generator.ts
at line 33, the import of configServiceProvider from index.js will fail because
index.js does not re-export it. Fix this by either adding an export statement
for configServiceProvider in
packages/fastify-generators/src/generators/core/config-service/index.js that
re-exports it from config-service.generator.js, or change the import in
prisma.generator.ts to directly import from config-service.generator.ts. Also
verify that your tsconfig.json and Node resolution settings support importing
.js modules from TypeScript sources.
| z.object({ | ||
| kind: z.literal('singleton'), | ||
| kind: z.literal('singleton').optional().default('singleton'), | ||
| /** |
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.
discriminatedUnion requires the discriminator to be present – making kind optional will break validation
Zod’s discriminatedUnion('kind', …) demands that the kind property exist in the raw input so it can pick the proper branch.
Marking it .optional().default('singleton') means:
- Input objects that omit
kindnow fail the discriminator check before defaults are applied. - Objects with
kind: undefinedare indistinguishable from the second variant and will also fail.
The previous mandatory literal was correct; keep kind required and rely on the .default({ kind: 'singleton' }) at the union level.
- kind: z.literal('singleton').optional().default('singleton'),
+ kind: z.literal('singleton'),Please add/adjust a unit test that parses an object {} and expects it to succeed due to the union-level default, ensuring future refactors don’t regress this behaviour.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| z.object({ | |
| kind: z.literal('singleton'), | |
| kind: z.literal('singleton').optional().default('singleton'), | |
| /** | |
| z.object({ | |
| kind: z.literal('singleton'), | |
| /** |
🤖 Prompt for AI Agents
In packages/core-generators/src/renderers/schemas/template-file-options.ts
around lines 5 to 7, the 'kind' property is incorrectly marked as optional with
a default, which breaks Zod's discriminatedUnion validation that requires 'kind'
to be present in the input. Change 'kind' to be a required literal without
'.optional().default()' and instead apply the default at the union schema level.
Additionally, add or update a unit test to parse an empty object '{}' and assert
that it succeeds by using the union-level default, preventing future
regressions.
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.
That's actually not necessary. Allows fileOptions to be set to {}
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.
@kingston Got it — I understand you’d like callers to be able to pass an empty object ({}) for fileOptions.
Just a heads-up: with Zod’s current implementation, making the discriminant optional does not actually achieve that.
z.discriminatedUnion('kind', …) looks at the raw input before any defaults are applied. If the kind key is missing (as in {}), discriminatedUnion can’t decide which branch to use and the parse fails.
Quick check:
import { z } from 'zod';
const schemaRequired = z.discriminatedUnion('kind', [
z.object({ kind: z.literal('singleton') }),
z.object({ kind: z.literal('instance') }),
]);
const schemaOptional = z.discriminatedUnion('kind', [
z.object({ kind: z.literal('singleton').optional().default('singleton') }),
z.object({ kind: z.literal('instance') }),
]);
schemaRequired.parse({ kind: 'singleton' }); // ✅
schemaRequired.parse({}); // ❌ Error: "Invalid discriminator value. Expected 'singleton' | 'instance'"
schemaOptional.parse({ kind: 'singleton' }); // ✅
schemaOptional.parse({}); // ❌ same error(The optional/default on the field is ignored during the discriminator check.)
To allow fileOptions = {} you’ll need a different approach, e.g.:
- Wrap the discriminated union in a
.default({ kind: 'singleton' })and make the whole field optional at the call site, or - Use a regular union + custom refine, or
- Accept
{}via.partial()and coerce afterwards.
Happy to adjust if you’d like to explore one of these, otherwise I’ll leave the current change as-is. Let me know!
| const TSX_VARIABLE_REGEX = | ||
| /\{\/\* TPL_([A-Z0-9_]+):START \*\/\}([\s\S]*?)\{\/\* TPL_\1:END \*\/\}/g; | ||
| const COMMENT_VARIABLE_REGEX = | ||
| /\/\* TPL_([A-Z0-9_]+):COMMENT:START \*\/([\s\S]*?)\/\* TPL_\1:COMMENT:END \*\//g; |
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.
TSX variable regex too strict – fails with whitespace/newlines
Prettier frequently emits { /* TPL_FOO:START */ }, with spaces/newlines between the brace and the comment. The current pattern requires them to be adjacent, so such variables are silently skipped.
-const TSX_VARIABLE_REGEX =
- /\{\/\* TPL_([A-Z0-9_]+):START \*\/\}([\s\S]*?)\{\/\* TPL_\1:END \*\/\}/g;
+const TSX_VARIABLE_REGEX =
+ /\{\s*\/\*\s*TPL_([A-Z0-9_]+):START\s*\*\/\s*\}([\s\S]*?)\{\s*\/\*\s*TPL_\1:END\s*\*\/\s*\}/g;This loosens the pattern while keeping it anchored to the same variable name.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const TSX_VARIABLE_REGEX = | |
| /\{\/\* TPL_([A-Z0-9_]+):START \*\/\}([\s\S]*?)\{\/\* TPL_\1:END \*\/\}/g; | |
| const COMMENT_VARIABLE_REGEX = | |
| /\/\* TPL_([A-Z0-9_]+):COMMENT:START \*\/([\s\S]*?)\/\* TPL_\1:COMMENT:END \*\//g; | |
| const TSX_VARIABLE_REGEX = | |
| /\{\s*\/\*\s*TPL_([A-Z0-9_]+):START\s*\*\/\s*\}([\s\S]*?)\{\s*\/\*\s*TPL_\1:END\s*\*\/\s*\}/g; | |
| const COMMENT_VARIABLE_REGEX = | |
| /\/\* TPL_([A-Z0-9_]+):COMMENT:START \*\/([\s\S]*?)\/\* TPL_\1:COMMENT:END \*\//g; |
🤖 Prompt for AI Agents
In
packages/core-generators/src/renderers/typescript/extractor-v2/extract-ts-template-variables.ts
around lines 9 to 12, the TSX_VARIABLE_REGEX is too strict because it requires
the comment to be immediately adjacent to the braces, causing it to miss matches
when there are spaces or newlines. Modify the regex to allow optional whitespace
characters between the braces and the comment markers while still anchoring to
the same variable name, so it correctly matches patterns like `{ /*
TPL_FOO:START */ }` with spaces or newlines.
| const mockFileIdMap = new Map<string, string>([]); | ||
|
|
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.
Instantiate a fresh Map per test to avoid state bleed-through
mockFileIdMap is declared once and then passed into every new TemplateExtractorConfigLookup.
If TemplateExtractorConfigLookup mutates the supplied map (very likely, given the “ID map” semantics), test cases may influence one another. Create a new map inside each test or in beforeEach instead:
-const mockFileIdMap = new Map<string, string>([]);
+let mockFileIdMap: Map<string, string>;
+
+beforeEach(() => {
+ mockFileIdMap = new Map<string, string>();
+ vol.reset();
+});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const mockFileIdMap = new Map<string, string>([]); | |
| // replace the single, shared const with a fresh map per test | |
| - const mockFileIdMap = new Map<string, string>([]); | |
| + let mockFileIdMap: Map<string, string>; | |
| + | |
| + beforeEach(() => { | |
| + mockFileIdMap = new Map<string, string>(); | |
| + vol.reset(); | |
| + }); |
🤖 Prompt for AI Agents
In
packages/sync/src/templates/extractor-v2/utils/merge-extractor-template-entries.unit.test.ts
around lines 22 to 23, the mockFileIdMap is declared once and shared across
tests, which risks state bleed-through if mutated. To fix this, move the
instantiation of mockFileIdMap inside each test or into a beforeEach hook so
that each test gets a fresh Map instance, preventing tests from affecting each
other's state.
| const startMarkerRegex = /(\w+)\s*(\/\* (TPL_[A-Z0-9_]+):START \*\/)\s*\(/g; | ||
| transformedCode = transformedCode.replaceAll( | ||
| startMarkerRegex, | ||
| (match, identifier, startMarkerComment) => | ||
| // Replace with: identifier, opening parenthesis, the START comment | ||
| `${identifier}(${startMarkerComment}`, | ||
| ); |
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
Regex too strict – breaks on member or generic calls
startMarkerRegex only matches an identifier made of \w+.
Cases like obj.method /* … */( or factory<MyType> /* … */( will be missed, causing incomplete preprocessing and extraction errors.
A slightly more permissive pattern fixes this:
-const startMarkerRegex = /(\w+)\s*(\/\* (TPL_[A-Z0-9_]+):START \*\/)\s*\(/g;
+const startMarkerRegex = /([\w.$<>]+)\s*(\/\* (TPL_[A-Z0-9_]+):START \*\/)\s*\(/g;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const startMarkerRegex = /(\w+)\s*(\/\* (TPL_[A-Z0-9_]+):START \*\/)\s*\(/g; | |
| transformedCode = transformedCode.replaceAll( | |
| startMarkerRegex, | |
| (match, identifier, startMarkerComment) => | |
| // Replace with: identifier, opening parenthesis, the START comment | |
| `${identifier}(${startMarkerComment}`, | |
| ); | |
| const startMarkerRegex = /([\w.$<>]+)\s*(\/\* (TPL_[A-Z0-9_]+):START \*\/)\s*\(/g; | |
| transformedCode = transformedCode.replaceAll( | |
| startMarkerRegex, | |
| (match, identifier, startMarkerComment) => | |
| // Replace with: identifier, opening parenthesis, the START comment | |
| `${identifier}(${startMarkerComment}`, | |
| ); |
🤖 Prompt for AI Agents
In
packages/core-generators/src/renderers/typescript/extractor-v2/preprocess-code-for-extraction-hack.ts
around lines 23 to 29, the regex startMarkerRegex is too restrictive by only
matching simple word characters (\w+) as identifiers, which fails on member
accesses like obj.method or generic calls like factory<MyType>. Update the regex
to allow more complex identifiers including dots and angle brackets so it
matches these cases, ensuring the preprocessing correctly captures all relevant
patterns.
| barrelExportPlugin.addGeneratedBarrelExport(generatorName, { | ||
| moduleSpecifier: `./${normalizeTsPathToJsPath(TYPED_TEMPLATES_FILE_NAME)}`, | ||
| namedExport: exportName, | ||
| name: 'templates', | ||
| }); |
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.
Barrel export path is wrong – generated file lives in a sub-directory
TYPED_TEMPLATES_FILE_PATH resolves to generated/typed-templates.ts, but the barrel export currently points to ./typed-templates.js.
Consumers will get “module not found” at runtime.
- moduleSpecifier: `./${normalizeTsPathToJsPath(TYPED_TEMPLATES_FILE_NAME)}`,
+ moduleSpecifier: `./${normalizeTsPathToJsPath(
+ TYPED_TEMPLATES_FILE_PATH,
+ )}`,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| barrelExportPlugin.addGeneratedBarrelExport(generatorName, { | |
| moduleSpecifier: `./${normalizeTsPathToJsPath(TYPED_TEMPLATES_FILE_NAME)}`, | |
| namedExport: exportName, | |
| name: 'templates', | |
| }); | |
| barrelExportPlugin.addGeneratedBarrelExport(generatorName, { | |
| moduleSpecifier: `./${normalizeTsPathToJsPath( | |
| TYPED_TEMPLATES_FILE_PATH, | |
| )}`, | |
| namedExport: exportName, | |
| name: 'templates', | |
| }); |
🤖 Prompt for AI Agents
In
packages/core-generators/src/renderers/extractor/plugins/typed-templates-file.ts
around lines 102 to 106, the barrel export path incorrectly points to
'./typed-templates.js' instead of the correct sub-directory path. Update the
moduleSpecifier to use TYPED_TEMPLATES_FILE_PATH (normalized to a JS path) to
reflect the actual location of the generated file, ensuring consumers can
resolve the module at runtime without errors.
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.
That's accurate since generated barrel export is from the generated directory.
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.
@kingston Got it—thanks for clarifying.
Because the barrel-export plugin writes into generated/index.ts, the moduleSpecifier indeed needs to be relative to that file, so ./${normalizeTsPathToJsPath(TYPED_TEMPLATES_FILE_NAME)} is the correct value. I’m withdrawing the suggestion. 👍
✏️ Learnings added
Learnt from: kingston
PR: halfdomelabs/baseplate#571
File: packages/core-generators/src/renderers/extractor/plugins/typed-templates-file.ts:102-106
Timestamp: 2025-06-11T18:31:22.221Z
Learning: For `templateExtractorBarrelExportPlugin.addGeneratedBarrelExport`, the generated barrel exports are written into `generated/index.ts`, therefore the `moduleSpecifier` must be specified relative to that file (e.g., `./typed-templates.js`), not the project root.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
| // Write file ID map | ||
| const fileIdMap = Object.fromEntries( | ||
| [...fileIdToRelativePathMap.entries()].sort(([a], [b]) => | ||
| a.localeCompare(b), | ||
| ), | ||
| ); | ||
| await writeJson(path.join(projectDirectory, FILE_ID_MAP_PATH), fileIdMap); | ||
| await writeGeneratedFileIdMap(projectDirectory, fileIdToRelativePathMap); | ||
|
|
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
writeGeneratedFileIdMap bypasses the pluggable operations interface
Every other side-effect is routed through operations to aid testing & overriding, but this one calls the concrete import directly.
Add it to GeneratorOperations (with a sensible default) and invoke via operations.writeGeneratedFileIdMap(...) for consistency.
🤖 Prompt for AI Agents
In packages/project-builder-server/src/sync/generate-for-directory.ts around
lines 203 to 205, the call to writeGeneratedFileIdMap bypasses the pluggable
operations interface used elsewhere. To fix this, add writeGeneratedFileIdMap as
a method to the GeneratorOperations interface with a default implementation,
then replace the direct call with operations.writeGeneratedFileIdMap(...) to
maintain consistency and enable easier testing and overriding.
| const templateMetadata: TsTemplateOutputTemplateMetadata | undefined = { | ||
| name: template.name, | ||
| template: | ||
| 'path' in template.source | ||
| ? template.source.path | ||
| ? // TODO[2025-06-11]: Remove this once we've migrated all TS templates. | ||
| path.isAbsolute(template.source.path) | ||
| ? '' | ||
| : template.source.path | ||
| : 'content-only-template', | ||
| generator: generatorInfo.name, |
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.
Consider preserving template identification for absolute paths.
Setting the template path to an empty string for absolute paths (line 119) removes valuable debugging information from the template metadata. Consider using a descriptive identifier like '<absolute-path>' or extracting the filename instead.
template:
'path' in template.source
- ? // TODO[2025-06-11]: Remove this once we've migrated all TS templates.
- path.isAbsolute(template.source.path)
- ? ''
- : template.source.path
+ ? path.isAbsolute(template.source.path)
+ ? `<absolute:${path.basename(template.source.path)}>`
+ : template.source.path
: 'content-only-template',📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const templateMetadata: TsTemplateOutputTemplateMetadata | undefined = { | |
| name: template.name, | |
| template: | |
| 'path' in template.source | |
| ? template.source.path | |
| ? // TODO[2025-06-11]: Remove this once we've migrated all TS templates. | |
| path.isAbsolute(template.source.path) | |
| ? '' | |
| : template.source.path | |
| : 'content-only-template', | |
| generator: generatorInfo.name, | |
| const templateMetadata: TsTemplateOutputTemplateMetadata | undefined = { | |
| name: template.name, | |
| template: | |
| 'path' in template.source | |
| ? path.isAbsolute(template.source.path) | |
| ? `<absolute:${path.basename(template.source.path)}>` | |
| : template.source.path | |
| : 'content-only-template', | |
| generator: generatorInfo.name, | |
| // …other fields… | |
| }; |
🤖 Prompt for AI Agents
In
packages/core-generators/src/renderers/typescript/actions/render-ts-template-file-action.ts
between lines 113 and 122, the template path is set to an empty string when it
is an absolute path, which removes useful debugging information. Instead of
setting it to an empty string, update the code to preserve a meaningful
identifier by either using a placeholder like '<absolute-path>' or extracting
and using the filename from the absolute path to retain useful metadata for
debugging.
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.
This is just temporary while we transition
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.
@kingston Got it — since this empty-string placeholder is only a stop-gap during the transition, we’ll leave the current logic untouched for now. When the migration is finished and the metadata format stabilizes, we can revisit this to restore richer template identifiers.
(ʘ curious bunny peers at migrating code ʘ)
| >; | ||
|
|
||
| export interface TsTemplateVariable {} | ||
| export interface TsTemplateFileVariable {} |
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.
Replace empty interface with type alias or add documentation.
The empty interface TsTemplateFileVariable is flagged by static analysis. If this is a placeholder for future properties, document it. Otherwise, use a type alias.
Option 1 - Use a type alias:
-export interface TsTemplateFileVariable {}
+export type TsTemplateFileVariable = Record<string, never>;Option 2 - Document the placeholder:
+/**
+ * Placeholder interface for template file variables.
+ * Currently empty but reserved for future properties.
+ */
export interface TsTemplateFileVariable {}🧰 Tools
🪛 Biome (1.9.4)
[error] 130-130: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
🪛 ESLint
[error] 130-130: An empty interface declaration allows any non-nullish value, including literals like 0 and "".
- If that's what you want, disable this lint rule with an inline comment or configure the 'allowInterfaces' rule option.
- If you want a type meaning "any object", you probably want
objectinstead. - If you want a type meaning "any value", you probably want
unknowninstead.
(@typescript-eslint/no-empty-object-type)
🤖 Prompt for AI Agents
In packages/core-generators/src/renderers/typescript/templates/types.ts at line
130, the empty interface TsTemplateFileVariable should be replaced with a type
alias if it is not intended to have properties, or add a comment above it
explaining it is a placeholder for future properties. Choose one approach:
either convert the empty interface to a type alias with an empty object type or
add clear documentation to justify the empty interface.
| import { templateConfigSchema } from '@baseplate-dev/sync/extractor-v2'; | ||
| import { | ||
| TemplateFileOptions, | ||
| templateFileOptionsSchema, | ||
| } from '#src/renderers/schemas/template-file-options.js'; |
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.
Fix import ordering and use type-only imports.
The static analysis correctly identifies import ordering issues and that TemplateFileOptions is only used as a type.
Apply this diff to fix the issues:
-import { CASE_VALIDATORS } from '@baseplate-dev/utils';
-import { templateConfigSchema } from '@baseplate-dev/sync/extractor-v2';
-import {
- TemplateFileOptions,
- templateFileOptionsSchema,
-} from '#src/renderers/schemas/template-file-options.js';
+import { CASE_VALIDATORS } from '@baseplate-dev/utils';
+import { templateConfigSchema } from '@baseplate-dev/sync/extractor-v2';
+
+import type { TemplateFileOptions } from '#src/renderers/schemas/template-file-options.js';
+import { templateFileOptionsSchema } from '#src/renderers/schemas/template-file-options.js';Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 ESLint
[error] 10-10: Expected "@baseplate-dev/sync/extractor-v2" to come before "@baseplate-dev/utils".
(perfectionist/sort-imports)
[error] 11-14: Imports "TemplateFileOptions" are only used as type.
(@typescript-eslint/consistent-type-imports)
[error] 11-14: Missed spacing between "@baseplate-dev/sync/extractor-v2" and "#src/renderers/schemas/template-file-options.js".
(perfectionist/sort-imports)
🤖 Prompt for AI Agents
In packages/core-generators/src/renderers/typescript/templates/types.ts around
lines 10 to 14, the import statements have ordering issues and
TemplateFileOptions is used only as a type. Reorder the imports to follow the
project's import order conventions and change the import of TemplateFileOptions
to a type-only import to avoid including unnecessary code in the bundle.
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
Chores