Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(API): Update the functionality by which slugs are generated for entities #419

Closed
wants to merge 2 commits into from

Conversation

Nil2000
Copy link
Contributor

@Nil2000 Nil2000 commented Sep 10, 2024

User description

Description

Updated keyshade/apps/api/src/common/slug-generator.ts as per mentioned in the issue

Fixes #416

Dependencies

Mention any dependencies/packages used

Future Improvements

Mention any improvements to be done in future related to any file/feature

Mentions

Mention and tag the people

Screenshots of relevant screens

Add screenshots of relevant screens

Developer's checklist

  • My PR follows the style guidelines of this project
  • I have performed a self-check on my work

If changes are made in the code:

  • I have followed the coding guidelines
  • My changes in code generate no new warnings
  • My changes are breaking another fix/feature of the project
  • I have added test cases to show that my feature works
  • I have added relevant screenshots in my PR
  • There are no UI/UX issues

Documentation Update

  • This PR requires an update to the documentation at docs.keyshade.xyz
  • I have made the necessary updates to the documentation, or no documentation changes are required.

PR Type

enhancement, bug_fix


Description

  • Updated the generateSlug function to include a counter, ensuring unique slugs by incrementing the counter if a slug already exists.
  • Refined error messages in the API key service to improve clarity by using apiKeySlug instead of apiKeyId.
  • Enhanced the slug generation logic for various entity types, ensuring better uniqueness and collision handling.

Changes walkthrough 📝

Relevant files
Bug fix
api-key.service.ts
Refine error messages in API key service                                 

apps/api/src/api-key/service/api-key.service.ts

  • Updated error messages to use apiKeySlug instead of apiKeyId.
  • Improved clarity of error handling in API key operations.
  • +3/-3     
    Enhancement
    slug-generator.ts
    Enhance slug generation with counter mechanism                     

    apps/api/src/common/slug-generator.ts

  • Modified generateSlug function to include a counter for uniqueness.
  • Implemented a loop to increment the counter if a slug exists.
  • Enhanced slug generation logic for various entity types.
  • +12/-3   

    💡 PR-Agent usage:
    Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Key issues to review

    Potential Performance Issue
    The while loop for generating unique slugs might run indefinitely if there's a high collision rate. Consider adding a maximum retry limit.

    Code Duplication
    The switch statement contains repetitive code for each entity type. Consider refactoring to reduce duplication.

    Copy link
    Contributor

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Possible bug
    Reorder operations to prevent potential null reference errors

    Consider moving the apiKey.id assignment after the null check to avoid potential
    runtime errors if apiKey is null.

    apps/api/src/api-key/service/api-key.service.ts [88-97]

     const apiKey = await this.prisma.apiKey.findUnique({
       where: {
         slug: apiKeySlug
       }
     })
    -const apiKeyId = apiKey.id
     
     if (!apiKey) {
       throw new NotFoundException(`API key ${apiKeySlug} not found`)
     }
     
    +const apiKeyId = apiKey.id
    +
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: The suggestion addresses a potential runtime error by ensuring that apiKey is not null before accessing its id property, which is a crucial fix for preventing application crashes.

    9
    Performance
    Optimize the slug generation and uniqueness check process

    Consider implementing a more efficient approach to handle slug generation and
    uniqueness checks, such as using a database transaction or a more optimized loop
    structure.

    apps/api/src/common/slug-generator.ts [92-157]

     export default async function generateEntitySlug(
       name: string,
    -  entityType:
    -    | 'WORKSPACE_ROLE'
    -    | 'WORKSPACE'
    -    | 'PROJECT'
    -    | 'VARIABLE'
    -    | 'SECRET'
    -    | 'INTEGRATION'
    -    | 'ENVIRONMENT'
    -    | 'API_KEY',
    +  entityType: 'WORKSPACE_ROLE' | 'WORKSPACE' | 'PROJECT' | 'VARIABLE' | 'SECRET' | 'INTEGRATION' | 'ENVIRONMENT' | 'API_KEY',
       prisma: PrismaService
     ): Promise<string> {
    -  let counter=0
    -  while (true) {
    -    const slug = generateSlug(name,counter)
    -    switch (entityType) {
    -      case 'WORKSPACE_ROLE':
    -        if (await checkWorkspaceRoleSlugExists(slug, prisma)) {
    -          counter++
    -          continue
    -        }
    -        return slug
    -      case 'WORKSPACE':
    -        if (await checkWorkspaceSlugExists(slug, prisma)) {
    -          counter++
    -          continue
    -        }
    -        return slug
    -      // ... other cases
    -    }
    -  }
    +  const checkSlugExists = getSlugExistenceChecker(entityType, prisma);
    +  let counter = 0;
    +  let slug: string;
    +
    +  do {
    +    slug = generateSlug(name, counter);
    +    counter++;
    +  } while (await checkSlugExists(slug));
    +
    +  return slug;
     }
     
    +function getSlugExistenceChecker(entityType: string, prisma: PrismaService) {
    +  const checkers = {
    +    'WORKSPACE_ROLE': checkWorkspaceRoleSlugExists,
    +    'WORKSPACE': checkWorkspaceSlugExists,
    +    // ... other entity types
    +  };
    +  return checkers[entityType] || (() => false);
    +}
    +
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: The suggestion optimizes the slug generation process by reducing repetitive code and improving performance, which is beneficial for scalability and maintainability.

    8
    Enhancement
    Enhance slug uniqueness by incorporating a timestamp

    Consider using a more robust method for generating unique slugs, such as
    incorporating a timestamp or a UUID, to reduce the likelihood of collisions.

    apps/api/src/common/slug-generator.ts [11-24]

    -const generateSlug = (name: string,counter:number): string => {
    -  // Convert to lowercase
    +const generateSlug = (name: string, counter: number): string => {
       const lowerCaseName = name.trim().toLowerCase()
    -
    -  // Replace spaces with hyphens
       const hyphenatedName = lowerCaseName.replace(/\s+/g, '-')
    -
    -  // Replace all non-alphanumeric characters with hyphens
       const alphanumericName = hyphenatedName.replace(/[^a-zA-Z0-9-]/g, '-')
    -
    -  // Append the name with 5 alphanumeric characters
    -  const slug =
    -    alphanumericName + '-' + counter.toString(36)
    +  const timestamp = Date.now().toString(36)
    +  const slug = `${alphanumericName}-${timestamp}-${counter.toString(36)}`
       return slug
     }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Incorporating a timestamp enhances the uniqueness of slugs, reducing collision risk, which is a valuable improvement for ensuring data integrity.

    7
    Best practice
    Implement a maximum length limit for generated slugs

    Consider adding a maximum length limit to the generated slug to ensure it doesn't
    exceed database or URL length restrictions.

    apps/api/src/common/slug-generator.ts [11-24]

    -const generateSlug = (name: string,counter:number): string => {
    -  // Convert to lowercase
    +const MAX_SLUG_LENGTH = 100; // Adjust as needed
    +
    +const generateSlug = (name: string, counter: number): string => {
       const lowerCaseName = name.trim().toLowerCase()
    -
    -  // Replace spaces with hyphens
       const hyphenatedName = lowerCaseName.replace(/\s+/g, '-')
    -
    -  // Replace all non-alphanumeric characters with hyphens
       const alphanumericName = hyphenatedName.replace(/[^a-zA-Z0-9-]/g, '-')
    -
    -  // Append the name with 5 alphanumeric characters
    -  const slug =
    -    alphanumericName + '-' + counter.toString(36)
    -  return slug
    +  const counterSuffix = '-' + counter.toString(36)
    +  const truncatedName = alphanumericName.slice(0, MAX_SLUG_LENGTH - counterSuffix.length)
    +  return truncatedName + counterSuffix
     }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    Why: Adding a maximum length limit is a good practice to prevent potential issues with database or URL length restrictions, improving code robustness.

    6

    @Nil2000 Nil2000 closed this Sep 10, 2024
    @Nil2000 Nil2000 deleted the nilabhra-branch branch September 10, 2024 08:04
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    API: Update the functionality by which slugs are generated for entities
    1 participant