Skip to content

Conversation

@kingston
Copy link
Collaborator

@kingston kingston commented Jan 10, 2025

  • Also major re-work of code-morph to be able to apply code morphs across multiple packages of Baseplate

Summary by CodeRabbit

Release Notes

  • New Features

    • Transitioned generators from a child-based to a task-based architecture
    • Enhanced modularity and organization of generator functionality across multiple packages
  • Refactoring

    • Updated generator creation methods in @halfdomelabs/sync, @halfdomelabs/code-morph, @halfdomelabs/fastify-generators, and @halfdomelabs/react-generators
    • Replaced createGeneratorWithChildren with createGeneratorWithTasks
    • Restructured task management and execution flow
  • Dependency Updates

    • Updated ts-morph to version 25.0.0 across multiple packages
    • Updated @inquirer/prompts to version 7.2.1 in @halfdomelabs/create-project
  • Chores

    • Removed deprecated create-generator-with-children.ts utility
    • Consolidated project structure and path mappings

@linear
Copy link

linear bot commented Jan 10, 2025

@changeset-bot
Copy link

changeset-bot bot commented Jan 10, 2025

🦋 Changeset detected

Latest commit: d7fe51b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@halfdomelabs/code-morph Minor
@halfdomelabs/baseplate-plugin-storage Patch
@halfdomelabs/fastify-generators Patch
@halfdomelabs/react-generators Patch
@halfdomelabs/core-generators Patch
@halfdomelabs/create-project Patch
@halfdomelabs/sync Patch
@halfdomelabs/project-builder-common Patch
@halfdomelabs/cli Patch
@halfdomelabs/project-builder-server Patch
@halfdomelabs/project-builder-test Patch
@halfdomelabs/project-builder-lib Patch
@halfdomelabs/project-builder-cli Patch
@halfdomelabs/project-builder-web Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jan 10, 2025

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Walkthrough

This pull request introduces a significant architectural shift across multiple packages, primarily moving from a child generator model to a task-based generator model. The changes span numerous generators in packages like react-generators, fastify-generators, core-generators, and code-morph. The transition involves replacing createGeneratorWithChildren with createGeneratorWithTasks, restructuring how generators define and execute their logic. Additionally, the project updates dependencies, refactors utility functions, and consolidates project structure.

Changes

File/Directory Change Summary
.vscode/generator.json.code-snippets Removed GeneratorWithConfig snippet
packages/code-morph/ Major restructuring of project, updated dependencies, added new utility functions and morphers
packages/core-generators/ Updated ts-morph dependency, refactored generators to use task-based approach
packages/create-project/ Updated @inquirer/prompts dependency, minor logging changes
packages/fastify-generators/ Updated ts-morph dependency, comprehensive refactoring of generators to task-based model
packages/react-generators/ Comprehensive refactoring of generators to task-based model
packages/sync/ Removed createGeneratorWithChildren, updated createGeneratorWithTasks

Sequence Diagram

sequenceDiagram
    participant Generator as Generator
    participant TaskBuilder as TaskBuilder
    participant Task as Main Task
    participant Dependencies as Dependencies
    participant Exports as Exports

    Generator->>TaskBuilder: createGeneratorWithTasks
    TaskBuilder->>Task: addTask('main')
    Task->>Dependencies: Define dependencies
    Task->>Exports: Define exports
    Task->>Task: Define run method
    Task-->>Generator: Return task configuration
Loading

This diagram illustrates the new task-based generator creation process, showing how generators now use a task builder to define their structure and behavior, with a clear separation of dependencies, exports, and execution logic.


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kingston
Copy link
Collaborator Author

@coderabbitai pause

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 26

🔭 Outside diff range comments (4)
packages/react-generators/src/generators/auth0/react-auth0/index.ts (1)

Line range hint 61-84: Validate callback path to prevent potential injection.

The dynamic construction of redirect URI using template literals could be vulnerable to injection if callbackPath is not properly sanitized. Consider adding path validation in the descriptor schema.

Apply this diff to add validation:

 const descriptorSchema = z.object({
-  callbackPath: z.string().optional(),
+  callbackPath: z.string().regex(/^[a-zA-Z0-9\-_\/]+$/).optional(),
 });
packages/fastify-generators/src/generators/core/fastify-cookie-context/index.ts (1)

Line range hint 59-69: Missing import for 'FastifyReply'

The FastifyReply type is used in the getReply function but is not imported, which will result in a TypeScript error.

Add the following import statement to fix the issue:

+import { FastifyReply } from 'fastify';
packages/fastify-generators/src/generators/vitest/prisma-vitest/index.ts (1)

Line range hint 73-97: Handle Asynchronous Operations in Vitest Setup Correctly

The custom setup block includes asynchronous code but does not handle it within an async function:

const { TEST_MODE } = process.env;

// don't run database set-up if only running unit tests
if (TEST_MODE !== 'unit') {
  // ...
}

Vitest setup files support asynchronous operations if they return a promise. Consider wrapping the setup code in an async function and exporting it, or using beforeAll hooks within your tests to handle asynchronous initialization.

Example:

+export default async () => {
  const { TEST_MODE } = process.env;

  if (TEST_MODE !== 'unit') {
    // async operations
  }
+};
packages/fastify-generators/src/generators/core/readme/index.ts (1)

Line range hint 21-46: Consider templating the README content.

The README content is hardcoded, making it difficult to maintain and customize.

Consider moving the content to a template file and adding customization options:

-        const readmeContent = `# ${projectName}\n\nThis project...`;
+        const template = await builder.readFile('templates/README.md.template');
+        const readmeContent = template.replace('${projectName}', projectName);
🧹 Nitpick comments (81)
packages/fastify-generators/src/generators/vitest/fastify-vitest/index.ts (2)

22-25: Consider removing unused child generator configuration.

Since we're transitioning to a task-based approach, the getDefaultChildGenerators returning an empty object might be unnecessary.

 const FastifyVitestGenerator = createGeneratorWithTasks({
   descriptorSchema,
-  getDefaultChildGenerators: () => ({}),
   buildTasks(taskBuilder) {

26-59: Consider using a more descriptive task name.

While the task implementation looks good, the generic name "main" could be more descriptive of its purpose, such as "setupVitestConfig" or "configureTestEnvironment".

     taskBuilder.addTask({
-      name: 'main',
+      name: 'setupVitestConfig',
       dependencies: {
packages/code-morph/src/types.ts (3)

9-13: Add JSDoc documentation for better developer experience.

While the interface is well-structured, adding JSDoc documentation would improve clarity, especially for the Optional generic parameter and validation field usage.

+/**
+ * Configuration options for a TypeScript morpher.
+ * @template Optional - Determines if the option is required or optional
+ */
 interface MorpherOption<Optional extends boolean> {
+  /** Whether this option can be omitted */
   optional: Optional;
+  /** Human-readable description of the option */
   description?: string;
+  /** Zod schema for validating the option value */
   validation?: z.ZodString;
 }

15-30: Excellent type-safe design with room for a minor enhancement.

The interface is well-crafted with proper type safety and flexibility. The conditional types for handling optional/required options are particularly well done.

Consider adding validation for pathGlobs to ensure they're valid glob patterns:

   transform: TransformFunction<{
     [key in keyof Options]: Options[key] extends MorpherOption<true>
       ? string | undefined
       : string;
   }>;
-  pathGlobs?: string[];
+  pathGlobs?: readonly string[];

Making pathGlobs readonly would prevent accidental modifications during runtime.


32-36: Consider adding runtime validation in the factory function.

The factory function currently acts as an identity function. Consider adding runtime validation to ensure all required options have validation rules and that the morpher object is properly structured.

 export function createTypescriptMorpher<
   Options extends Record<string, MorpherOption<boolean>>,
 >(morpher: TypescriptMorpher<Options>): TypescriptMorpher<Options> {
+  // Validate required options have validation rules
+  Object.entries(morpher.options).forEach(([key, option]) => {
+    if (!option.optional && !option.validation) {
+      throw new Error(`Required option "${key}" must have a validation rule`);
+    }
+  });
+
   return morpher;
 }
packages/core-generators/src/generators/node/ts-utils/index.ts (3)

60-68: Consider using a more descriptive task name.

While the implementation is correct, consider renaming the task from "main" to something more descriptive like "generateTsUtils" or "copyUtilFiles" to better reflect its purpose.


72-88: Consider using path utilities for robust path handling.

The current implementation uses string replacement (replace(/\.ts$/, '.js')) for path construction. Consider using Node.js path utilities to make this more robust:

-path: `@/src/utils/${config.file.replace(/\.ts$/, '.js')}`,
+path: `@/src/utils/${path.basename(config.file, '.ts')}.js`,

89-117: Consider optimizing dependency resolution.

The current implementation recursively resolves dependencies for each used template. Consider pre-computing the dependency tree or using memoization to avoid redundant resolution:

// Pre-compute dependency tree once
const dependencyTree: Record<string, Set<string>> = {};
for (const [key, config] of Object.entries(UTIL_CONFIG_MAP)) {
  dependencyTree[key] = new Set();
  const stack = [...(config.dependencies ?? [])];
  while (stack.length > 0) {
    const dep = stack.pop()!;
    dependencyTree[key].add(dep);
    stack.push(...(UTIL_CONFIG_MAP[dep].dependencies ?? []));
  }
}

This would simplify the build process and improve performance for larger dependency trees.

packages/fastify-generators/src/generators/core/fastify-health-check/index.ts (4)

28-31: Consider removing unused child generator configuration

Since we're moving to a task-based model, the getDefaultChildGenerators returning an empty object might be unnecessary. Consider removing it if it's no longer needed in the new architecture.

 const FastifyHealthCheckGenerator = createGeneratorWithTasks({
   descriptorSchema,
-  getDefaultChildGenerators: () => ({}),
   buildTasks(taskBuilder) {

31-41: Consider using a more descriptive task name

The task name 'main' is quite generic. Consider using a more descriptive name that reflects the task's purpose, such as 'setupHealthCheck' or 'configureHealthCheckPlugin'.


60-94: Consider adding error handling for the build process

The build method performs several operations that could potentially fail (template rendering, file operations). Consider adding try-catch blocks and proper error handling.

 build: async (builder) => {
+  try {
     const healthCheckPlugin = typescript.createTemplate({
       CHECK: { type: 'code-expression' },
     });
     // ... existing code ...
     await builder.apply(
       healthCheckPlugin.renderToAction(
         'health-check.ts',
         'src/plugins/health-check.ts',
       ),
     );
+  } catch (error) {
+    throw new Error(`Failed to build health check plugin: ${error.message}`);
+  }
 },

72-79: Consider extracting template string to a constant

The template string for wrapping check content could be extracted to improve readability and maintainability.

+const CHECK_WRAPPER_TEMPLATE = `
+async () => {
+  %s
+
+  return { success: true }
+}
+`.trim();
+
 checksBlock.wrapAsExpression((content) =>
-  `async () => {
-    ${content}
-
-    return { success: true }
-  }
-  `.trim(),
+  CHECK_WRAPPER_TEMPLATE.replace('%s', content),
 ),
packages/react-generators/src/generators/auth0/auth0-components/index.ts (2)

19-19: Consider using a more descriptive task name

The task name 'main' is generic. Consider using a more descriptive name that reflects the task's purpose, such as 'setupAuth0Components' or 'generateRequireAuthComponent'.


27-52: Consider breaking down the task implementation

The current task implementation handles multiple responsibilities including component registration, import mapping, and file generation. Consider breaking this into smaller, focused tasks for better maintainability and testing.

Here's a suggested refactoring approach:

  buildTasks(taskBuilder) {
-   taskBuilder.addTask({
-     name: 'main',
+   taskBuilder.addTask({
+     name: 'registerComponents',
+     dependencies: {
+       reactComponents: reactComponentsProvider,
+     },
+     run({ reactComponents }) {
+       reactComponents.registerComponent({ name: 'RequireAuth' });
+       return { componentName: 'RequireAuth' };
+     },
+   });
+
+   taskBuilder.addTask({
+     name: 'setupImports',
+     dependencies: {
+       reactComponents: reactComponentsProvider,
+     },
+     run({ reactComponents }) {
+       return {
+         getProviders: () => ({
+           authComponents: {
+             getImportMap: () => ({
+               '%auth-components': {
+                 path: reactComponents.getComponentsImport(),
+                 allowedImports: ['RequireAuth'],
+               },
+             }),
+           },
+         }),
+       };
+     },
+   });
+
+   taskBuilder.addTask({
+     name: 'generateFiles',
      dependencies: {
        reactComponents: reactComponentsProvider,
        typescript: typescriptProvider,
      },
-     exports: {
-       authComponents: authComponentsProvider.export(projectScope),
-     },
      run({ reactComponents, typescript }) {
        const [, requireAuthPath] = makeImportAndFilePath(
          `${reactComponents.getComponentsFolder()}/RequireAuth/index.tsx`,
        );
-       reactComponents.registerComponent({ name: 'RequireAuth' });

        return {
-         getProviders: () => ({
-           authComponents: {
-             getImportMap: () => ({
-               '%auth-components': {
-                 path: reactComponents.getComponentsImport(),
-                 allowedImports: ['RequireAuth'],
-               },
-             }),
-           },
-         }),
          build: async (builder) => {
            await builder.apply(
              typescript.createCopyAction({
                source: 'RequireAuth.tsx',
                destination: requireAuthPath,
              }),
            );
          },
        };
      },
    });
packages/fastify-generators/src/generators/auth/prisma-password-transformer/index.ts (1)

17-22: Consider using a more descriptive task name

While the task structure and dependency declaration look good, consider renaming the task from 'main' to something more descriptive like 'addPasswordTransformer' to better reflect its purpose.

-      name: 'main',
+      name: 'addPasswordTransformer',
packages/react-generators/src/generators/core/react-tailwind/index.ts (1)

99-99: Consider implementing dark mode support.

The TODO comment indicates that dark mode is not currently supported. Given Tailwind's built-in dark mode capabilities, this could be a valuable addition.

Would you like me to help implement dark mode support or create a GitHub issue to track this enhancement?

packages/react-generators/src/generators/apollo/apollo-error/index.ts (2)

26-34: Consider task granularity for future maintainability.

The current implementation uses a single 'main' task. As complexity grows, consider breaking this into smaller, focused tasks (e.g., separate tasks for utility setup and provider configuration).


35-35: Consider adding return type for task run method.

To enhance type safety and maintainability, consider explicitly defining the return type interface for the task's run method.

-      run({ typescript }) {
+      run({ typescript }): Promise<{
+        getProviders: () => {
+          apolloError: {
+            getImportMap: () => Record<string, { path: string; allowedImports: string[] }>;
+          };
+        };
+        build: (builder: any) => Promise<void>;
+      }> {
packages/fastify-generators/src/generators/prisma/prisma-model-index/index.ts (2)

10-12: Remove unnecessary getDefaultChildGenerators

Since we're transitioning to a task-based approach, the getDefaultChildGenerators returning an empty object appears to be unnecessary.

 const PrismaModelIndexGenerator = createGeneratorWithTasks({
   descriptorSchema,
-  getDefaultChildGenerators: () => ({}),

19-24: Consider enhancing error handling and return value

Two suggestions for improvement:

  1. The empty object return value (return {}) could be more meaningful by returning the result of the operation or removing it if truly nothing needs to be returned.
  2. Consider adding error handling for the addModelAttribute operation in case it fails.

Example implementation:

   run({ prismaModel }) {
+    try {
       prismaModel.addModelAttribute({
         name: 'index',
         args: [fields],
       });
-      return {};
+      return { success: true };
+    } catch (error) {
+      throw new Error(`Failed to add index attribute: ${error.message}`);
+    }
   },
packages/react-generators/src/generators/auth0/auth0-apollo/index.ts (2)

21-24: Well-structured transition to task-based architecture.

The new structure using buildTasks provides better organization and clarity compared to the previous children-based approach. The empty default child generators object correctly indicates this is a leaf generator.

Consider documenting the task-based architecture pattern in the project's technical documentation to help other developers understand this new pattern.


50-69: Consider enhancing error handling in the auth link setup.

The Apollo link setup is well-structured, but consider adding more robust error handling:

 build: async (builder) => {
   const linkTemplate = await builder.readTemplate('auth-link.ts');
+  if (!linkTemplate) {
+    throw new Error('Failed to load auth-link.ts template');
+  }
   const authLink = TypescriptCodeUtils.extractTemplateSnippet(
     linkTemplate,
     'AUTH_LINK',
   );
+  if (!authLink) {
+    throw new Error('Failed to extract AUTH_LINK snippet');
+  }
packages/fastify-generators/src/generators/prisma/prisma-timestamp-fields/index.ts (2)

25-29: Ensure consistent ordering of field attributes

The order of attributes in the createdAt and updatedAt fields is inconsistent. For better readability and maintainability, consider aligning the attribute order.

Apply this diff to reorder the attributes in the updatedAt field:

          attributes: [
            { name: '@map', args: [`"updated_at"`] },
+           { name: '@db.Timestamptz', args: ['3'] },
            { name: '@default', args: [`now()`] },
            { name: '@updatedAt' },
-           { name: '@db.Timestamptz', args: ['3'] },
          ],

Also applies to: 38-43


48-48: Unnecessary return statement in run method

The run method returns an empty object, which may be unnecessary if the method does not require a return value. Removing the return {}; statement can simplify the code.

Apply this diff to remove the unnecessary return statement:

         }
-        return {};
       },
packages/react-generators/src/generators/auth0/auth0-hooks/index.ts (2)

48-72: Consider using immutable state management.

The currentUserFields array is mutable and modified through addCurrentUserField. This could lead to issues in concurrent scenarios.

Consider using immutable state management:

- const currentUserFields: string[] = [];
+ let currentUserFields: readonly string[] = [];
  
  // ...
  addCurrentUserField: (field: string) => {
-   currentUserFields.push(field);
+   currentUserFields = [...currentUserFields, field];
  },

73-120: Consider enhancing error handling for file operations.

The build implementation uses multiple await builder.apply() calls for file operations, but error handling could be improved.

Consider wrapping file operations in try-catch blocks and adding error recovery logic:

  build: async (builder) => {
+   try {
      await builder.apply(
        typescript.createCopyAction({
          source: 'hooks/useCurrentUser.ts',
          destination: useCurrentUserPath,
          // ...
        }),
      );
      // ... other operations
+   } catch (error) {
+     // Log error details
+     throw new Error(`Failed to build Auth0 hooks: ${error.message}`);
+   }
  },
packages/fastify-generators/src/generators/core/fastify-cookie-context/index.ts (1)

70-79: Unnecessary 'void' operator in 'set' and 'clear' methods

In the set and clear methods within the creator function, the use of the void operator before function calls is unnecessary and may reduce code readability. Since these methods do not need to alter the return value, you can remove the void operator.

Apply this diff to remove the void operator:

- set: (name, value, options) => void reply.setCookie(name, value, options),
- clear: (name) => void reply.clearCookie(name),
+ set: (name, value, options) => reply.setCookie(name, value, options),
+ clear: (name) => reply.clearCookie(name),
packages/fastify-generators/src/generators/core/fastify-server/index.ts (1)

171-173: Add error handling for asynchronous apply operations

In the build function, consider adding error handling for the asynchronous builder.apply calls when rendering index.ts and server.ts. This ensures that any errors during file generation are caught and managed appropriately.

Apply this diff to add error handling:

 await builder.apply(
   indexFile.renderToAction('index.ts', 'src/index.ts'),
+).catch(error => {
+  console.error('Error applying index file:', error);
+});

...

 await builder.apply(
   serverFile.renderToAction('server.ts', 'src/server.ts'),
+).catch(error => {
+  console.error('Error applying server file:', error);
+});

Also applies to: 216-218

packages/code-morph/src/utils/find-workspace-projects.ts (1)

55-55: Improve TypeScript type narrowing in the filter function

The filter at line 55 removes undefined values but doesn't inform TypeScript of the narrowed type. Modify the filter to include a type predicate for better type safety.

Apply this diff to refine the filter function:

       );

-      return packagesWithNames.filter((p) => p !== undefined);
+      return packagesWithNames.filter(
+        (p): p is WorkspacePackage => p !== undefined,
+      );
     }
packages/fastify-generators/src/generators/prisma/prisma-relation-field/index.ts (1)

57-57: Consider renaming isManyToOne for clarity

The variable isManyToOne derives from relationshipType === 'oneToMany', which might be confusing. Consider renaming it to isOneToMany to better reflect the relationship type and enhance code readability.

packages/fastify-generators/src/generators/auth/auth-roles/index.ts (1)

56-61: Simplify the role existence check using a Set for efficiency

The current implementation checks for the existence of required roles using the every and some methods:

if (!['public', 'user', 'system'].every((name) => roles.some((r) => r.name === name))) {
  throw new Error('public, user, and system roles are required');
}

Consider improving the efficiency by converting the role names into a Set for faster lookup:

Apply this diff to simplify the check:

 const roleNamesSet = new Set(roles.map((r) => r.name));
 if (!['public', 'user', 'system'].every((name) => roleNamesSet.has(name))) {
   throw new Error('public, user, and system roles are required');
 }
packages/react-generators/src/generators/auth/auth-service/index.ts (1)

50-60: Optimize template creation by consolidating configuration

You're creating a tokensFile template with configurations spread across multiple calls. Consider consolidating the template creation and configurations to improve readability and maintainability.

Apply this diff to consolidate configurations:

 const tokensFile = typescript.createTemplate(
   {
     API_ENDPOINT_URI: { type: 'code-expression' },
   },
   {
     importMappers: [reactApolloSetup],
   },
 );
 tokensFile.addCodeEntries({
   API_ENDPOINT_URI: reactApolloSetup.getApiEndpointExpression(),
 });
packages/react-generators/src/generators/core/react-error/index.ts (2)

46-57: Initialize code blocks with defaults to avoid empty code generation

In the template creation for loggerFile, default values are provided for LOGGER_ACTIONS but not for CONTEXT_ACTIONS:

const loggerFile = typescript.createTemplate(
  {
    CONTEXT_ACTIONS: {
      type: 'code-block',
    },
    LOGGER_ACTIONS: {
      type: 'code-block',
      default: '// no error reporters registered',
    },
  },
  { importMappers: [reactLogger] },
);

Consider adding a default value for CONTEXT_ACTIONS to prevent potential issues with empty code blocks, which can lead to syntax errors in the generated files.

Apply this diff to add a default:

 CONTEXT_ACTIONS: {
   type: 'code-block',
+  default: '// no context actions registered',
 },

69-92: Ensure clean-up of code blocks to prevent code bloat

As addContextAction, addErrorReporter, and addErrorFormatter methods may be called multiple times, ensure that the code blocks in loggerFile and formatterFile do not accumulate redundant or duplicate code. Implement mechanisms to check for duplicates or to clear code blocks when necessary.

packages/fastify-generators/src/generators/core/app-module/index.ts (2)

28-99: Enhance Readability by Refactoring Nested Functions

The run function inside the main task contains several nested functions and variables. To improve readability and maintainability, consider refactoring some of this logic into separate helper functions or utilities.


65-67: Provide More Context in Error Messages

When an unknown field entry is encountered in registerFieldEntry, the error message 'Unknown field entry: ${name}' is thrown. To aid debugging, consider adding more context, such as the expected valid fields.

Example:

- throw new Error(\`Unknown field entry: \${name}\`);
+ throw new Error(\`Unknown field entry: \${name}. Valid fields are: \${validFields.join(', ')}\`);
packages/code-morph/src/morphers/migrate-generator-with-children.morpher.ts (2)

49-50: Provide Detailed Error Message for Multiple Call Expressions

The error thrown when multiple call expressions are found is generic:

throw new Error('Only one call expression allowed');

To improve debugging, include additional information such as the number of call expressions found and their locations.

Example:

- throw new Error('Only one call expression allowed');
+ throw new Error(\`Expected one 'createGeneratorWithTasks' call expression, but found \${callExpressions.length}.\`);

105-110: Simplify the Check for Unused descriptor Parameter

The logic to determine if the descriptor parameter is unused is complex:

const isDescriptorUnused =
  !parameters[0] ||
  (parameters[0] &&
    parameters[0].getText() === 'descriptor' &&
    !createGeneratorMethodBody.includes('descriptor'));

Consider simplifying this condition for better readability.

Example:

- // existing complex condition
+ const isDescriptorUnused = !parameters[0]?.getText().includes('descriptor') || !createGeneratorMethodBody.includes('descriptor');

Ensure that the simplified condition maintains the correct logic.

packages/code-morph/src/scripts/run-morpher.ts (2)

202-208: Improve Error Handling in main Function

In the top-level await main().catch(...) block, the error handling is generic and might suppress important error information.

Consider enhancing the error handling to provide more detailed information:

  • Log the error stack trace for easier debugging.
  • Differentiate between known and unknown errors to handle them appropriately.

Apply this diff to improve error handling:

 await main().catch((err: unknown) => {
   if (err instanceof Error && err.name === 'ExitPromptError') {
     process.exit(1);
   }
-  console.error(err);
+  if (err instanceof Error) {
+    console.error('An unexpected error occurred:', err.message);
+    console.error(err.stack);
+  } else {
+    console.error('An unknown error occurred:', err);
+  }
   process.exit(1);
 });

136-150: Streamline Morpher Option Prompts

When prompting for morpher options, the current implementation sequentially prompts the user, which can be tedious.

Consider using inquirer's prompt method with an array of questions to display all option prompts at once.

-import { checkbox, input, search } from '@inquirer/prompts';
+import inquirer, { checkbox, search } from '@inquirer/prompts';

...

 const promptedOptions: Record<string, string> = {};
-for (const [optionName, option] of Object.entries(morpher.options)) {
-  const prompt = await input({
-    message: `Please enter the value for ${optionName}${
-      option.optional ? ' (optional)' : ''
-    }${option.description ? `: ${option.description}` : ''}`,
-    validate: (value) => {
-      if (!option.optional && !value) return 'This option is required';
-      if (option.validation) {
-        const result = option.validation.safeParse(value);
-        if (!result.success) return result.error.message;
-      }
-      return true;
-    },
-  });
-  promptedOptions[optionName] = prompt;
-}
+const questions = Object.entries(morpher.options).map(([optionName, option]) => ({
+  type: 'input',
+  name: optionName,
+  message: `Please enter the value for ${optionName}${
+    option.optional ? ' (optional)' : ''
+  }${option.description ? `: ${option.description}` : ''}`,
+  validate: (value: string) => {
+    if (!option.optional && !value) return 'This option is required';
+    if (option.validation) {
+      const result = option.validation.safeParse(value);
+      if (!result.success) return result.error.message;
+    }
+    return true;
+  },
+}));
+const answers = await inquirer.prompt(questions);
+Object.assign(promptedOptions, answers);

This approach makes the user experience smoother by presenting all required options in a single prompt session.

packages/core-generators/src/generators/node/prettier/index.ts (1)

173-179: Handle module resolution failures gracefully

When the resolveModuleWithVersion function fails to find the Prettier module, the code falls back to the bundled version of Prettier. Ensure that this fallback is acceptable in all use cases, and consider providing more detailed guidance to the user about installing the correct version of Prettier in their project dependencies.

packages/react-generators/src/generators/admin/admin-crud-queries/index.ts (1)

205-214: Consider merging fields instead of throwing an error

When a duplicate root with a different field set is detected, the code throws an error, which may halt execution. Instead of throwing an error, consider merging the fields or warning the user to enhance robustness and user experience.

Apply this diff to merge fields:

- if (!areFieldsIdentical(existingRoot.fields, root.fields)) {
-   throw new Error(
-     `Root ${root.name ?? 'unnamed'} already exists with different fields`,
-   );
- }
+ if (!areFieldsIdentical(existingRoot.fields, root.fields)) {
+   existingRoot.fields = mergeGraphQLFields([existingRoot.fields, root.fields]);
+ }
packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts (1)

216-623: Consider refactoring the buildTransformer function for readability

The buildTransformer function contains complex logic with deep nesting and multiple responsibilities. Splitting this function into smaller, well-named helper functions can improve readability and maintainability.

packages/code-morph/src/morphers/tests/move-import-reference/simple/bar.ts (1)

1-1: Add documentation to the foo function

The foo function is currently empty. Adding a docstring or comment to explain its intended use can improve code clarity, especially if it's for testing purposes.

packages/code-morph/src/morphers/tests/move-import-reference/simple/bar2.ts (1)

1-1: Add documentation to the foo2 function

The foo2 function is currently empty. Consider adding a comment or docstring to clarify its purpose, which will enhance code readability.

packages/code-morph/src/morphers/tests/move-import-reference/simple/input.ts (1)

1-2: Consider removing @ts-nocheck.

Using @ts-nocheck might mask potential type issues. Consider enabling type checking to ensure type safety in tests.

packages/code-morph/src/utils/fs.ts (1)

3-7: Add JSDoc documentation and specify access type.

The function implementation is clean and follows best practices. Consider these improvements:

  1. Add JSDoc to document the function's purpose and error cases it handles.
  2. Use constants from node:fs to specify the type of access being checked (e.g., F_OK for existence).
+import { constants } from 'node:fs';
 import { access } from 'node:fs/promises';

+/**
+ * Checks if a file exists at the specified path.
+ * @param filePath - The path to check
+ * @returns Promise that resolves to true if the file exists, false if the file doesn't exist or is inaccessible
+ */
 export async function pathExists(filePath: string): Promise<boolean> {
-  return access(filePath)
+  return access(filePath, constants.F_OK)
     .then(() => true)
     .catch(() => false);
 }
packages/code-morph/src/morphers/migrate-generator-with-children.morpher.unit.test.ts (1)

1-4: Add test documentation to describe morpher functionality.

While the test setup is correct, consider adding documentation to describe:

  1. The purpose of this morpher
  2. The scenarios being tested
  3. Expected outcomes
+/**
+ * Tests for migrateGeneratorWithChildrenMorpher
+ *
+ * This morpher transforms generators from using createGeneratorWithChildren
+ * to the new task-based architecture using createGeneratorWithTasks.
+ *
+ * Test scenarios:
+ * - Basic generator migration
+ * - Generators with multiple children
+ * - Error cases
+ */
 import migrateGeneratorWithChildrenMorpher from './migrate-generator-with-children.morpher.js';
 import { runMorpherTests } from './tests/morpher.test-helper.js';

 runMorpherTests(migrateGeneratorWithChildrenMorpher);
packages/code-morph/src/utils/array.ts (1)

1-7: Add documentation and consider error handling strategy.

The implementation is efficient using Promise.all, but consider these improvements:

  1. Add JSDoc documentation:
+/**
+ * Filters an array asynchronously using a predicate function.
+ * @param array - The input array to filter
+ * @param predicate - Async function that returns true for elements to keep
+ * @returns Promise resolving to filtered array
+ * @throws Rejects if any predicate promise rejects
+ */
 export async function asyncFilter<T>(
  1. Consider a more memory-efficient implementation that doesn't store all results:
export async function asyncFilter<T>(
  array: T[],
  predicate: (value: T) => Promise<boolean>,
): Promise<T[]> {
  const filtered: T[] = [];
  for (const item of array) {
    if (await predicate(item)) {
      filtered.push(item);
    }
  }
  return filtered;
}

Note: The current implementation using Promise.all is more performant but uses more memory. The alternative implementation above is more memory-efficient but sequential. Choose based on your use case.

packages/code-morph/src/constants/ts-morph-settings.ts (1)

7-13: Enhance documentation for manipulation settings.

The settings are well-defined, but consider adding more comprehensive documentation:

+/**
+ * Default manipulation settings for ts-morph operations.
+ *
+ * @property indentationText - Uses 2 spaces for indentation
+ * @property quoteKind - Uses single quotes for strings
+ * @property usePrefixAndSuffixTextForRename - Preserves comments during rename
+ * @property useTrailingCommas - Disabled due to ts-morph issue #1603
+ *                               (Array literals lose their trailing comma during manipulation)
+ *
+ * @see {@link https://github.com/dsherret/ts-morph/issues/1603|ts-morph#1603}
+ */
 export const TS_MORPH_MANIPULATION_SETTINGS: Partial<ManipulationSettings> = {
   indentationText: IndentationText.TwoSpaces,
   quoteKind: QuoteKind.Single,
   usePrefixAndSuffixTextForRename: true,
-  // There is an issue with trailing commas (https://github.com/dsherret/ts-morph/issues/1603)
+  // Disabled: Array literals lose their trailing comma during manipulation
+  // See: https://github.com/dsherret/ts-morph/issues/1603
   useTrailingCommas: false,
 };
packages/fastify-generators/src/generators/prisma/prisma-model-unique/index.ts (1)

24-27: Consider extracting field mapping logic

While the implementation is correct, consider extracting the field mapping for better readability:

-  args: [fields.map(({ name }) => name)],
+  const fieldNames = fields.map(({ name }) => name);
+  args: [fieldNames],
packages/fastify-generators/src/generators/prisma/prisma-enum/index.ts (1)

26-30: Consider documenting the empty prismaEnum provider

The empty object returned as prismaEnum provider might need documentation to explain its purpose.

 return {
   getProviders: () => ({
+    // Empty object as this provider is used as a marker for dependency tracking
     prismaEnum: {},
   }),
 };
packages/code-morph/src/morphers/utils/imports.ts (1)

14-29: Add input validation and error handling

While the implementation is solid, consider adding:

  1. Input validation for null/undefined parameters
  2. Error handling for AST manipulation failures
 export function insertImportDeclarationAtTop(
   sourceFile: SourceFile,
   importStructure: OptionalKind<ImportDeclarationStructure>,
 ): void {
+  if (!sourceFile || !importStructure) {
+    throw new Error('Source file and import structure are required');
+  }
+
+  try {
     const statements = sourceFile.getStatementsWithComments();
     const firstNonCommentStatement =
       statements.find((statement) => !Node.isCommentStatement(statement)) ??
       undefined;
     sourceFile.insertImportDeclaration(
       firstNonCommentStatement?.getChildIndex() ?? 0,
       {
         ...importStructure,
         leadingTrivia: '\n',
       },
     );
+  } catch (error) {
+    throw new Error(`Failed to insert import declaration: ${error.message}`);
+  }
 }
packages/code-morph/src/load-morphers.ts (1)

28-30: Enhance error message with file list

When no morphers are found, include the list of files that were attempted to be loaded for better debugging.

 if (morphers.length === 0) {
-  throw new Error(`No morphers found in ${morphersPath}`);
+  throw new Error(
+    `No morphers found in ${morphersPath}. Files found: ${files.join(', ')}`
+  );
 }
packages/react-generators/src/generators/admin/admin-crud-text-display/index.ts (1)

11-14: Consider adding task description

The task structure looks good, but adding a description would improve maintainability.

 const AdminCrudTextDisplayGenerator = createGeneratorWithTasks({
   descriptorSchema,
   getDefaultChildGenerators: () => ({}),
   buildTasks(taskBuilder, { modelField }) {
+    // Task: Adds a text display component for the specified model field
     taskBuilder.addTask({
packages/code-morph/src/utils/find-nearest-ancestor-file.ts (1)

18-19: Replace infinite loop with while loop

Using an infinite loop with a break condition is less readable than a while loop.

-  for (;;) {
+  while (true) {
     const filePath = path.join(currentPath, filename);
     // ... rest of the code ...
     currentPath = parentPath;
   }

Also applies to: 38-39

packages/react-generators/src/generators/auth/auth-pages/index.ts (2)

33-47: Consider splitting task into smaller subtasks

The current implementation uses a single 'main' task. Consider splitting into smaller, focused tasks for better maintainability.

   buildTasks(taskBuilder) {
-    taskBuilder.addTask({
-      name: 'main',
-      dependencies: {},
-      exports: {
-        authPages: authPagesProvider.export(projectScope),
-      },
-      run() {
-        return {
-          getProviders: () => ({
-            authPages: {},
-          }),
-        };
-      },
-    });
+    // Task: Initialize auth pages configuration
+    taskBuilder.addTask({
+      name: 'init',
+      dependencies: {},
+      run() {
+        return {};
+      },
+    });
+
+    // Task: Setup auth pages provider
+    taskBuilder.addTask({
+      name: 'setup-provider',
+      dependencies: {},
+      exports: {
+        authPages: authPagesProvider.export(projectScope),
+      },
+      run() {
+        return {
+          getProviders: () => ({
+            authPages: {},
+          }),
+        };
+      },
+    });

42-44: Document empty provider object

The empty object returned by the provider should be documented to explain its purpose.

         getProviders: () => ({
-          authPages: {},
+          // Empty object as this provider is used as a marker for auth pages setup
+          authPages: {},
         }),
packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-deps/output.ts (1)

47-48: Consider parameterizing the test file path and content.

Hardcoding the test file path and content reduces flexibility and testability.

Consider making these configurable:

-            builder.writeFile('test.txt', 'test');
+            const { testFilePath = 'test.txt', testContent = 'test' } = descriptor;
+            builder.writeFile(testFilePath, testContent);
packages/code-morph/src/morphers/tests/migrate-generator-with-children/simple/output.ts (1)

30-40: Improve type safety of descriptor usage.

The descriptor parameter is used directly without type annotation or validation.

Consider adding type safety:

-  buildTasks(taskBuilder, descriptor) {
+  buildTasks(taskBuilder, descriptor: z.infer<typeof descriptorSchema>) {
packages/fastify-generators/src/generators/core/readme/index.ts (1)

48-53: Add error handling for file operations.

The build function lacks error handling for file operations.

Consider adding try-catch:

-          build: (builder) => {
+          build: async (builder) => {
+            try {
               builder.writeFile('README.md', readmeContent);
+            } catch (error) {
+              throw new Error(`Failed to write README.md: ${error.message}`);
+            }
           },
packages/react-generators/src/generators/admin/admin-crud-password-input/index.ts (1)

38-44: Consider enhancing password validation schema.

The current validation schema (z.string().nullish()) could be strengthened to enforce password requirements.

-                'z.string().nullish()',
+                'z.string().min(8).regex(/[A-Z]/).regex(/[a-z]/).regex(/[0-9]/).regex(/[^A-Za-z0-9]/).nullish()',
packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/index.ts (1)

41-51: Consider adding error handling for file operations.

The build process involves file operations that could fail. Consider adding error handling and logging.

 build: async (builder) => {
+  try {
     await builder.apply(
       typescript.createCopyAction({
         source: 'graceful-shutdown.ts',
         destination: gracefulShutdownPath,
         importMappers: [loggerService, errorHandlerService],
       }),
     );
+  } catch (error) {
+    errorHandlerService.logError('Failed to copy graceful-shutdown.ts', error);
+    throw error;
+  }
 },
packages/react-generators/src/generators/core/react-proxy/index.ts (1)

40-48: Consider using a more robust state management approach.

The current implementation uses a local variable for WebSocket state. Consider using a more robust state management approach.

-let enableWebsocket = false;
+class ProxyState {
+  private enableWebsocket = false;
+  
+  setWebSocketEnabled(enabled: boolean) {
+    this.enableWebsocket = enabled;
+  }
+  
+  isWebSocketEnabled() {
+    return this.enableWebsocket;
+  }
+}
+const proxyState = new ProxyState();

 return {
   getProviders: () => ({
     reactProxy: {
       enableWebSocket: () => {
-        enableWebsocket = true;
+        proxyState.setWebSocketEnabled(true);
       },
     },
   }),
plugins/baseplate-plugin-storage/src/generators/react/admin-crud-file-input/index.ts (1)

39-44: Consider explicitly listing GraphQL fields instead of using spread operator.

Using the spread operator (...FileInput) makes the schema less explicit. Consider listing the fields explicitly for better documentation and type safety.

 graphQLFields: [
   {
     name: modelRelation,
-    fields: [{ type: 'spread', on: 'FileInput' }],
+    fields: [
+      { name: 'id', type: 'string' },
+      { name: 'name', type: 'string' },
+      { name: 'size', type: 'number' },
+      { name: 'mimeType', type: 'string' },
+      { name: 'url', type: 'string' },
+    ],
   },
 ],
packages/react-generators/src/generators/admin/admin-crud-text-input/index.ts (1)

29-57: Consider enhancing error handling for input validation

While the task implementation is correct, consider adding validation for the input type compatibility with the validation rules, especially for date/dateTime inputs.

 run({ adminCrudInputContainer, reactComponents }) {
   const inputType = INPUT_TYPE_MAP[type];
+  // Validate that the validation rules are compatible with the input type
+  if (type === 'date' || type === 'dateTime') {
+    // Add validation compatibility check
+  }
   adminCrudInputContainer.addInput({
packages/react-generators/src/generators/admin/admin-home/index.ts (1)

54-67: Consider adding error handling for build failures

The build process should include error handling for file system operations.

 build: async (builder) => {
+  try {
     await builder.apply(
       typescript.createCopyAction({
         source: 'Home.page.tsx',
         destination: pagePath,
         importMappers: [authHooks, reactComponents],
       }),
     );
+  } catch (error) {
+    throw new Error(`Failed to build Home page: ${error.message}`);
+  }
 },
packages/fastify-generators/src/generators/auth/password-hasher-service/index.ts (1)

56-61: Consider adding type checking for imported functions

The allowedImports should be type-checked against the actual exports of the service.

 getImportMap: () => ({
   '%password-hasher-service': {
     path: fileImport,
     allowedImports: ['createPasswordHash', 'verifyPasswordHash'],
+    // TODO: Add type checking to ensure these functions exist in the service
   },
 }),
packages/react-generators/src/generators/auth/auth-layout/index.ts (1)

60-62: Consider making layout styles configurable

The hardcoded Tailwind classes in the layout component could be made configurable through the descriptor schema.

 const descriptorSchema = z.object({
   name: z.string().min(1),
+  styles: z.object({
+    container: z.string().default('min-h-full flex items-center justify-center bg-slate-100'),
+  }).default({}),
 });
packages/react-generators/src/generators/admin/admin-crud-enum-input/index.ts (1)

Line range hint 33-57: Consider extracting template generation to a separate function.

The template generation logic is complex and could benefit from being extracted into a separate function for better readability and maintainability.

+ function createSelectInputTemplate(label: string, modelField: string, options: Array<{ label: string, value: string }>) {
+   return TypescriptCodeUtils.createExpression(
+     `<SelectInput.LabelledController
+       label="${label}"
+       control={control}
+       name="${modelField}"
+       options={${modelField}Options}
+     />`,
+     'import { SelectInput } from "%react-components"',
+     {
+       importMappers: [reactComponents],
+       headerBlocks: [
+         TypescriptCodeUtils.createBlock(
+           `const ${modelField}Options = [
+             ${options
+               .map(
+                 (option) =>
+                   `{ label: ${quot(option.label)}, value: ${quot(
+                     option.value,
+                   )} }`,
+               )
+               .join(',\n')}
+           ];`,
+         ),
+       ],
+     },
+   );
+ }

  adminCrudInputContainer.addInput({
-   content: TypescriptCodeUtils.createExpression(...),
+   content: createSelectInputTemplate(label, modelField, options),
    ...
  });
packages/fastify-generators/src/generators/prisma/prisma-field/index.ts (1)

54-87: Consider enhancing error messages for enum validation

While the enum validation logic is correct, the error messages could be more descriptive to help developers understand and fix issues faster.

Consider updating the error messages:

-          throw new Error(`Enum type required`);
+          throw new Error(`Enum type is required when type is set to 'enum'`);

-          throw new Error(`Enum type can only be used with type 'enum'`);
+          throw new Error(`Enum type '${enumType}' can only be used when type is set to 'enum', but got type '${type}'`);
packages/react-generators/src/generators/auth0/auth0-callback/index.ts (1)

30-35: Consider using path utilities for file paths

Direct string concatenation for file paths could cause issues across different platforms.

Consider using path utilities:

-          `${reactRoutes.getDirectoryBase()}/auth0-callback.page.tsx`,
+          path.join(reactRoutes.getDirectoryBase(), 'auth0-callback.page.tsx'),

-          `${reactRoutes.getDirectoryBase()}/signup.page.tsx`,
+          path.join(reactRoutes.getDirectoryBase(), 'signup.page.tsx'),
packages/core-generators/src/generators/docker/docker-compose/index.ts (1)

71-82: Consider using template literals more effectively

The current string template usage with trim() could be simplified.

Consider this cleaner approach:

-        const services = `
-services:
-${serviceEntries.join('\n')}`.trim();
+        const services = `services:\n${serviceEntries.join('\n')}`;

-        const volumes = `
-volumes:
-${volumeEntries.join('\n')}`.trim();
+        const volumes = `volumes:\n${volumeEntries.join('\n')}`;
packages/react-generators/src/generators/core/react-app/index.ts (1)

50-51: Consider adding validation for renderRoot.

The default value for renderRoot could benefit from additional validation to ensure it's a valid React component.

-        let renderRoot: TypescriptCodeExpression =
-          TypescriptCodeUtils.createExpression('<div />');
+        let renderRoot: TypescriptCodeExpression =
+          TypescriptCodeUtils.createExpression('<div data-testid="app-root" />');
+
+        const validateRenderRoot = (root: TypescriptCodeExpression) => {
+          if (!root.toString().trim()) {
+            throw new Error('Invalid render root: expression cannot be empty');
+          }
+        };
+        validateRenderRoot(renderRoot);
packages/react-generators/src/generators/apollo/apollo-error-link/index.ts (1)

Line range hint 17-92: Consider enhancing error reporting with additional context.

The error handling implementation is thorough, covering both GraphQL and network errors. However, consider including additional context in the error reports:

  • Request payload (sanitized)
  • Operation variables (sanitized)
  • Stack trace for network errors
 if (graphQLErrors?.length) {
   graphQLErrors.forEach((error) => {
     const { message, path } = error;
     logger.error(
-      `[GraphQL Error] Message: ${message}, Path: ${
+      `[GraphQL Error] Message: ${message}, Operation: ${
+        operation.operationName ?? 'Anonymous'
+      }, Path: ${
         path?.join(',') ?? ''
-      }, Operation: ${operation.operationName ?? 'Anonymous'}`
+      }, Variables: ${
+        JSON.stringify(operation.variables, null, 2)
+      }`
     );
   });
packages/react-generators/src/generators/admin/admin-crud-foreign-input/index.ts (1)

81-88: Consider enhancing validation for foreign key relationships.

While the UUID validation is correct, consider adding additional validation rules for foreign key relationships:

  • Existence validation
  • Referential integrity checks
  • Cascade behavior
 validation: [
   {
     key: localField,
     expression: TypescriptCodeUtils.createExpression(
-      `z.string().uuid()${isOptional ? '.nullish()' : ''}`,
+      `z.string().uuid()${isOptional ? '.nullish()' : ''}.refine(
+        async (id) => {
+          if (!id) return true;
+          const exists = await checkForeignKeyExists(id, '${foreignModelName}');
+          return exists;
+        },
+        { message: 'Referenced record does not exist' }
+      )`,
     ),
   },
 ],
packages/code-morph/src/morphers/tests/morpher.test-helper.ts (1)

12-32: Consider enhancing file system utilities with additional error handling.

The file system utilities are well-implemented but could benefit from additional error handling:

  • Directory existence checks
  • File permission checks
  • Symlink handling
 const readFileWithTsExtension = (
   directory: string,
   baseFileName: string,
 ): string | undefined => {
+  if (!fs.existsSync(directory)) {
+    throw new Error(`Directory does not exist: ${directory}`);
+  }
   const fileName = getFileWithTsExtension(directory, baseFileName);
   if (!fileName) return undefined;
   const filePath = path.join(directory, fileName);
+  try {
+    const stats = fs.statSync(filePath);
+    if (stats.isSymbolicLink()) {
+      const realPath = fs.realpathSync(filePath);
+      return fs.readFileSync(realPath, 'utf8');
+    }
     return fs.readFileSync(filePath, 'utf8');
+  } catch (error) {
+    throw new Error(`Failed to read file ${filePath}: ${error.message}`);
+  }
 };
packages/react-generators/src/generators/core/react-config/index.ts (1)

39-147: Consider extracting configuration validation logic.

The task-based implementation looks good, but the configuration handling could be improved:

  1. The configuration validation logic (lines 57-64) could be extracted into a separate function for better maintainability.
  2. The environment variable handling (lines 137-143) could benefit from validation to ensure no sensitive data is accidentally exposed.

Consider extracting the validation logic:

+const createEnvironmentValidator = () => 
+  TypescriptCodeUtils.createExpression(
+    `z.enum(['development', 'test', 'staging', 'production'])`,
+    "import { z } from 'zod'",
+  );

 const configEntryMap = createNonOverwriteableMap<Record<string, ConfigEntry>>(
   {
     VITE_ENVIRONMENT: {
       comment: 'Environment the app is running in',
-      validator: TypescriptCodeUtils.createExpression(
-        `z.enum(['development', 'test', 'staging', 'production'])`,
-        "import { z } from 'zod'",
-      ),
+      validator: createEnvironmentValidator(),
       devValue: 'development',
     },
   },
   { name: 'react-config-entries' },
 );
packages/react-generators/src/generators/core/react-routes/index.ts (1)

27-129: Consider splitting route registration logic.

The task-based implementation looks good, but the route handling could be improved:

  1. The route registration logic for passthrough and non-passthrough routes (lines 70-125) could be split into separate methods for better maintainability.
  2. The layout registration (line 85) could benefit from additional validation.

Consider extracting the route registration logic:

+const registerPassthroughRoutes = (
+  routes: ReactRoute[],
+  layouts: ReactRouteLayout[],
+  pathName: string,
+  layoutKey?: string,
+) => {
+  const renderedRoutes = renderRoutes(routes, layouts);
+  reactRoutes.registerRoute({
+    path: pathName,
+    layoutKey,
+    children: renderedRoutes,
+  });
+  for (const route of routes)
+    reactRoutes.registerRoute({
+      ...route,
+      path: route.path && `${reactRoutes.getRoutePrefix()}/${pathName}/${route.path}`,
+    });
+  for (const layout of layouts) reactRoutes.registerLayout(layout);
+};

 build: async (builder) => {
   if (isPassthrough) {
-    const renderedRoutes = renderRoutes(routes, layouts);
-    reactRoutes.registerRoute({
-      path: pathName,
-      layoutKey,
-      children: renderedRoutes,
-    });
-    for (const route of routes)
-      reactRoutes.registerRoute({
-        ...route,
-        path: route.path && `${reactRoutes.getRoutePrefix()}/${pathName}/${route.path}`,
-      });
-    for (const layout of layouts) reactRoutes.registerLayout(layout);
+    registerPassthroughRoutes(routes, layouts, pathName, layoutKey);
   } else {
     // ... rest of the code
   }
 }
packages/fastify-generators/src/generators/prisma/prisma-crud-create/index.ts (1)

132-191: Consider extracting task configuration to a separate function.

The task configuration is quite large and contains complex logic. Consider extracting it to a separate function for better maintainability.

+function buildMainTask(descriptor: z.infer<typeof descriptorSchema>) {
+  return {
+    name: 'main',
+    dependencies: {
+      prismaOutput: prismaOutputProvider,
+      serviceFile: serviceFileProvider.dependency(),
+      crudPrismaService: prismaCrudServiceProvider,
+      serviceContext: serviceContextProvider,
+      prismaUtils: prismaUtilsProvider,
+    },
+    run: ({
+      prismaOutput,
+      serviceFile,
+      crudPrismaService,
+      serviceContext,
+      prismaUtils,
+    }) => {
+      // ... existing task implementation
+    },
+  };
+}

 const PrismaCrudCreateGenerator = createGeneratorWithTasks({
   descriptorSchema,
   getDefaultChildGenerators: () => ({}),
   buildTasks(taskBuilder, descriptor) {
-    taskBuilder.addTask({
-      name: 'main',
-      // ... existing task configuration
-    });
+    taskBuilder.addTask(buildMainTask(descriptor));
   },
 });
packages/react-generators/src/generators/core/react-logger/index.ts (1)

50-75: Consider enhancing error handling in file operations.

While the implementation is solid, consider adding error handling for file operations in the build method.

 build: async (builder) => {
   builder.setBaseDirectory(react.getSrcFolder());
+  try {
     await builder.apply(
       typescript.createCopyAction({
         source: 'logger.ts',
         destination: 'services/logger.ts',
       }),
     );
+  } catch (error) {
+    throw new Error(`Failed to copy logger.ts: ${error.message}`);
+  }
 },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 9f6667e and 8d85e1f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (116)
  • .vscode/generator.json.code-snippets (0 hunks)
  • packages/code-morph/eslint.config.js (1 hunks)
  • packages/code-morph/lib/types.ts (0 hunks)
  • packages/code-morph/lib/utils/find-nearest-tsconfig.ts (0 hunks)
  • packages/code-morph/package.json (1 hunks)
  • packages/code-morph/scripts/run-morpher.ts (0 hunks)
  • packages/code-morph/src/constants/ts-morph-settings.ts (1 hunks)
  • packages/code-morph/src/index.ts (1 hunks)
  • packages/code-morph/src/load-morphers.ts (1 hunks)
  • packages/code-morph/src/morphers/migrate-generator-with-children.morpher.ts (1 hunks)
  • packages/code-morph/src/morphers/migrate-generator-with-children.morpher.unit.test.ts (1 hunks)
  • packages/code-morph/src/morphers/move-import-reference.morpher.ts (4 hunks)
  • packages/code-morph/src/morphers/move-import-reference.morpher.unit.test.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-deps/input.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-deps/output.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-descriptor/input.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-descriptor/output.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/simple/input.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/migrate-generator-with-children/simple/output.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/morpher.test-helper.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/bar.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/bar2.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/input.ts (1 hunks)
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/options.json (1 hunks)
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/output.ts (1 hunks)
  • packages/code-morph/src/morphers/utils/imports.ts (1 hunks)
  • packages/code-morph/src/runner.ts (3 hunks)
  • packages/code-morph/src/scripts/run-morpher.ts (1 hunks)
  • packages/code-morph/src/types.ts (1 hunks)
  • packages/code-morph/src/utils/array.ts (1 hunks)
  • packages/code-morph/src/utils/find-nearest-ancestor-file.ts (1 hunks)
  • packages/code-morph/src/utils/find-workspace-projects.ts (1 hunks)
  • packages/code-morph/src/utils/fs.ts (1 hunks)
  • packages/code-morph/transforms/migrate-create-generator-with-children.ts (0 hunks)
  • packages/code-morph/tsconfig.json (1 hunks)
  • packages/code-morph/vitest.config.ts (1 hunks)
  • packages/core-generators/package.json (1 hunks)
  • packages/core-generators/src/generators/docker/docker-compose/index.ts (2 hunks)
  • packages/core-generators/src/generators/node/eslint/index.ts (2 hunks)
  • packages/core-generators/src/generators/node/node-git-ignore/index.ts (2 hunks)
  • packages/core-generators/src/generators/node/prettier/index.ts (2 hunks)
  • packages/core-generators/src/generators/node/ts-utils/index.ts (2 hunks)
  • packages/core-generators/src/generators/node/vitest/index.ts (2 hunks)
  • packages/create-project/package.json (1 hunks)
  • packages/create-project/src/create-baseplate-project.ts (1 hunks)
  • packages/create-project/src/npm.service.ts (1 hunks)
  • packages/create-project/src/project-creator.ts (1 hunks)
  • packages/fastify-generators/package.json (1 hunks)
  • packages/fastify-generators/src/generators/auth/auth-plugin/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/auth/auth-roles/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/auth/password-hasher-service/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/auth/prisma-password-transformer/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/app-module/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/fastify-cookie-context/index.ts (3 hunks)
  • packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/fastify-health-check/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/fastify-server/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/logger-service/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/readme/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-crud-create/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-crud-delete/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-crud-update/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-enum/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-field/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-model-id/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-model-index/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-model-unique/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-relation-field/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-timestamp-fields/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/prisma-utils/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/stripe/fastify-stripe/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/vitest/fastify-vitest/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/vitest/prisma-vitest/index.ts (3 hunks)
  • packages/react-generators/src/generators/admin/admin-components/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-enum-input/index.ts (3 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-foreign-input/index.ts (3 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-list/index.ts (3 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-password-input/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-queries/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-section/index.ts (3 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-text-display/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-text-input/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-home/index.ts (2 hunks)
  • packages/react-generators/src/generators/admin/admin-layout/index.ts (2 hunks)
  • packages/react-generators/src/generators/apollo/apollo-error-link/index.ts (3 hunks)
  • packages/react-generators/src/generators/apollo/apollo-error/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-apollo/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-components/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-hooks/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-layout/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-login-page/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth/auth-pages/index.ts (3 hunks)
  • packages/react-generators/src/generators/auth/auth-service/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth0/auth0-apollo/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth0/auth0-callback/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth0/auth0-components/index.ts (1 hunks)
  • packages/react-generators/src/generators/auth0/auth0-hooks/index.ts (2 hunks)
  • packages/react-generators/src/generators/auth0/react-auth0/index.ts (3 hunks)
  • packages/react-generators/src/generators/core/react-app/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-components/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-config/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-error/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-logger/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-not-found-handler/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-proxy/index.ts (3 hunks)
  • packages/react-generators/src/generators/core/react-router/index.ts (3 hunks)
  • packages/react-generators/src/generators/core/react-routes/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-tailwind/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-typescript/index.ts (1 hunks)
  • packages/sync/src/utils/create-generator-with-children.ts (0 hunks)
  • packages/sync/src/utils/create-generator-with-tasks.ts (1 hunks)
  • packages/sync/src/utils/index.ts (0 hunks)
  • plugins/baseplate-plugin-storage/src/generators/fastify/prisma-file-transformer/index.ts (2 hunks)
  • plugins/baseplate-plugin-storage/src/generators/react/admin-crud-file-input/index.ts (2 hunks)
  • plugins/baseplate-plugin-storage/src/generators/react/upload-components/index.ts (2 hunks)
💤 Files with no reviewable changes (7)
  • .vscode/generator.json.code-snippets
  • packages/sync/src/utils/index.ts
  • packages/code-morph/lib/utils/find-nearest-tsconfig.ts
  • packages/code-morph/lib/types.ts
  • packages/sync/src/utils/create-generator-with-children.ts
  • packages/code-morph/scripts/run-morpher.ts
  • packages/code-morph/transforms/migrate-create-generator-with-children.ts
✅ Files skipped from review due to trivial changes (5)
  • packages/code-morph/vitest.config.ts
  • packages/create-project/src/project-creator.ts
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/output.ts
  • packages/create-project/src/npm.service.ts
  • packages/code-morph/src/morphers/tests/move-import-reference/simple/options.json
🔇 Additional comments (154)
packages/fastify-generators/src/generators/vitest/fastify-vitest/index.ts (3)

8-8: LGTM! Import change aligns with the architectural shift.

The replacement of createGeneratorWithChildren with createGeneratorWithTasks correctly implements the transition to task-based generators.


38-45: LGTM! Vitest configuration looks good.

The setup block for dotenv configuration is properly implemented using TypeScript code utils.


47-51: LGTM! Test script configuration is well-structured.

The addition of both general test and unit-specific test scripts with appropriate environment variables is well implemented.

packages/code-morph/src/types.ts (1)

1-8: Well-structured type definition for transform functions!

The TransformFunction type is well-designed with proper generic constraints and clear parameter types.

packages/core-generators/src/generators/node/ts-utils/index.ts (2)

2-2: LGTM! Import changes align with architectural shift.

The change from createGeneratorWithChildren to createGeneratorWithTasks aligns with the PR's objective of transitioning to a task-based generator model.


56-59: LGTM! Generator structure follows new architecture.

The transition to createGeneratorWithTasks maintains the necessary configuration while adopting the new task-based approach.

packages/fastify-generators/src/generators/core/fastify-health-check/index.ts (2)

10-10: LGTM! Import change aligns with architectural shift

The transition to createGeneratorWithTasks aligns with the PR's objective of moving to a task-based architecture.


28-97: Overall implementation looks solid

The transition to the task-based architecture is well-implemented. The code is structured logically, and the health check functionality is properly maintained through the refactoring. The suggested improvements are minor and can be addressed in follow-up changes.

packages/react-generators/src/generators/auth0/auth0-components/index.ts (3)

6-6: LGTM! Import changes align with architectural shift

The transition to importing createGeneratorWithTasks from '@halfdomelabs/sync' aligns well with the PR's objective of moving to a task-based generator model.


24-26: LGTM! Well-structured exports configuration

The exports configuration clearly defines the generator's interface through the authComponents provider, maintaining good encapsulation.


14-16: Verify if empty getDefaultChildGenerators is intentional

While the transition to createGeneratorWithTasks looks good, please confirm if returning an empty object from getDefaultChildGenerators is intentional, as this generator might need to integrate with other generators in the future.

Let's check if other generators in the codebase follow similar patterns:

✅ Verification successful

Empty getDefaultChildGenerators is a verified pattern

The empty object return from getDefaultChildGenerators is consistent with the established pattern across all generators in the codebase. This appears to be an intentional design choice where child generators are not required for this type of component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other generators using createGeneratorWithTasks
# to verify the pattern of getDefaultChildGenerators usage

ast-grep --pattern 'createGeneratorWithTasks({
  $$$
  getDefaultChildGenerators: $_,
  $$$
})'

Length of output: 72760

packages/fastify-generators/src/generators/auth/prisma-password-transformer/index.ts (1)

13-16: Verify removal of child generators

The transition to createGeneratorWithTasks aligns with the PR objectives. However, let's verify that no child generators were unintentionally removed during this refactor.

✅ Verification successful

Empty child generators configuration is correct

The empty getDefaultChildGenerators configuration is valid as this generator is not used as a child generator anywhere in the codebase, and it doesn't require any child generators for its functionality. This aligns with the transition to task-based architecture.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any references to this generator being used as a child in other generators
rg -l "PrismaPasswordTransformerGenerator" packages/ | \
  xargs rg "getDefaultChildGenerators.*PrismaPasswordTransformerGenerator"

Length of output: 127


Script:

#!/bin/bash
# Step 1: Find all files containing references to PrismaPasswordTransformerGenerator
echo "=== Files referencing PrismaPasswordTransformerGenerator ==="
rg -l "PrismaPasswordTransformerGenerator" packages/

# Step 2: For each file found, show the context of how this generator is used
echo -e "\n=== Usage context of PrismaPasswordTransformerGenerator ==="
rg -B 3 -A 3 "PrismaPasswordTransformerGenerator" packages/

Length of output: 1664

packages/react-generators/src/generators/core/react-tailwind/index.ts (4)

9-9: LGTM! Successful transition to task-based architecture.

The change from createGeneratorWithChildren to createGeneratorWithTasks aligns well with the PR's objective of enabling code morphs across multiple packages.

Also applies to: 30-30


33-44: Well-structured task definition with clear dependencies.

The task structure effectively organizes dependencies and exports, maintaining the same functionality while adapting to the new task-based approach.


89-98: LGTM! Robust file operations implementation.

The template handling is well-implemented with proper path joining and data injection for global styles.


50-55: Verify compatibility of package versions.

While pinning versions is good practice, please verify that these versions are stable and compatible with each other:

Run this script to check the latest stable versions and their compatibility:

✅ Verification successful

Package versions are compatible and stable

The specified versions are recent, stable, and satisfy all peer dependency requirements. While there are newer patch versions available (tailwindcss 3.4.17 and @tailwindcss/forms 0.5.10), the current versions are sufficiently up-to-date and compatible with each other.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check latest versions and compatibility of Tailwind-related packages

# Check latest versions on npm
for pkg in tailwindcss autoprefixer @tailwindcss/forms
do
  echo "Checking $pkg..."
  curl -s "https://registry.npmjs.org/$pkg" | jq -r '.["dist-tags"].latest'
done

# Check for any reported peer dependency issues
for pkg in tailwindcss autoprefixer @tailwindcss/forms
do
  echo "Checking peer dependencies for $pkg..."
  curl -s "https://registry.npmjs.org/$pkg" | jq -r '.versions | to_entries | .[-1].value.peerDependencies'
done

Length of output: 1589

packages/react-generators/src/generators/apollo/apollo-error/index.ts (3)

9-9: LGTM! Import changes align with architectural shift.

The transition to importing createGeneratorWithTasks aligns with the PR's objective of refactoring generators to use a task-based approach.


35-59: LGTM! Clean implementation of task-based logic.

The implementation successfully:

  • Preserves the core functionality of Apollo error handling
  • Maintains proper path construction
  • Utilizes the typescript provider effectively

23-26: Verify if default child generators are still needed.

Given the transition to a task-based approach, please verify if getDefaultChildGenerators is still required or if it can be removed.

✅ Verification successful

Empty child generators configuration is correct

The empty getDefaultChildGenerators configuration is intentional and correct for this generator. It explicitly indicates that this generator doesn't need any child generators, which is a valid pattern within the task-based generator framework.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of child generators in the codebase
rg -l "getDefaultChildGenerators" --type ts

Length of output: 8993


Script:

#!/bin/bash
# Check the implementation in create-generator-with-tasks
cat packages/sync/src/utils/create-generator-with-tasks.ts

Length of output: 11236

packages/fastify-generators/src/generators/prisma/prisma-model-index/index.ts (2)

Line range hint 1-9: LGTM! Well-structured schema definition

The transition to createGeneratorWithTasks aligns with the PR objectives, and the schema validation using zod ensures type safety for the fields array.


16-18: Verify prismaModel provider availability

Let's verify that the prismaModel provider is consistently available across different contexts where this generator might be used.

✅ Verification successful

Provider usage verified and consistent

The prismaModel provider is properly implemented in the prisma-model module and consistently imported across all prisma generators. Its usage in this context is correct and follows the established pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other uses of prismaModelProvider to ensure consistent availability
rg -l "prismaModelProvider" --type ts

# Check for any conditional imports or provider creation
ast-grep --pattern 'import { prismaModelProvider } from $path'

Length of output: 642


Script:

#!/bin/bash
# Check how prismaModelProvider is imported in these files
rg "import.*prismaModelProvider" --type ts

# Find the provider implementation
ast-grep --pattern 'export const prismaModelProvider = $_'

Length of output: 1201

packages/react-generators/src/generators/auth0/auth0-apollo/index.ts (3)

6-6: LGTM! Import aligns with the new task-based architecture.

The transition from createGeneratorWithChildren to createGeneratorWithTasks is consistent with the PR's objective of refactoring the code-morph functionality.


25-33: Clean task organization with clear dependencies and exports.

The task structure clearly defines its dependencies and exports, making the component's requirements and capabilities explicit.


34-48: Verify Auth0 hook dependency handling.

The Auth0 integration looks good, but there's a potential improvement opportunity:

Let's verify that the Auth0 hook dependency is consistently handled across the codebase:

✅ Verification successful

Auth0 hook dependency handling is consistent

The Auth0 integration follows a consistent pattern across the codebase, with proper modularization and separation of concerns. The current implementation in the Apollo integration correctly aligns with the established patterns in other Auth0-related modules.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other Auth0 hook usages to ensure consistent patterns
rg -t typescript "useAuth0.*getAccessTokenSilently" 

# Check for any direct Auth0 imports that might need similar treatment
rg -t typescript "@auth0/auth0-react"

Length of output: 161


Script:

#!/bin/bash
# Search for Auth0 hook usage patterns with context
rg "useAuth0.*getAccessTokenSilently" -l --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' --type=ts --type=js

# Search for Auth0 imports with context
rg "from ['|\"]@auth0/auth0-react['|\"]" -l --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' --type=ts --type=js

# Search for Auth0 configuration patterns
rg "Auth0Provider|auth0\." -l --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' --type=ts --type=js

Length of output: 1122

packages/fastify-generators/src/generators/prisma/prisma-timestamp-fields/index.ts (1)

Line range hint 1-50: Refactored generator aligns with task-based architecture

The transition from createGeneratorWithChildren to createGeneratorWithTasks is well-executed. The buildTasks method effectively encapsulates the generator logic, enhancing modularity and maintainability. The use of taskBuilder.addTask and the organization of field-adding logic within the run method adhere to the new architectural patterns.

packages/react-generators/src/generators/admin/admin-layout/index.ts (2)

46-130: Successful refactoring to use createGeneratorWithTasks

The transition from createGeneratorWithChildren to createGeneratorWithTasks is implemented effectively. The buildTasks method is well-defined, tasks are properly added with correct dependencies and exports, and the internal logic within the run method preserves the intended functionality. This refactor enhances the modularity and maintainability of the generator.


105-105: Verify the resolution of %auth-components import path

In the import statement import {RequireAuth} from '%auth-components';, ensure that the placeholder %auth-components is correctly resolved by the importMappers. Incorrect resolution may lead to module not found errors at runtime. Verify that the authComponents provider handles this mapping appropriately.

packages/react-generators/src/generators/auth0/auth0-hooks/index.ts (4)

6-6: LGTM! Import changes align with architectural shift.

The transition from createGeneratorWithChildren to createGeneratorWithTasks in the imports reflects the architectural changes described in the PR objectives.


18-31: Well-structured task definition with clear dependencies.

The new task-based structure improves modularity and maintainability by explicitly defining dependencies and exports.


35-45: LGTM! Well-organized hook path definitions.

The hook paths are consistently defined using the makeImportAndFilePath utility, following a clear organizational structure in the hooks folder.


20-20: Verify the removal of child generators.

The getDefaultChildGenerators returns an empty object. Please verify that no child generators are needed in this context after the architectural change.

✅ Verification successful

Empty child generators configuration is correct.

The auth0-hooks generator follows the same pattern as other auth0-related generators, where each handles a specific, focused responsibility without needing to compose child generators. This is consistent with the architectural design across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any references to child generators in the codebase
rg -l "getDefaultChildGenerators" | xargs -I {} rg -A 5 "getDefaultChildGenerators.*{.*}" {}

Length of output: 17420


Script:

#!/bin/bash
# Search for getDefaultChildGenerators implementations
rg "getDefaultChildGenerators.*=.*" -A 3

# Look for auth0 related generator files
fd "auth0.*\.(ts|js)" --type f

# Check for any generator dependencies or relationships
rg "generators.*auth0" -A 3

Length of output: 51845

plugins/baseplate-plugin-storage/src/generators/react/upload-components/index.ts (6)

35-46: Well-structured task configuration with clear dependency injection.

The task configuration follows best practices with explicit dependencies and scoped exports.


54-56: Clean component registration.

The FileInput component registration is concise and follows the expected pattern.


58-71: Well-structured import mapping with explicit allowed imports.

The import mapping follows best practices by:

  • Using utility functions for path generation
  • Explicitly defining allowed imports
  • Maintaining a clear organization

76-115: Comprehensive build configuration with proper file handling.

The build configuration effectively manages:

  • Import map provision
  • Component, GQL, and hook file copying
  • Variable replacements

31-34: Verify the completeness of the migration to tasks.

The empty getDefaultChildGenerators suggests this generator might still be in transition. Consider whether any child generators need to be migrated to tasks.

✅ Verification successful

Migration to tasks is correctly implemented

The empty getDefaultChildGenerators is intentional as this generator is not used as a child by other generators and doesn't require any child generators itself. The migration to tasks is complete.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining child generator references
rg -l "getDefaultChildGenerators|createGeneratorWithChildren" --type ts

Length of output: 9368


Script:

#!/bin/bash
# Search for references to UploadComponentsGenerator in the plugin
rg -l "UploadComponentsGenerator" plugins/baseplate-plugin-storage/

# Check if any of the plugin's generators are using this as a child
ast-grep --pattern 'getDefaultChildGenerators = () => ({
  $$$
  uploadComponents: $$$
  $$$
})'

Length of output: 247


73-74: Verify GQL file path construction.

Ensure that getComponentsFolder() always returns a valid path for GQL file registration.

✅ Verification successful

GQL file path construction is reliable

The getComponentsFolder() method is implemented to consistently return ${srcFolder}/components, and this pattern is successfully used across multiple components in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for getComponentsFolder implementations and usages
ast-grep --pattern 'getComponentsFolder() {
  $$$
}'

Length of output: 54


Script:

#!/bin/bash
# Search for class containing components folder related methods
ast-grep --pattern 'class $_ {
  $$$
  componentsFolder
  $$$
}'

# Backup text-based search
rg -i "getComponentsFolder" -A 3
rg -i "componentsFolder" -A 3

# Check the actual file structure
fd -t f "FileInput" --exec ls -l

Length of output: 9316

packages/react-generators/src/generators/auth0/react-auth0/index.ts (4)

7-7: LGTM! Import changes align with the architectural shift.

The transition from createGeneratorWithChildren to createGeneratorWithTasks reflects the intended architectural change.


28-37: LGTM! Well-structured task implementation.

The task structure is clean with clear dependencies and exports. The use of providers follows the project's patterns.


24-27: Verify if empty child generators are intentional.

While the transition to task-based approach looks good, please confirm if having empty default child generators is intentional, given that this is part of a larger architectural change.

✅ Verification successful

Empty child generators are intentionally used across all auth0 generators

The empty default child generators are consistent with the implementation pattern used across all five auth0 generators (react-auth0, auth0-apollo, auth0-callback, auth0-components, and auth0-hooks). Each generator is designed to be self-contained within the new task-based architecture.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other auth0 generators follow the same pattern
rg -t typescript "getDefaultChildGenerators.*=.*\(\).*=>.*{}" packages/react-generators/src/generators/auth0/

Length of output: 277


Script:

#!/bin/bash
# First, find all generator files in auth0 directory
echo "=== Auth0 Generator Files ==="
fd "index.ts" packages/react-generators/src/generators/auth0/

# Then search for getDefaultChildGenerators implementations
echo -e "\n=== Default Child Generators Patterns ==="
rg "getDefaultChildGenerators.*=.*\(" packages/react-generators/src/generators/auth0/ -A 2

# Look for related generator imports or dependencies
echo -e "\n=== Related Generator References ==="
rg "import.*Generator" packages/react-generators/src/generators/auth0/ -A 1

Length of output: 3119


43-59: Ensure secure handling of Auth0 configuration.

While the configuration structure is good, please ensure:

  1. Dev values are clearly documented as placeholders
  2. Production deployment process includes proper secret management
  3. Validation helps prevent security misconfigurations
✅ Verification successful

Auth0 configuration implementation is secure and well-structured

The current implementation already follows security best practices:

  • All Auth0 configurations have proper validation using Zod
  • Placeholder values are clearly marked in dev environment
  • Auth0Provider setup includes all necessary security parameters including audience and redirect configuration
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for documentation about Auth0 configuration
rg -l "auth0.*configuration|configure.*auth0" -g "*.md" .

Length of output: 59


Script:

#!/bin/bash
# Search for any Auth0-related documentation
rg -l "auth0" -g "*.md" .

# Look for Auth0 configuration in template files
fd -e env.template -e env.example -X cat

# Check for Auth0 implementation details
ast-grep --pattern 'VITE_AUTH0_'

Length of output: 145


Script:

#!/bin/bash
# Check changelog content for Auth0 information
cat packages/project-builder-lib/CHANGELOG.md

# Look for Auth0 configuration usage
rg "VITE_AUTH0_" -A 3 -B 3

# Search for Auth0 setup or configuration files
fd -e ts -e js -e tsx -e jsx auth0

Length of output: 9533

packages/fastify-generators/src/generators/core/logger-service/index.ts (1)

74-74: Verify compatibility and latest versions of 'pino' and 'pino-pretty'

Ensure that the specified versions of pino (9.5.0) and pino-pretty (13.0.0) are compatible with your codebase and are the latest stable releases. Updating to the latest versions can help avoid potential bugs and take advantage of new features.

Run the following script to check the latest available versions of these packages:

Also applies to: 76-82

✅ Verification successful

Minor update recommended for 'pino' package

Your current setup is compatible, but consider updating pino from 9.5.0 to 9.6.0 for latest bug fixes. pino-pretty is already at the latest version (13.0.0).

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the latest versions of 'pino' and 'pino-pretty' packages.

# Check the latest version of 'pino'
npm info pino version

# Check the latest version of 'pino-pretty'
npm info pino-pretty version

Length of output: 67


Script:

#!/bin/bash
# Check package.json files for pino-related dependencies
fd package.json --exec jq -r '.dependencies["pino"] // .devDependencies["pino"] // empty, .dependencies["pino-pretty"] // .devDependencies["pino-pretty"] // empty'

# Look for pino configuration patterns
rg -l "pino|logger" --type ts

# Check for specific pino usage patterns
ast-grep --pattern 'import $_ from "pino"'

Length of output: 7680

packages/fastify-generators/src/generators/core/fastify-server/index.ts (4)

13-15: Correctly updated imports to use createGeneratorWithTasks

The import statements have been updated to include createGeneratorWithTasks, createNonOverwriteableMap, and createProviderType, aligning with the new task-based architecture.


49-52: Proper transition to createGeneratorWithTasks in generator initialization

The generator initialization now uses createGeneratorWithTasks with the descriptorSchema and an empty getDefaultChildGenerators. The buildTasks method is correctly defined, which enhances the modularity and clarity of the generator.


53-64: Well-defined main task with appropriate dependencies and exports

The main task is added to the task builder with the necessary dependencies, including nodeProvider, loggerServiceProvider, configServiceProvider, rootModuleProvider, and typescriptProvider. The exports are correctly specified with fastifyServerProvider.


100-111: Ensure configuration entries have unique keys and proper defaults

When merging configuration entries for SERVER_HOST and SERVER_PORT, verify that the keys are unique within the configuration map and that the default values align with the application's requirements.

packages/core-generators/src/generators/node/vitest/index.ts (2)

32-131: Refactoring to Task-Based Generator Improves Modularity

The transition from createGeneratorWithChildren to createGeneratorWithTasks enhances the modularity and clarity of the generator implementation. The use of tasks and encapsulation aligns with best practices, improving maintainability.


55-57: Verify Package Versions for Security and Compatibility

Please verify that the specified versions '2.1.1' for vitest and '4.3.2' for vite-tsconfig-paths are up-to-date and free from known vulnerabilities. This ensures the project benefits from the latest features and security patches.

Run the following script to check for the latest versions and security advisories:

packages/react-generators/src/generators/auth/auth-components/index.ts (1)

27-72: Refactor to task-based generator enhances modularity

The transition from createGeneratorWithChildren to createGeneratorWithTasks improves the structure and readability of the generator. Defining tasks within buildTasks allows for better organization of dependencies and export logic.

packages/react-generators/src/generators/core/react-typescript/index.ts (1)

39-66: Inconsistent moduleResolution may cause build conflicts

The moduleResolution option is set to 'bundler' in the main tsconfig.json (line 39) and 'Node' in tsconfig.node.json (line 66). This discrepancy can lead to inconsistent module resolution behavior between the main application and the Node-specific configurations. Consider aligning the moduleResolution settings or ensuring that the difference is intentional and won't cause issues.

packages/react-generators/src/generators/core/react-not-found-handler/index.ts (3)

30-33: Successful refactoring to createGeneratorWithTasks

The ReactNotFoundHandlerGenerator has been refactored to use createGeneratorWithTasks, and the buildTasks method is properly defined. This enhances the modularity and clarity of the generator setup.


36-43: Dependencies and exports are correctly specified

The dependencies (reactPages, reactComponents, typescript) and exports (reactNotFound) are appropriately defined within the task. This ensures that all necessary providers are available for the task execution.


44-79: Well-structured task logic in run and build methods

The run method correctly initializes the not found route and registers it with reactPages. The build method properly handles the file copy action for the NotFound page. The use of makeImportAndFilePath and TypescriptCodeUtils.createExpression is effective for setting up the route element.

packages/core-generators/src/generators/node/node-git-ignore/index.ts (2)

21-30: Transition to createGeneratorWithTasks is successfully applied

The NodeGitIgnoreGenerator has been updated to utilize createGeneratorWithTasks. The structure of the generator now aligns with the task-based architecture, improving maintainability.


31-79: Efficient handling of exclusion lines in .gitignore

The initialization of exclusionLines with standard ignore patterns is comprehensive. The addExclusions method and the handling of descriptor.additionalExclusions ensure that custom exclusions can be added. Writing the .gitignore file with writeFormattedAction is correctly implemented.

packages/fastify-generators/src/generators/prisma/prisma-relation-field/index.ts (3)

30-33: Refactoring to use createGeneratorWithTasks is properly implemented

The PrismaRelationFieldGenerator has been updated to use createGeneratorWithTasks, and the buildTasks method is correctly defined. This aligns the generator with the new task-based architecture.


37-43: Dependencies are accurately specified

The dependencies for prismaModel and foreignModel are correctly set up using prismaModelProvider, referencing the appropriate model names from the descriptor.


80-89: Verify if the foreign model's relation field requires additional attributes

Currently, the foreignModel.addField method adds the relation field with only the @relation attribute specifying the relationshipName. Consider verifying whether additional attributes such as fields, references, onDelete, and onUpdate should be included to fully define the relationship and maintain referential integrity.

packages/fastify-generators/src/generators/auth/auth-roles/index.ts (2)

43-61: ⚠️ Potential issue

Verify the accessibility of the 'roles' parameter within 'buildTasks' and 'run' methods

In the buildTasks method (line 43~), you are destructuring { roles }, but it's unclear where roles is coming from. Similarly, in the run function (line 54~), roles is used but not defined within its scope. Please ensure that the roles parameter is correctly passed and accessible within both buildTasks and run methods to prevent potential ReferenceError.


70-78: Clarify the usage of authRolesImport in authSetup configuration

In line 80~, you set authRolesImport in authSetup.getConfig():

authSetup.getConfig().set('authRolesImport', authRolesImport);

Ensure that authSetup expects this configuration key and that it's utilized appropriately downstream. If authRolesImport is a new addition, verify that all necessary adjustments have been made where authSetup consumes this configuration.

✅ Verification successful

authRolesImport configuration is properly integrated and utilized

The configuration is well-defined in AuthGeneratorConfig, properly validated with clear error messages, and correctly utilized in the import mapping system. No additional adjustments are needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find authSetup class/interface definition
ast-grep --pattern 'class authSetup {
  $$$
}'

# Search for interfaces or types related to authSetup
ast-grep --pattern 'interface $_ {
  $$$
  authRolesImport
  $$$
}'

# Look for direct string references to authRolesImport
rg "authRolesImport" -A 3 -B 3

# Find any config interfaces that might contain authRolesImport
ast-grep --pattern 'interface $_Config {
  $$$
}'

Length of output: 4865

packages/react-generators/src/generators/auth/auth-service/index.ts (2)

79-95: 🛠️ Refactor suggestion

Handle potential errors during file copy operations

In the build method, you perform file copy operations using typescript.createCopyAction and builder.apply. Ensure that these operations include error handling to catch any issues during file copying, such as missing source files or write permission errors.

Consider wrapping the copy actions in try-catch blocks or adding error callbacks to handle exceptions gracefully.


44-61: Ensure correct path resolution for generated files

In the run method (line 44~), you are generating file paths using makeImportAndFilePath:

const [serviceImport, servicePath] = makeImportAndFilePath(`${authFolder}/index.ts`);

Double-check that the authFolder variable is correctly set to src/services/auth and that generated paths resolve to the intended locations. This will prevent issues with module imports and file placements in the project structure.

✅ Verification successful

Path resolution implementation is correct and consistent

The makeImportAndFilePath utility correctly handles path resolution, and the auth service generator follows the established pattern used successfully across the codebase. The base path src/services/auth is consistent with the project's conventions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find the implementation of makeImportAndFilePath
ast-grep --pattern 'function makeImportAndFilePath'

# Find other usages of makeImportAndFilePath
rg "makeImportAndFilePath" -A 2

# Look for similar path handling in generator files
fd "index.ts" --exec rg -l "services.*auth" {}

Length of output: 37568

packages/react-generators/src/generators/core/react-error/index.ts (1)

94-103: Verify the formatting and placement of generated service files

When rendering templates to actions for the files error-logger.ts and error-formatter.ts, ensure that the generated code adheres to the project's formatting standards and is placed in the correct directories.

Consider integrating a code formatter or linter to automatically format the generated files.

packages/fastify-generators/src/generators/core/app-module/index.ts (2)

24-28: Verify the Usage of descriptor in buildTasks

The descriptor parameter is passed to the buildTasks method but is not used within the method body. Please confirm if this is intentional. If descriptor is not needed, consider removing it to simplify the method signature.


88-89: Ensure Correct Import Paths in Generated Code

The import statement in indexFile.addCodeAddition uses the path '@/${moduleFolder}/index.js'. Please verify that this path resolves correctly based on your project's module resolution settings. If using TypeScript path mappings or module aliases, ensure they are correctly configured.

packages/fastify-generators/src/generators/vitest/prisma-vitest/index.ts (3)

49-52: Check Compatibility of Added Development Dependencies

The specific versions of vitest-mock-extended and pg-connection-string are added:

node.addDevPackages({
  'vitest-mock-extended': '1.3.2',
  'pg-connection-string': '2.6.4',
});

Ensure these versions are compatible with existing dependencies and consider updating to the latest versions if there are no breaking changes to benefit from the latest features and security patches.

✅ Verification successful

Dependencies are Compatible and Properly Versioned

The specified versions of [email protected] and [email protected] are already successfully being used in the project's test infrastructure. These exact versions are proven to work in the existing codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find all package.json files
echo "=== Package.json files ==="
fd package.json

# Search for existing usage of these packages in package.json files
echo -e "\n=== Existing package versions ==="
rg -l "vitest-mock-extended|pg-connection-string" $(fd package.json)

# Look for imports
echo -e "\n=== Import statements ==="
rg "from ['\"]vitest-mock-extended['\"]|from ['\"]pg-connection-string['\"]"

# Check content of package.json files that mention these packages
echo -e "\n=== Package.json contents with these dependencies ==="
for f in $(rg -l "vitest-mock-extended|pg-connection-string" $(fd package.json)); do
  echo "=== $f ==="
  cat "$f"
done

Length of output: 6588


62-71: Validate Import Mapping Configuration

The importMap object defines custom import aliases:

const importMap = {
  '%prisma-vitest/db': { /* ... */ },
  '%prisma-vitest/prisma': { /* ... */ },
};

Please verify that these custom import aliases are correctly resolved in your build and test configurations. Ensure that tools like TypeScript, Vitest, and your IDE recognize these aliases to prevent import errors.

✅ Verification successful

Import Aliases are Correctly Configured in Generator Templates

The import aliases are part of the generator's template system and are properly mapped to the generated test helper files. This is verified by the working implementation in the test project where these imports are correctly resolved.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find relevant configuration files
echo "=== Searching for configuration files ==="
fd -e json -e js -e ts "config|vitest" --type f

# Look for path mappings in these files
echo -e "\n=== Searching for path alias configurations ==="
rg -l "paths|alias" $(fd -e json -e js -e ts "config|vitest" --type f)

# Search for actual usage of these aliases
echo -e "\n=== Searching for usage of prisma-vitest aliases ==="
rg "%prisma-vitest/(db|prisma)"

Length of output: 11792


Script:

#!/bin/bash
# Look for template files and configuration setup in the prisma-vitest generator
echo "=== Searching for prisma-vitest related files ==="
fd "prisma-vitest" --type f

# Check the content of these files
echo -e "\n=== Checking template content ==="
rg -A 5 -B 5 "createTestDatabase|prismaMock|import.*prisma-vitest"

# Look for path mapping configuration in the generator
echo -e "\n=== Checking path mapping configuration ==="
rg -A 10 "paths.*prisma-vitest|alias.*prisma-vitest"

Length of output: 14358


124-127: Verify Module Resolution in Import Replacement

In the prismaHelperPath replacement:

PRISMA_SERVICE_PATH: typescript.resolveModule(
  prismaOutput.getPrismaServicePath(),
  prismaHelperPath,
),

Ensure that typescript.resolveModule correctly computes the relative path between prismaHelperPath and the Prisma service path. Incorrect paths may lead to runtime errors if modules cannot be found.

✅ Verification successful

Module Resolution Implementation is Correct

The path resolution between prismaHelperPath and the Prisma service path is correctly implemented and well-tested. The resolved path is used appropriately in the test helper template for mocking purposes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find typescript.resolveModule implementation
ast-grep --pattern 'resolveModule($$$)'

# Find prismaOutput related files
rg "prismaOutput" -A 5

# Look for test files related to this functionality
fd "test|spec" -e ts -e js | xargs rg "resolveModule|prismaOutput"

# Find where prismaHelperPath is defined
rg "prismaHelperPath" -A 3

Length of output: 73252


Script:

#!/bin/bash
# Find getPrismaServicePath implementation
ast-grep --pattern 'getPrismaServicePath($$$)'

# Find where prismaHelperPath is defined in the vitest context
rg -B 5 -A 5 "prismaHelperPath.*=" 

# Look for related test files
fd "vitest|test" -e ts | xargs rg "getPrismaServicePath|prismaHelperPath"

Length of output: 1300


Script:

#!/bin/bash
# Find makeImportAndFilePath implementation
ast-grep --pattern 'makeImportAndFilePath($$$)'

# Get the complete prisma-vitest generator file
cat packages/fastify-generators/src/generators/vitest/prisma-vitest/index.ts

# Look for related test files
fd "prisma.*test-helper" -e ts

Length of output: 29233


Script:

#!/bin/bash
# Get the template content
cat packages/fastify-generators/src/generators/vitest/prisma-vitest/templates/prisma.test-helper.ts

# Find getPrismaServicePath implementation
rg -B 3 -A 3 "getPrismaServicePath.*{" 

# Find typescript.resolveModule implementation
rg -B 3 -A 3 "resolveModule.*{" 

Length of output: 1071


Script:

#!/bin/bash
# Find getPrismaServicePath implementation with fixed pattern
rg "getPrismaServicePath.*\(" -B 2 -A 2

# Find resolveModule implementation with fixed pattern
rg "export function resolveModule" -B 2 -A 5

# Look for any test files that verify the path resolution
fd "test|spec" -e ts | xargs rg "resolveModule.*test"

Length of output: 5021

packages/fastify-generators/src/generators/prisma/prisma-crud-delete/index.ts (2)

7-7: Import updated to use createGeneratorWithTasks

The import statement correctly updates to import createGeneratorWithTasks from '@halfdomelabs/sync', aligning with the new task-based architecture.


108-149: Generator successfully refactored to use createGeneratorWithTasks

The PrismaCrudDeleteGenerator has been effectively refactored to use createGeneratorWithTasks. Tasks are properly defined, dependencies are accurately specified, and the run function implements the logic correctly.

packages/react-generators/src/generators/core/react-router/index.ts (2)

14-14: Imports updated for task-based architecture

The import statements now correctly include createGeneratorWithTasks and createProviderType, reflecting the shift to the task-based architecture.


Line range hint 43-172: ReactRouterGenerator refactored to use createGeneratorWithTasks

The generator has been successfully updated to use createGeneratorWithTasks. Tasks are properly constructed, dependencies and exports are correctly defined, and the run function accurately implements the required logic for setting up routes and rendering.

packages/react-generators/src/generators/auth/auth-hooks/index.ts (2)

11-11: Imports updated to include createGeneratorWithTasks

The import statement now includes createGeneratorWithTasks, matching the architectural updates.


33-170: AuthHooksGenerator refactored to task-based structure

The generator has been effectively refactored to use createGeneratorWithTasks. Tasks are properly defined, dependencies and exports are accurately specified, and the run function contains the correct logic for building and applying actions related to authentication hooks.

packages/code-morph/src/scripts/run-morpher.ts (1)

76-85: Optimize Package Filtering in getPackages

The asyncFilter used in getPackages sequentially processes each package, which can be slow for large workspaces.

[performance]

Consider parallelizing the filter operation to improve performance:

-const packagesWithGlobs = await asyncFilter(
+const packagesWithGlobs = await Promise.all(
   workspacePackages,
-  async (pkg) => {
+  async (pkg): Promise<WorkspacePackage | null> => {
     if (!(await pathExists(path.join(pkg.directory, 'tsconfig.json'))))
-      return false;
+      return null;
     if (!morpher.pathGlobs?.length) return pkg;
     const matchingFiles = await globby(morpher.pathGlobs, {
       cwd: pkg.directory,
       gitignore: true,
     });
-    return matchingFiles.length > 0;
+    return matchingFiles.length > 0 ? pkg : null;
   },
 );
+const filteredPackages = packagesWithGlobs.filter(notEmpty);

This change collects the packages in parallel and filters out non-matching packages, potentially reducing the total execution time.

packages/fastify-generators/src/generators/prisma/prisma-crud-update/index.ts (1)

190-202: Verify Correct Use of Primary Key Expressions

The whereUniqueExpression is set using primaryKey.whereClause, which should accurately represent the unique identifier for the model.

Ensure that primaryKey.whereClause correctly constructs a unique identifier for the Prisma update operation.

Run the following script to verify:

✅ Verification successful

Primary Key Expression Implementation is Correct

The getPrimaryKeyExpressions function correctly handles both single and composite primary keys, properly constructing the whereClause for Prisma's update operations. The implementation includes proper validation and type safety.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify primary key expressions for all models.

# Test: List models and their unique identifiers.
ast-grep --pattern 'const primaryKey = getPrimaryKeyExpressions($_)' --json

# Expected Result: Each model should have a valid unique identifier in the `whereClause`.

Length of output: 1630


Script:

#!/bin/bash
# Find the implementation of getPrimaryKeyExpressions
ast-grep --pattern 'function getPrimaryKeyExpressions($_) {
  $$$
}'

# Find the import statement
rg "import.*getPrimaryKeyExpressions" -A 1

Length of output: 115


Script:

#!/bin/bash
# Try different patterns for the implementation
ast-grep --pattern 'export const getPrimaryKeyExpressions = $_'

# Search for files containing primaryKey-related code
rg "getPrimaryKeyExpressions" -B 2 -A 2

# Look for type definitions
ast-grep --pattern 'type $_PrimaryKey'

Length of output: 3610


Script:

#!/bin/bash
# Get the implementation and related types
cat packages/fastify-generators/src/generators/prisma/_shared/crud-method/primary-key-input.ts

# Look for PrismaOutputModel definition
rg "interface PrismaOutputModel" -A 5

Length of output: 4011

packages/react-generators/src/generators/core/react-components/index.ts (2)

69-214: Well-Structured Refactor to Task-Based Generator

The refactoring of ReactComponentsGenerator to use createGeneratorWithTasks improves the code structure and readability. Dependencies, exports, and build steps are cleanly organized within tasks.


121-132: Confirm Correct Import Paths for Render Siblings

When adding the ConfirmDialog component as a render sibling, the import path uses @/${srcFolder}/components. Ensure that this path correctly resolves based on your project structure.

If the components are located in src/components, the import path should be '@/components'.

Apply this diff if adjustment is needed:

 reactApp.addRenderSibling(
   TypescriptCodeUtils.createExpression(
     '<ConfirmDialog />',
-    `import { ConfirmDialog } from "@/${srcFolder}/components";`,
+    `import { ConfirmDialog } from "@/components";`,
   ),
 );
packages/core-generators/src/generators/node/prettier/index.ts (1)

112-272: ⚠️ Potential issue

Ensure thread-safe initialization of shared promises

In the formatFunction, the shared variables prettierModulePromise and prettierConfigPromise are initialized lazily. If formatFunction is called concurrently, this could lead to race conditions during the initialization of these promises. Consider using a mutex or initialization pattern that ensures thread-safe assignment to prevent potential issues.

Apply this diff to address the potential race condition:

- if (!prettierModulePromise) {
+ if (prettierModulePromise === undefined) {
    // Initialization code
  }

Alternatively, you could initialize the promises at the top level to avoid concurrency issues within the function.

Likely invalid or redundant comment.

packages/react-generators/src/generators/admin/admin-crud-list/index.ts (3)

Line range hint 33-234: Refactor to task-based generator is well-implemented

The transition from createGeneratorWithChildren to createGeneratorWithTasks is clean and maintains the functionality effectively. Dependencies, exports, and the task's run logic are appropriately structured.


120-121: Ensure 'graphQLFields' are defined for all columns

When setting row fields using c.display.graphQLFields, make sure that graphQLFields is defined for every column to prevent potential runtime errors. Adding a check or default value can enhance the reliability of the code.

Run the following script to check for columns without graphQLFields:


84-88: Verify existence of 'dataDependencies' in columns

In the mergeAdminCrudDataDependencies call, you are accessing c.display.dataDependencies without checking if dataDependencies exists on c.display. If any column lacks dataDependencies, this could lead to runtime errors. Consider adding a null check or default value to ensure robustness.

Run the following script to check for columns without dataDependencies:

packages/react-generators/src/generators/admin/admin-crud-queries/index.ts (1)

66-323: Task-based refactoring maintains functionality

The refactoring to use createGeneratorWithTasks is successfully implemented. The main task encapsulates the query generation logic effectively, and the provider continues to expose the necessary methods.

packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts (6)

7-7: Import statement updated to reflect new architecture

The import of createGeneratorWithTasks from @halfdomelabs/sync aligns with the transition to the task-based generator model.


185-187: Refactored to use createGeneratorWithTasks

The change from createGeneratorWithChildren to createGeneratorWithTasks in the definition of EmbeddedRelationTransformerGenerator accurately reflects the intended architectural refactor.


188-215: Tasks correctly defined within buildTasks function

The buildTasks function effectively utilizes taskBuilder to define tasks, with appropriate parameters and dependencies. This setup enhances modularity and clarity in task management.


232-236: Ensure foreignCrudService is adequately checked before use

Although there is a check for foreignCrudService when embeddedTransformerNames is provided, ensure all subsequent usages of foreignCrudService handle the possibility of it being undefined to prevent runtime errors.


241-244: Optional chaining correctly used for safe property access

The use of optional chaining with embeddedTransformerNames?.map and foreignCrudService?.getTransformerByName(name) ensures that the code handles undefined values gracefully.


627-629: Transformer added to prismaCrudServiceSetup appropriately

The addition of the transformer via prismaCrudServiceSetup.addTransformer integrates the new transformer correctly into the CRUD service setup.

packages/code-morph/src/index.ts (1)

1-3: LGTM! Well-organized exports.

The exports are properly structured and the addition of load-morphers.js aligns with the PR's objective of enabling code morphs across packages.

packages/code-morph/src/morphers/tests/move-import-reference/simple/input.ts (1)

3-7: LGTM! Clear test case structure.

The test case provides a focused example for testing import reference movement functionality.

packages/code-morph/eslint.config.js (1)

1-8: Verify the scope of ignored files.

The ESLint configuration looks good, extending the base rules appropriately. However, let's verify that the ignore pattern isn't too broad.

✅ Verification successful

ESLint ignore pattern is correctly scoped

The pattern src/morphers/tests/*/**/* precisely targets test fixtures while keeping unit tests and test helpers under lint coverage. This is the right approach as:

  • Unit tests (.morpher.unit.test.ts) remain linted
  • Only test fixtures containing intentionally malformed code are ignored
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the scope of files being ignored by ESLint

# List all files that match the ignore pattern
fd . "src/morphers/tests" -t f

# Compare with all test files to ensure we're not ignoring too much
fd . "src/morphers" -t f

Length of output: 261


Script:

#!/bin/bash
# First, let's understand the repository structure
fd . packages/code-morph -t d

# Then find all test files in the code-morph package
fd . packages/code-morph -t f -e test.js -e test.ts -e spec.js -e spec.ts

# Check if there are any files with 'morpher' in their path
fd . packages/code-morph -t f | grep -i morpher

Length of output: 2437

packages/fastify-generators/src/generators/prisma/prisma-model-id/index.ts (2)

1-1: LGTM: Import updated to reflect new architecture

The import change aligns with the PR objective of transitioning to a task-based model.


10-25: LGTM: Clean task-based implementation

The refactoring to use createGeneratorWithTasks is well-structured:

  • Task dependencies are clearly defined
  • Core functionality is properly encapsulated in the 'main' task
  • Original behavior is preserved
packages/code-morph/src/morphers/utils/imports.ts (1)

8-13: LGTM: Well-documented function

The JSDoc comments clearly explain the purpose and parameters of the function.

packages/code-morph/src/load-morphers.ts (1)

8-9: Verify path resolution compatibility

The use of import.meta.dirname might not be compatible with all Node.js versions. Consider adding a fallback mechanism.

packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-deps/input.ts (2)

33-36: ⚠️ Potential issue

Fix incorrect parameter usage in createGenerator

The function uses tabWidth directly without destructuring it from the parameters.

-  createGenerator({ tabWidth }) {
+  createGenerator(descriptor) {
     const prettierConfig = createNonOverwriteableMap<PrettierConfig>({
-      tabWidth,
+      tabWidth: descriptor.tabWidth,
     });

Likely invalid or redundant comment.


1-1: Consider enabling TypeScript type checking

The @ts-nocheck directive disables all TypeScript type checking for this file. Consider enabling type checking to catch potential type-related issues early.

packages/code-morph/src/morphers/tests/migrate-generator-with-children/simple/input.ts (1)

28-49: Well-structured implementation!

The implementation correctly:

  • Declares and uses dependencies
  • Properly destructures and uses parameters
  • Correctly accesses descriptor properties
packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-descriptor/output.ts (1)

28-53: Verify task-based migration pattern

The migration to createGeneratorWithTasks follows the correct pattern by:

  • Using taskBuilder.addTask
  • Defining a main task
  • Moving exports to task level
  • Preserving the original functionality

However, ensure that the descriptor is properly passed to the task's run function.

packages/code-morph/src/morphers/tests/migrate-generator-with-children/no-deps/output.ts (1)

1-1: Consider removing @ts-nocheck and fixing type issues.

Using @ts-nocheck bypasses TypeScript's type checking, which could hide potential type-related issues. Consider addressing the type issues directly.

packages/react-generators/src/generators/admin/admin-crud-section/index.ts (1)

59-61: Consider implementing the adminCrudSection provider interface.

The provider returns an empty object, which might not be the intended implementation.

packages/react-generators/src/generators/admin/admin-crud-password-input/index.ts (1)

14-53: LGTM! Clean transition to task-based architecture.

The refactoring from createGeneratorWithChildren to createGeneratorWithTasks is well-structured. The task encapsulation maintains the original functionality while improving code organization.

packages/fastify-generators/src/generators/core/fastify-graceful-shutdown/index.ts (1)

17-53: LGTM! Well-structured task implementation.

The transition to task-based architecture maintains all necessary functionality while improving code organization. The plugin registration and file copying logic are properly encapsulated.

packages/react-generators/src/generators/core/react-proxy/index.ts (1)

Line range hint 25-68: LGTM! Clean task-based implementation.

The transition maintains all proxy functionality while improving code structure. The WebSocket and proxy configuration handling is well-organized.

plugins/baseplate-plugin-storage/src/generators/react/admin-crud-file-input/index.ts (1)

15-61: LGTM! Well-structured task implementation.

The transition to task-based architecture is clean and maintains all file input functionality while improving code organization.

packages/react-generators/src/generators/admin/admin-crud-text-input/index.ts (1)

25-28: LGTM: Clean migration to task-based structure

The migration from createGeneratorWithChildren to createGeneratorWithTasks maintains the core functionality while improving the code organization.

packages/react-generators/src/generators/admin/admin-home/index.ts (1)

42-52: Verify path resolution across different environments

The path resolution for the Home component should be tested across different operating systems to ensure consistent behavior.

✅ Verification successful

Path resolution implementation verified as cross-platform safe

The makeImportAndFilePath utility explicitly handles path normalization and ensures consistent behavior across different operating systems by:

  • Converting platform-specific separators to POSIX format
  • Using node's built-in path utilities for reliable path handling
  • Maintaining consistent import path format with @/ prefix
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for potential path resolution issues across the codebase
rg -g '*.{ts,tsx}' "makeImportAndFilePath|getDirectoryBase" -A 2

Length of output: 41994


Script:

#!/bin/bash
# Check the implementation of makeImportAndFilePath
cat packages/core-generators/src/utils/path.ts

Length of output: 567

packages/fastify-generators/src/generators/auth/password-hasher-service/index.ts (1)

49-51: Review argon2 package version for security updates

The hardcoded version of @node-rs/argon2 (2.0.2) should be verified for security updates.

✅ Verification successful

✓ Package version is current and secure

The @node-rs/argon2 package is at the latest version (2.0.2) with no known security vulnerabilities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for latest version and security advisories
echo "Checking latest version of @node-rs/argon2"
curl -s https://registry.npmjs.org/@node-rs/argon2/latest | jq '.version'

echo "Checking for security advisories"
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@node-rs/argon2") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
    }
  }
}'

Length of output: 545

packages/fastify-generators/src/generators/auth/auth-plugin/index.ts (2)

18-21: LGTM! Generator refactored to use task-based approach.

The transition from createGeneratorWithChildren to createGeneratorWithTasks aligns with the PR objective and maintains the same functionality.


21-75: Verify task dependencies and return values.

The task structure looks good, with dependencies and logic properly encapsulated. However, let's verify that all dependencies are being used effectively.

Run the following script to analyze dependency usage:

✅ Verification successful

Dependencies and task structure verified successfully.

All dependencies are properly utilized within the task's run method, and the return interface follows the established pattern seen across the codebase. The importMappers array correctly includes authContext, userSessionService, and userSessionTypes for the typescript.createCopyAction call.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all declared dependencies are used within the task's run method.

# Search for dependency usage patterns
ast-grep --pattern $'run({$deps}) {
  $$$
  $dep
  $$$
}'

Length of output: 58


Script:

#!/bin/bash
# Find task definition and usage patterns
ast-grep --pattern 'addTask({
  name: $_,
  dependencies: {
    $$$
  },
  $$$
})'

# Search for similar task patterns to understand the interface
rg "getProviders.*build.*" -A 5 -B 5

Length of output: 123


Script:

#!/bin/bash
# Search for task-related patterns in TypeScript files
rg "buildTasks.*taskBuilder" -t ts -A 10
rg "getProviders.*build" -t ts -A 10

# Search for specific dependency usage
rg "typescript\.createCopyAction|appModule\.getModuleFolder|userSessionService|authContext|node\.addPackages" -t ts

Length of output: 77597


Script:

#!/bin/bash
# Search for similar task return patterns and importMappers usage
rg "getProviders.*return.*{" -A 5
rg "createCopyAction.*importMappers" -A 2 -B 2

Length of output: 194


Script:

#!/bin/bash
# Search for task patterns with simpler regex
rg "getProviders\(\)" -t ts -A 3
rg "build: async.*typescript\.createCopyAction" -t ts -B 3 -A 3
rg "importMappers: \[" -t ts -A 3

Length of output: 47870

packages/react-generators/src/generators/admin/admin-crud-enum-input/index.ts (1)

21-24: LGTM! Generator refactored to use task-based approach.

The transition from createGeneratorWithChildren to createGeneratorWithTasks maintains the same functionality while improving code organization.

packages/code-morph/src/morphers/move-import-reference.morpher.ts (2)

12-23: LGTM! Improved options structure with better documentation.

The new options structure provides better documentation with descriptions and explicit validation rules.


71-75: Verify the behavior of insertImportDeclarationAtTop.

The new utility function is being used to handle import declarations. Let's verify its implementation and usage across the codebase.

✅ Verification successful

Implementation of insertImportDeclarationAtTop is correct and well-designed

The utility function correctly handles import declarations by:

  • Preserving existing comments at the top of the file
  • Inserting imports at the appropriate position
  • Maintaining proper formatting with newlines
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation and usage of insertImportDeclarationAtTop

# Find the implementation
ast-grep --pattern 'function insertImportDeclarationAtTop'

# Find other usages
rg 'insertImportDeclarationAtTop'

Length of output: 438


Script:

#!/bin/bash
# Get the implementation of insertImportDeclarationAtTop
ast-grep --pattern 'export function insertImportDeclarationAtTop($_) {
  $$$
}'

# Look for test files
fd 'imports.test' --exec cat {}

Length of output: 115


Script:

#!/bin/bash
# Get the entire implementation file
cat packages/code-morph/src/morphers/utils/imports.ts

# Look for test files with .ts extension
fd 'imports.test.ts' --exec cat {}

# Backup: simpler ast-grep pattern
ast-grep --pattern 'insertImportDeclarationAtTop'

Length of output: 1332

packages/create-project/src/create-baseplate-project.ts (1)

83-83: LGTM! More precise error handling.

The error handling now correctly checks both the instance type and name, making it more robust.

packages/fastify-generators/src/generators/prisma/prisma-field/index.ts (1)

50-53: LGTM: Clean transition to task-based architecture

The refactoring from createGeneratorWithChildren to createGeneratorWithTasks maintains the generator's functionality while improving its structure.

packages/core-generators/src/generators/docker/docker-compose/index.ts (1)

91-96: 🛠️ Refactor suggestion

Verify YAML formatting compatibility

The code uses a generic formatter for the Docker Compose file. This might not preserve YAML-specific formatting requirements.

Consider using a YAML-specific formatter or validating the output format:

           builder.writeFile(
             dockerComposePath,
-            `${`
-${entries.join('\n')}`.trim()}\n`,
+            entries.join('\n') + '\n',
-            { shouldFormat: true },
+            { shouldFormat: true, parser: 'yaml' },
           );
packages/core-generators/src/generators/node/eslint/index.ts (2)

28-108: LGTM! Clean transition to task-based approach.

The refactoring maintains the original functionality while improving code organization. The task structure clearly separates concerns and maintains proper dependency management.


69-82: Verify package versions for security and compatibility.

The ESLint-related packages have fixed versions. Since these are dev dependencies, it's good practice to verify they're up to date.

✅ Verification successful

Several packages have newer versions available, but current versions are secure

  • Current versions have no known security vulnerabilities
  • Major version updates available for ESLint (9.x) and typescript-eslint packages (8.x) should be carefully tested for compatibility
  • Minor updates available for eslint-import-resolver-typescript (3.7.0), eslint-plugin-import (2.31.0), and eslint-plugin-vitest (0.5.4)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check latest versions and security advisories for ESLint packages
for pkg in "@typescript-eslint/eslint-plugin" "@typescript-eslint/parser" "eslint" "eslint-plugin-jsx-a11y" "eslint-plugin-react" "eslint-plugin-react-hooks" "eslint-config-prettier" "eslint-import-resolver-typescript" "eslint-plugin-import" "eslint-plugin-vitest"; do
  echo "Checking $pkg..."
  # Get latest version from npm
  curl -s "https://registry.npmjs.org/$pkg" | jq -r '.["dist-tags"].latest'
  
  # Check for security advisories
  gh api graphql -f query='{
    securityVulnerabilities(first: 1, ecosystem: NPM, package: "'$pkg'") {
      nodes {
        advisory {
          summary
          severity
        }
        vulnerableVersionRange
      }
    }
  }'
done

Length of output: 7573

packages/fastify-generators/src/generators/stripe/fastify-stripe/index.ts (2)

27-105: LGTM! Well-structured task implementation.

The refactoring successfully maintains the complex dependency chain while improving code organization through the task-based approach.


52-55: Verify Stripe package versions for security.

The implementation uses fixed versions for stripe and fastify-raw-body. Given these are production dependencies interfacing with payment systems, version verification is crucial.

packages/react-generators/src/generators/auth/auth-login-page/index.ts (1)

32-113: LGTM! Clean implementation of the task-based approach.

The refactoring successfully preserves the complex template handling while improving code organization through tasks.

packages/react-generators/src/generators/core/react-app/index.ts (1)

35-109: LGTM! Well-structured task implementation with proper state management.

The refactoring successfully maintains the complex state management while improving code organization through tasks.

packages/react-generators/src/generators/apollo/apollo-error-link/index.ts (1)

13-16: LGTM! Clean transition to task-based structure.

The generator has been successfully refactored to use createGeneratorWithTasks while maintaining the same descriptor schema and empty child generators.

packages/react-generators/src/generators/admin/admin-crud-foreign-input/index.ts (1)

23-26: LGTM! Clean transition to task-based structure.

The generator has been successfully refactored to use createGeneratorWithTasks while maintaining the same descriptor schema and empty child generators.

packages/react-generators/src/generators/admin/admin-components/index.ts (2)

24-27: LGTM! Clean transition to task-based structure.

The generator has been successfully refactored to use createGeneratorWithTasks while maintaining the same descriptor schema and empty child generators.


39-41: Verify the fixed version of nanoid.

The package version is fixed to 3.3.8. Please verify if this version is still secure and up-to-date.

✅ Verification successful

The fixed version 3.3.8 of nanoid is secure and appropriate.

While newer versions exist (up to 5.0.9), version 3.3.8 is not affected by any known security vulnerabilities and represents a stable point in the v3 line. Upgrading to v4 or v5 could introduce breaking changes without significant security benefits.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for latest versions and security advisories for nanoid package.

# Check NPM for latest versions
npm view nanoid versions --json | jq -r '.[-1]'

# Check for security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "nanoid") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 1125

packages/code-morph/src/morphers/tests/morpher.test-helper.ts (1)

54-112: LGTM! Comprehensive test runner implementation.

The test runner implementation is thorough and well-structured:

  • Proper test case collection
  • Comprehensive error handling
  • Integration with prettier for consistent formatting
  • Clear test output and error reporting
packages/fastify-generators/src/generators/prisma/prisma-utils/index.ts (2)

9-9: LGTM! Import updated for task-based architecture.

The import statement has been correctly updated to use createGeneratorWithTasks instead of createGeneratorWithChildren.


64-117: Verify task dependencies are properly ordered.

The transition to task-based architecture looks good. However, the task dependencies between typescript, serviceContext, prismaOutput, and tsUtils should be verified to ensure they are executed in the correct order.

Run this script to analyze the dependency graph:

✅ Verification successful

Dependencies are correctly ordered and independent

The dependencies in the prisma-utils generator are used independently as import mappers during file copying operations. There are no ordering constraints or circular dependencies between typescript, serviceContext, prismaOutput, and tsUtils providers. The current implementation is correct and efficient.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify task dependencies and their execution order
# Look for any circular dependencies or incorrect ordering

# Search for dependency declarations
rg -A 5 "dependencies: {" packages/fastify-generators/src/generators/prisma/
# Search for dependency usage patterns
rg -A 5 "run\(\{.*\}\)" packages/fastify-generators/src/generators/prisma/

Length of output: 6013


Script:

#!/bin/bash
# Search for provider definitions and dependencies with fixed patterns
rg "dependencies: \{" -A 10 packages/fastify-generators/src/generators/prisma/

# Search for provider definitions
rg "Provider = " -A 5 packages/fastify-generators/src/

# Use ast-grep to find provider definitions
ast-grep --pattern 'const $_ = createProvider({
  $$$
})'

Length of output: 30748

packages/react-generators/src/generators/auth/auth-apollo/index.ts (2)

6-6: LGTM! Import updated for task-based architecture.

The import statement has been correctly updated to use createGeneratorWithTasks.


23-115: Verify Apollo link ordering and dependencies.

The task-based implementation looks good, but the Apollo link configuration requires careful verification:

  1. The authLink depends on refreshTokenLink
  2. The refreshTokenLink depends on errorLink
  3. The websocket options are properly configured for token handling

Run this script to verify the Apollo link configuration:

✅ Verification successful

Apollo link configuration is correctly ordered and dependencies are valid

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify Apollo link configuration and dependencies
# Look for any circular dependencies or incorrect ordering in link chain

# Search for link declarations and their dependencies
ast-grep --pattern 'reactApolloSetup.addLink({
  name: $_,
  $$$,
  dependencies: [$_],
  $$$
})'

# Search for websocket option declarations
ast-grep --pattern 'reactApolloSetup.addWebsocketOption($_, $_)'

Length of output: 7153

packages/react-generators/src/generators/core/react-config/index.ts (1)

14-14: LGTM! Import updated for task-based architecture.

The import statement has been correctly updated to use createGeneratorWithTasks.

packages/react-generators/src/generators/core/react-routes/index.ts (1)

5-5: LGTM! Import updated for task-based architecture.

The import statement has been correctly updated to use createGeneratorWithTasks.

packages/fastify-generators/src/generators/prisma/prisma-crud-create/index.ts (2)

7-7: LGTM: Import statement updated to reflect architectural changes.

The import statement has been updated to use createGeneratorWithTasks from @halfdomelabs/sync, aligning with the new task-based architecture.


128-131: Verify task configuration structure.

The generator has been refactored to use tasks instead of child generators. Please ensure that the task-based approach maintains all the functionality previously handled by child generators.

✅ Verification successful

Task-based implementation verified successfully.

The generator follows the established task-based patterns used consistently across the codebase. The migration from child generators is complete and maintains the required functionality through the task configuration structure.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usages of createGeneratorWithChildren
# to ensure complete migration to task-based approach

rg -l "createGeneratorWithChildren" --type ts

Length of output: 390


Script:

#!/bin/bash
# Check git history for the previous implementation
git log -L :PrismaCrudCreateGenerator:packages/fastify-generators/src/generators/prisma/prisma-crud-create/index.ts

# Find similar task-based generators for pattern comparison
rg "createGeneratorWithTasks" -A 5 --type ts

Length of output: 66343

packages/sync/src/utils/create-generator-with-tasks.ts (1)

182-182: Verify impact of broader type constraint.

The type constraint has been changed from z.SomeZodObject to z.ZodType, which allows for more flexible schema definitions. Please ensure that this broader type constraint doesn't lead to runtime issues with schema validation.

✅ Verification successful

Type constraint change is safe and beneficial

The broader type constraint from z.SomeZodObject to z.ZodType is safe as all existing usages in the codebase use z.object() schemas, which satisfy both constraints. The change enables more flexibility for future schema definitions while maintaining type safety through Zod's runtime validation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any custom schema types that might be affected
# by the broader type constraint

# Search for custom schema definitions
rg -A 5 "z\.object\(" --type ts

# Search for direct usage of createGeneratorWithTasks
ast-grep --pattern 'createGeneratorWithTasks<$_>($_)'

Length of output: 71342

packages/code-morph/tsconfig.json (1)

7-7: Verify path migration completeness.

The project structure has been reorganized:

  1. Path alias changed from @scripts/* to @src/*
  2. Include paths consolidated to src/**/*

Please ensure all imports have been updated to use the new path structure.

Also applies to: 10-10

✅ Verification successful

Path migration successfully verified

The code-morph package has been properly migrated:

  • All files are correctly organized in the src/ directory
  • No references to old path aliases (@scripts/*)
  • @src/* imports are correctly configured and used throughout the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to old paths

# Check for any remaining @scripts imports
rg "@scripts/" --type ts

# Check for any files still in old directories
fd -t f . transforms morphers lib

Length of output: 263


Script:

#!/bin/bash
# Verify project structure and path usage

# Check if src directory exists and show its structure
fd . src -t d

# Check for any variations of old paths (case insensitive)
rg -i "scripts/" --type ts
rg -i "transforms/" --type ts
rg -i "morphers/" --type ts
rg -i "lib/" --type ts

# Check usage of new @src alias
rg "@src/" --type ts

Length of output: 66491


Script:

#!/bin/bash
# Check code-morph package structure and imports

# Show directory structure of code-morph package
fd . packages/code-morph -t f

# Check for any old imports in code-morph package
rg "@scripts/" packages/code-morph
rg "transforms/" packages/code-morph
rg "morphers/" packages/code-morph
rg "lib/" packages/code-morph

# Check usage of new @src alias in code-morph package
rg "@src/" packages/code-morph

Length of output: 4504

packages/create-project/package.json (1)

28-28: Verify compatibility with pinned version.

The version of @inquirer/prompts has been pinned to 7.2.1 from ^4.3.2. While this provides better dependency stability, please ensure:

  1. Version 7.2.1 includes all required features
  2. There are no known security issues with this version
✅ Verification successful

Version 7.2.1 appears compatible and secure

The pinned version is being used correctly in both packages:

  • Only core prompt features (input, checkbox, search) are utilized
  • No security vulnerabilities are reported for this version
  • Both packages are aligned on the same version
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any security advisories for @inquirer/prompts

gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@inquirer/prompts") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 350


Script:

#!/bin/bash
# Find files importing @inquirer/prompts and show their content
rg --type js --type ts "@inquirer/prompts" -B 2 -A 5

# Also check package.json files for any other packages depending on @inquirer/prompts
rg -g "package.json" "@inquirer/prompts"

Length of output: 1258

packages/code-morph/package.json (2)

24-24: Script changes reflect improved project structure and testing.

The movement of run:morpher to src/scripts and addition of test script with vitest indicates better organization and test coverage.

Also applies to: 26-26


30-30: Verify compatibility with updated dependencies.

The transition from jscodeshift to ts-morph and addition of new dependencies (@inquirer/prompts, globby, yaml) represents a significant architectural change.

Run this script to check for any breaking changes in the new ts-morph version:

Also applies to: 33-33, 36-36, 37-37

✅ Verification successful

Dependencies are compatible and properly integrated

The transition from jscodeshift to ts-morph and the addition of new dependencies (@inquirer/prompts, globby, yaml) shows proper integration with standard API usage patterns and appropriate version constraints. No breaking changes or compatibility issues detected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any ts-morph API usage that might be affected by the version update
rg -A 3 "(?:Project|SourceFile|Node|SyntaxKind)\." 

Length of output: 15147


Script:

#!/bin/bash
# Check ts-morph version and new dependencies
echo "=== Checking package versions ==="
cat packages/code-morph/package.json | jq '.dependencies'

echo -e "\n=== Checking @inquirer/prompts usage ==="
rg "@inquirer/prompts" -A 2

echo -e "\n=== Checking globby usage ==="
rg "globby" -A 2

echo -e "\n=== Checking yaml usage ==="
rg "yaml" -A 2

Length of output: 21177

packages/fastify-generators/package.json (1)

46-46: Dependency version sync looks good.

The ts-morph version update aligns with the changes in code-morph package, maintaining consistency across packages.

packages/core-generators/package.json (1)

54-54: Dependency version sync looks good.

The ts-morph version update aligns with other packages, ensuring consistent AST manipulation capabilities across the codebase.

packages/react-generators/src/generators/core/react-logger/index.ts (2)

31-34: Good architectural shift to task-based generation.

The transition from createGeneratorWithChildren to createGeneratorWithTasks aligns with the PR objectives and provides better modularity.


35-48: Well-structured task definition with clear dependencies.

The task definition follows best practices with:

  • Clear name and purpose
  • Explicit dependency declarations
  • Proper export configuration
plugins/baseplate-plugin-storage/src/generators/fastify/prisma-file-transformer/index.ts (9)

10-10: Updated import statement aligns with architectural changes

The import of createGeneratorWithTasks reflects the transition to a task-based generator model, ensuring consistency with the new architecture.


24-24: Generator initialization correctly uses createGeneratorWithTasks

The use of createGeneratorWithTasks in initializing PrismaFileTransformerGenerator correctly aligns with the new task-based structure.


27-42: Proper setup of tasks in buildTasks method

The buildTasks method is appropriately defined, and the task 'main' is correctly added with the necessary dependencies and parameters in the run function.


46-61: Robust error handling for foreign relation validation

The code correctly validates the existence and structure of the foreign relation, throwing informative errors if the relation is not found or does not meet the required conditions (e.g., having exactly one field).


67-68: Consider including 'upsert' in isFieldOptional condition

Currently, isFieldOptional is determined by operationType === 'update' || foreignRelation.isOptional;. Should the 'upsert' operation also be considered here to ensure correct optionality handling during upsert operations?


70-76: Ensure accurate parameter construction in validateFileUploadInput

The validateFileUploadInput function call constructs arguments based on operationType. Please verify that all operation types ('create', 'update', 'upsert') are correctly handled, and the conditional logic accurately reflects the intended behavior, especially concerning the inclusion of existingItem and the use of optional chaining.


97-97: Double-check the assignment of isNullable in dtoField

The isNullable property is set to foreignRelation.isOptional. Verify whether isNullable should reflect foreignRelation.isOptional or if it requires a different condition to accurately represent the nullability in the DTO field.


115-124: Validate expressions for createExpression and updateExpression

Ensure that the createExpression and updateExpression are correctly defined for both optional and non-optional fields. Specifically, confirm that:

  • For createExpression, the logic accurately handles optional fields.
  • For updateExpression, the use of createPrismaDisconnectOrConnectData and the handling of foreignRelation.isOptional align with the expected Prisma behavior.

127-130: Transformer flags are appropriately set

The flags isAsync, needsExistingItem, and needsContext are correctly set, ensuring that the transformer functions as expected within the async context and has access to necessary data.

{
name: 'passwordHash',
transformer: TypescriptCodeUtils.createBlock(
'const passwordHash = password ?? await createPasswordHash(password);',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect password hashing logic

The current logic password ?? await createPasswordHash(password) has two issues:

  1. It uses null coalescing with await which doesn't make logical sense
  2. If password is null, it attempts to hash null instead of storing null
-                  'const passwordHash = password ?? await createPasswordHash(password);',
+                  'const passwordHash = password ? await createPasswordHash(password) : null;',
📝 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.

Suggested change
'const passwordHash = password ?? await createPasswordHash(password);',
'const passwordHash = password ? await createPasswordHash(password) : null;',

Comment on lines +23 to +50
run({ prismaCrudServiceSetup, passwordHasherService }) {
prismaCrudServiceSetup.addTransformer('password', {
buildTransformer: () => ({
inputFields: [
{
type: TypescriptCodeUtils.createExpression('string | null'),
dtoField: {
name: 'password',
type: 'scalar',
scalarType: 'string',
isOptional: true,
isNullable: true,
},
},
],
outputFields: [
{
name: 'passwordHash',
transformer: TypescriptCodeUtils.createBlock(
'const passwordHash = password ?? await createPasswordHash(password);',
'import {createPasswordHash} from "%password-hasher-service";',
{ importMappers: [passwordHasherService] },
),
},
],
isAsync: true,
}),
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for password hashing

The transformer is marked as async but doesn't handle potential errors from createPasswordHash. Consider wrapping the password hashing in a try-catch block.

-                transformer: TypescriptCodeUtils.createBlock(
-                  'const passwordHash = password ? await createPasswordHash(password) : null;',
-                  'import {createPasswordHash} from "%password-hasher-service";',
-                  { importMappers: [passwordHasherService] },
-                ),
+                transformer: TypescriptCodeUtils.createBlock(
+                  `try {
+                    const passwordHash = password ? await createPasswordHash(password) : null;
+                    return { passwordHash };
+                  } catch (error) {
+                    throw new Error('Failed to hash password: ' + error.message);
+                  }`,
+                  'import {createPasswordHash} from "%password-hasher-service";',
+                  { importMappers: [passwordHasherService] },
+                ),
📝 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.

Suggested change
run({ prismaCrudServiceSetup, passwordHasherService }) {
prismaCrudServiceSetup.addTransformer('password', {
buildTransformer: () => ({
inputFields: [
{
type: TypescriptCodeUtils.createExpression('string | null'),
dtoField: {
name: 'password',
type: 'scalar',
scalarType: 'string',
isOptional: true,
isNullable: true,
},
},
],
outputFields: [
{
name: 'passwordHash',
transformer: TypescriptCodeUtils.createBlock(
'const passwordHash = password ?? await createPasswordHash(password);',
'import {createPasswordHash} from "%password-hasher-service";',
{ importMappers: [passwordHasherService] },
),
},
],
isAsync: true,
}),
});
run({ prismaCrudServiceSetup, passwordHasherService }) {
prismaCrudServiceSetup.addTransformer('password', {
buildTransformer: () => ({
inputFields: [
{
type: TypescriptCodeUtils.createExpression('string | null'),
dtoField: {
name: 'password',
type: 'scalar',
scalarType: 'string',
isOptional: true,
isNullable: true,
},
},
],
outputFields: [
{
name: 'passwordHash',
transformer: TypescriptCodeUtils.createBlock(
`try {
const passwordHash = password ? await createPasswordHash(password) : null;
return { passwordHash };
} catch (error) {
throw new Error('Failed to hash password: ' + error.message);
}`,
'import {createPasswordHash} from "%password-hasher-service";',
{ importMappers: [passwordHasherService] },
),
},
],
isAsync: true,
}),
});

Comment on lines +48 to +52
node.addPackages({
axios: '1.7.4',
'react-dropzone': '14.2.3',
'react-circular-progressbar': '2.1.0',
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Critical: Security vulnerability in [email protected]

The current axios version (1.7.4) contains a HIGH severity Server-Side Request Forgery vulnerability. Please update the dependencies:

  • axios: Update to 1.7.9 (fixes critical SSRF vulnerability)
  • react-dropzone: Update to 14.3.5 (latest version)
  • react-circular-progressbar: 2.1.0 (already at latest)
🔗 Analysis chain

Verify package versions for security updates.

The dependencies use fixed versions. Please verify:

  1. If these are the latest stable versions
  2. If there are any known security vulnerabilities
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for latest versions and security advisories
for pkg in "axios" "react-dropzone" "react-circular-progressbar"; do
  echo "Checking $pkg..."
  curl -s "https://registry.npmjs.org/$pkg" | jq -r '.["dist-tags"].latest'
  
  # Check for security advisories
  gh api graphql -f query="{
    securityVulnerabilities(first: 5, ecosystem: NPM, package: \"$pkg\") {
      nodes {
        advisory {
          summary
          severity
          publishedAt
        }
        vulnerableVersionRange
      }
    }
  }"
done

Length of output: 2483

Comment on lines +70 to +79
creator: (req) =>
new TypescriptCodeExpression(
`
{
get: (name) => ${req}.cookies[name],
set: (name, value, options) => void getReply().setCookie(name, value, options),
clear: (name) => void getReply().clearCookie(name),
}
`,
),
),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

'getReply()' is undefined in 'creator' function

The creator function uses getReply() but it is not defined in this scope, leading to a ReferenceError at runtime. The getReply() function is defined within the body function and is not accessible inside creator. Additionally, reply is not passed to the creator function.

To fix this issue, modify the creator function to accept reply as a parameter and adjust the code accordingly:

-creator: (req) =>
+creator: (req, reply) =>

{
  get: (name) => ${req}.cookies[name],
- set: (name, value, options) => void getReply().setCookie(name, value, options),
- clear: (name) => void getReply().clearCookie(name),
+ set: (name, value, options) => {
+   if (!reply) {
+     throw new Error(
+       'Reply is not defined. This may happen if calling this function from a websocket connection.'
+     );
+   }
+   reply.setCookie(name, value, options);
+ },
+ clear: (name) => {
+   if (!reply) {
+     throw new Error(
+       'Reply is not defined. This may happen if calling this function from a websocket connection.'
+     );
+   }
+   reply.clearCookie(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.

Suggested change
creator: (req) =>
new TypescriptCodeExpression(
`
{
get: (name) => ${req}.cookies[name],
set: (name, value, options) => void getReply().setCookie(name, value, options),
clear: (name) => void getReply().clearCookie(name),
}
`,
),
),
creator: (req, reply) =>
new TypescriptCodeExpression(
`
{
get: (name) => ${req}.cookies[name],
set: (name, value, options) => {
if (!reply) {
throw new Error(
'Reply is not defined. This may happen if calling this function from a websocket connection.'
);
}
reply.setCookie(name, value, options);
},
clear: (name) => {
if (!reply) {
throw new Error(
'Reply is not defined. This may happen if calling this function from a websocket connection.'
);
}
reply.clearCookie(name);
},
}
`,
),

Comment on lines +85 to +87
'%logger-service': {
path: '@/src/services/logger.js',
allowedImports: ['logger'],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update import paths to match the generated file extension

The import paths are using the .js extension, but the generated file is logger.ts. To ensure correct module resolution and consistency, please update the import paths to use the appropriate extension or omit it if your module resolution allows.

Apply this diff to fix the import paths:

85           '%logger-service': {
86-            path: '@/src/services/logger.js',
86+            path: '@/src/services/logger',
87             allowedImports: ['logger'],
          },

And update the import statement accordingly:

103-                  'import { logger } from "@/src/services/logger.js"',
103+                  'import { logger } from "@/src/services/logger"',

Also applies to: 103-104

Comment on lines +37 to +39
const prettierConfig = createNonOverwriteableMap<PrettierConfig>({
tabWidth,
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect tabWidth usage in task implementation

The tabWidth is used directly without being accessed from the descriptor.

   const prettierConfig = createNonOverwriteableMap<PrettierConfig>({
-    tabWidth,
+    tabWidth: descriptor.tabWidth,
   });
📝 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.

Suggested change
const prettierConfig = createNonOverwriteableMap<PrettierConfig>({
tabWidth,
});
const prettierConfig = createNonOverwriteableMap<PrettierConfig>({
tabWidth: descriptor.tabWidth,
});

Comment on lines +17 to +19
const descriptorSchema = z.object({
tabWidth: z.number().default(2),
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add missing imports and types.

The code is missing:

  1. The z import from 'zod'
  2. The PrettierConfig type definition or import

Add the following imports:

+import { z } from 'zod';
+import type { PrettierConfig } from './types';

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +67 to +69
await builder.apply(
typescript.renderBlockToAction(component, layoutPath),
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for component rendering

The component rendering process should include error handling for potential TypeScript rendering failures.

 await builder.apply(
-  typescript.renderBlockToAction(component, layoutPath),
+  typescript.renderBlockToAction(component, layoutPath).catch((error) => {
+    throw new Error(`Failed to render auth layout component: ${error.message}`);
+  }),
 );
📝 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.

Suggested change
await builder.apply(
typescript.renderBlockToAction(component, layoutPath),
);
await builder.apply(
typescript.renderBlockToAction(component, layoutPath).catch((error) => {
throw new Error(`Failed to render auth layout component: ${error.message}`);
}),
);

Comment on lines +75 to +81
const formatted = await prettier.format(sourceFile.getFullText(), {
...prettierConfig,
parser: 'typescript',
});
writeFileSync(sourceFile.getFilePath(), formatted, {
encoding: 'utf8',
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider handling Prettier formatting errors gracefully

The Prettier formatting is added without specific error handling. If formatting fails, it could prevent valid transformations from being saved.

Consider wrapping the formatting in a try-catch:

         if (!dryRun) {
-          const formatted = await prettier.format(sourceFile.getFullText(), {
-            ...prettierConfig,
-            parser: 'typescript',
-          });
-          writeFileSync(sourceFile.getFilePath(), formatted, {
-            encoding: 'utf8',
-          });
+          try {
+            const formatted = await prettier.format(sourceFile.getFullText(), {
+              ...prettierConfig,
+              parser: 'typescript',
+            });
+            writeFileSync(sourceFile.getFilePath(), formatted, {
+              encoding: 'utf8',
+            });
+          } catch (formatError) {
+            console.warn(`Failed to format ${sourceFile.getFilePath()}: ${formatError.message}`);
+            // Fall back to unformatted content
+            writeFileSync(sourceFile.getFilePath(), sourceFile.getFullText(), {
+              encoding: 'utf8',
+            });
+          }
📝 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.

Suggested change
const formatted = await prettier.format(sourceFile.getFullText(), {
...prettierConfig,
parser: 'typescript',
});
writeFileSync(sourceFile.getFilePath(), formatted, {
encoding: 'utf8',
});
if (!dryRun) {
try {
const formatted = await prettier.format(sourceFile.getFullText(), {
...prettierConfig,
parser: 'typescript',
});
writeFileSync(sourceFile.getFilePath(), formatted, {
encoding: 'utf8',
});
} catch (formatError) {
console.warn(`Failed to format ${sourceFile.getFilePath()}: ${formatError.message}`);
// Fall back to unformatted content
writeFileSync(sourceFile.getFilePath(), sourceFile.getFullText(), {
encoding: 'utf8',
});
}

Comment on lines +40 to +44

// load files from path
if (lstatSync(path).isDirectory()) {
project.addSourceFilesAtPaths(`${path}/**/*.ts`);
project.addSourceFilesAtPaths(`${path}/**/*.tsx`);
project.addSourceFilesAtPaths(sourceGlobs.map((glob) => `${path}/${glob}`));
} else {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Use path.join for cross-platform path handling

The review comment is valid. The codebase consistently uses path.join() for path concatenation across different files, but this instance deviates from that pattern. Using string template literals for path concatenation could cause issues on different platforms, particularly Windows.

  • packages/code-morph/src/runner.ts:43: Replace string template literal with path.join(path, glob) for consistent cross-platform behavior.
🔗 Analysis chain

Verify glob pattern handling across different platforms

The code concatenates path and glob patterns using string literals, which might cause issues on different platforms.

Consider using path.join for better cross-platform compatibility:

-    project.addSourceFilesAtPaths(sourceGlobs.map((glob) => `${path}/${glob}`));
+    project.addSourceFilesAtPaths(sourceGlobs.map((glob) => path.join(path, glob)));
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for Windows-style paths in the codebase
rg -l '\\\\' | grep -v 'test'

Length of output: 429


Script:

#!/bin/bash
# Check for path-related imports and usage
rg "import.*path.*from" -A 1
rg "path\.join|path\.resolve|path\.normalize" -A 1

Length of output: 36707

@coderabbitai
Copy link

coderabbitai bot commented Jan 10, 2025

✅ Actions performed

Reviews paused.

@kingston kingston merged commit b18263c into main Jan 11, 2025
4 checks passed
@kingston kingston deleted the kingston/eng-532-deprecate-creategeneratorwithchildren branch January 11, 2025 08:04
@github-actions github-actions bot mentioned this pull request Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants