Skip to content

Conversation

@ChiragAgg5k
Copy link
Member

@ChiragAgg5k ChiragAgg5k commented Nov 18, 2025

Summary

This PR fixes how enums are rendered across all SDK templates by ensuring that parameter.enumName is always set at the source level, eliminating the need for fallback checks throughout the templates.

Problem

Previously, enums were rendering incorrectly in generated SDK documentation and code examples. For instance:

  • Before: .light, .africaAbidjan, .jpg (missing enum class prefix)
  • After: Theme.light, Timezone.africaAbidjan, Output.jpg

This occurred because parameter.enumName could be empty/null when x-enum-name wasn't explicitly set in the OpenAPI specification, causing templates to output incomplete enum references.

Solution

Instead of having fallback logic scattered across 15+ template files with patterns like:

{% if parameter.enumName is not empty %}
{% set name = parameter.enumName %}
{% else %}
{% set name = parameter.name %}
{% endif %}

This PR centralizes the fallback logic in the source (src/Spec/Swagger2.php) where parameters are parsed:

$param['enumName'] = $parameter['x-enum-name'] ?? $param['name'];

Changes Made

Core Fix

  • src/Spec/Swagger2.php (lines 232, 271): Added fallback to ensure enumName always has a value

Template Cleanup (16 files)

Removed fallback hacks from all templates:

Documentation Examples:

  • templates/dart/docs/example.md.twig
  • templates/flutter/docs/example.md.twig
  • templates/python/docs/example.md.twig
  • templates/php/docs/example.md.twig
  • templates/kotlin/docs/kotlin/example.md.twig
  • templates/kotlin/docs/java/example.md.twig
  • templates/android/docs/kotlin/example.md.twig
  • templates/android/docs/java/example.md.twig

Service/SDK Templates:

  • templates/php/src/Services/Service.php.twig
  • templates/python/package/services/service.py.twig
  • templates/kotlin/src/main/kotlin/io/appwrite/models/Model.kt.twig
  • templates/web/src/services/template.ts.twig
  • templates/react-native/src/services/template.ts.twig
  • templates/node/src/services/template.ts.twig
  • templates/deno/src/services/service.ts.twig

Verification

Generated examples now correctly render enums across all SDKs:

  • Dart: Theme.light, Timezone.africaAbidjan, Output.jpg
  • Flutter: Theme.light, Timezone.africaAbidjan, Output.jpg
  • Python: theme.LIGHT, timezone.AFRICA_ABIDJAN, output.JPG
  • PHP: Theme::LIGHT(), Timezone::AFRICAABIDJAN(), Output::JPG()
  • Kotlin/Android: Proper enum class references
  • TypeScript (Web/Node/React Native/Deno): Proper enum imports and usage

Impact

  • Code Quality: Cleaner, more maintainable templates
  • DRY Principle: Single source of truth for enum name fallback logic
  • Bug Fix: Resolves incorrect enum rendering across all SDKs
  • No Breaking Changes: Only affects generated documentation/examples, not SDK functionality

Test Plan

  • Regenerated Dart examples - enums render correctly
  • Regenerated Flutter examples - enums render correctly
  • Regenerated Python examples - enums render correctly
  • Regenerated PHP examples - enums render correctly
  • Verified all template fallback patterns removed

Summary by CodeRabbit

  • Refactor
    • Streamlined enum handling in code generators to consistently use enumName values, removing fallback logic and simplifying how enum types are imported across multiple language templates.

This commit fixes how enums are rendered across all SDK templates by
ensuring that parameter.enumName is always set at the source level,
eliminating the need for fallback checks throughout the templates.

Changes:
- Fixed src/Spec/Swagger2.php to always set enumName with fallback to parameter name
- Removed enumName fallback pattern from 15 template files across all SDKs
- Simplified enum import logic in service templates
- Updated example templates to use enumName directly

Previously, enums were rendering incorrectly (e.g., ".light" instead of "Theme.light")
because enumName could be empty when x-enum-name wasn't set in the OpenAPI spec.

Now all SDKs correctly generate:
- Dart/Flutter: Theme.light, Timezone.africaAbidjan, Output.jpg
- Python: theme.LIGHT, timezone.AFRICA_ABIDJAN, output.JPG
- PHP: Theme::LIGHT(), Timezone::AFRICAABIDJAN(), Output::JPG()
- Kotlin/Android: Proper enum class references

Affected templates:
- Dart, Flutter, Python, PHP, Kotlin, Android, Web, React Native, Node, Deno
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Warning

Rate limit exceeded

@ChiragAgg5k has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 55 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between d552c63 and 3f39061.

📒 Files selected for processing (10)
  • templates/android/docs/java/example.md.twig (2 hunks)
  • templates/android/docs/kotlin/example.md.twig (2 hunks)
  • templates/dotnet/docs/example.md.twig (1 hunks)
  • templates/kotlin/docs/java/example.md.twig (2 hunks)
  • templates/kotlin/docs/kotlin/example.md.twig (2 hunks)
  • templates/node/docs/example.md.twig (1 hunks)
  • templates/python/docs/example.md.twig (2 hunks)
  • templates/react-native/docs/example.md.twig (1 hunks)
  • templates/ruby/docs/example.md.twig (1 hunks)
  • templates/web/docs/example.md.twig (1 hunks)

Walkthrough

This PR refactors enum handling across the codebase by introducing a consistent use of parameter.enumName throughout multiple language templates and the Swagger2 parser. The PHP source file adds a null-coalescing fallback to ensure enumName always has a value (either from x-enum-name or the parameter name itself). Correspondingly, multiple template files simplify their enum import and usage logic to rely directly on parameter.enumName instead of computing intermediate names from either parameter.enumName or parameter.name. This affects code generation for Java, Kotlin, Dart, Deno, Flutter, Node.js, PHP, Python, and React Native templates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Multiple heterogeneous template files: Changes span 15+ files across different language targets (Java, Kotlin, Dart, Deno, Flutter, Node, PHP, Python, React Native, Web), each requiring language-specific context verification
  • Repetitive refactoring pattern: While the underlying logic change is consistent (removing intermediate name derivation and using parameter.enumName directly), the same pattern is applied across numerous files rather than a single centralized location
  • Potential regression risk: Several summaries flag that the new logic removes fallbacks to parameter.name; if parameter.enumName is ever empty or undefined, this could generate invalid code
  • Interdependency concern: The Swagger2.php change (introducing the null-coalescing fallback) is foundational; ensure it consistently populates enumName for all scenarios that the templates now depend on
  • Language-specific verification: Each template language may have different naming conventions and import patterns that require separate validation

Areas requiring extra attention:

  • Verify that parameter.enumName is never empty/null in any code path that reaches these simplified templates
  • Confirm the null-coalescing fallback in src/Spec/Swagger2.php covers all parameter scenarios (regular parameters and body properties)
  • Test code generation output for each language target to ensure no malformed enum imports or references are produced
  • Check if any existing tests cover the scenarios where enumName would be missing (and confirm they still pass or are updated appropriately)

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main change: fixing enum rendering by centralizing enumName assignment and removing template-level fallback logic.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
templates/python/docs/example.md.twig (1)

6-13: Fix incorrect condition preventing enum imports in Python example

Line 8 uses {% if method == parameter.required %}, which compares an object to a boolean and will never be true. This blocks the entire enum import block from executing, causing generated Python examples to omit required enum imports.

Change to:

{% if parameter.required %}

This same bug appears in multiple templates (ruby, kotlin, android) and should be fixed everywhere it occurs.

templates/kotlin/docs/java/example.md.twig (1)

7-14: The enum import guard condition is indeed wrong and prevents imports from being emitted

Your review correctly identifies a critical logic error: the condition {% if method == parameter.required %} at line 9 compares the method object to a boolean, which is always false and prevents this block from executing.

The same problematic condition exists in:

  • templates/kotlin/docs/kotlin/example.md.twig:9
  • templates/python/docs/example.md.twig:8
  • templates/ruby/docs/example.md.twig:7
  • templates/android/docs/kotlin/example.md.twig:9
  • templates/android/docs/java/example.md.twig:9

The enumName usage itself is correct (line 12 imports via parameter.enumName), but the wrapping guard prevents it from ever running. Change to {% if parameter.required %} to fix.

🧹 Nitpick comments (2)
templates/kotlin/src/main/kotlin/io/appwrite/models/Model.kt.twig (1)

5-8: Enum imports now correctly rely on property.enumName

Using property.enumName | caseUcfirst for the Kotlin enum import matches how enumName is populated in Swagger2::getDefinitions, so templates can rely on a single source of truth. You might optionally dedupe repeated imports across properties later, but the current change is sound.

src/Spec/Swagger2.php (1)

209-235: Centralizing enumName fallback in parseMethod is correct and matches existing enum derivation

Setting:

$param['enumName'] = $parameter['x-enum-name'] ?? $param['name'];
...
$temp['enumName'] = $value['x-enum-name'] ?? $temp['name'];

ensures all enum-bearing request parameters and body properties have a non-empty enumName that templates can safely consume. This matches the previous effective behaviour in getRequestEnums (enumName or fallback to name), but moves the logic to parsing time so templates no longer need per-file fallbacks.

getRequestEnums() still does $enumName = $parameter['enumName'] ?? $parameter['name'];, which is now redundant but not incorrect; you could simplify that later if desired.

Also applies to: 253-279

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 991858e and d552c63.

📒 Files selected for processing (16)
  • src/Spec/Swagger2.php (2 hunks)
  • templates/android/docs/java/example.md.twig (2 hunks)
  • templates/android/docs/kotlin/example.md.twig (2 hunks)
  • templates/dart/docs/example.md.twig (1 hunks)
  • templates/deno/src/services/service.ts.twig (1 hunks)
  • templates/flutter/docs/example.md.twig (3 hunks)
  • templates/kotlin/docs/java/example.md.twig (1 hunks)
  • templates/kotlin/docs/kotlin/example.md.twig (1 hunks)
  • templates/kotlin/src/main/kotlin/io/appwrite/models/Model.kt.twig (1 hunks)
  • templates/node/src/services/template.ts.twig (1 hunks)
  • templates/php/docs/example.md.twig (2 hunks)
  • templates/php/src/Services/Service.php.twig (1 hunks)
  • templates/python/docs/example.md.twig (1 hunks)
  • templates/python/package/services/service.py.twig (1 hunks)
  • templates/react-native/src/services/template.ts.twig (1 hunks)
  • templates/web/src/services/template.ts.twig (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: build (8.3, Python310)
  • GitHub Check: build (8.3, Python313)
  • GitHub Check: build (8.3, AppleSwift56)
  • GitHub Check: build (8.3, Ruby30)
  • GitHub Check: build (8.3, WebChromium)
  • GitHub Check: build (8.3, Python311)
  • GitHub Check: build (8.3, Ruby31)
  • GitHub Check: build (8.3, PHP80)
  • GitHub Check: build (8.3, PHP83)
  • GitHub Check: build (8.3, Node16)
  • GitHub Check: build (8.3, KotlinJava8)
  • GitHub Check: build (8.3, FlutterBeta)
  • GitHub Check: build (8.3, FlutterStable)
  • GitHub Check: build (8.3, DartStable)
  • GitHub Check: build (8.3, Android5Java17)
  • GitHub Check: build (8.3, Android14Java17)
  • GitHub Check: swift (server)
  • GitHub Check: apple (client)
  • GitHub Check: android (client)
🔇 Additional comments (14)
templates/php/src/Services/Service.php.twig (1)

9-16: PHP enum imports correctly centralized on parameter.enumName

Using parameter.enumName for both the added check and the imported class (Enums\{{ parameter.enumName | caseUcfirst }}) matches the new parser behaviour and keeps the enum-name logic in one place. This should preserve behaviour while simplifying the template.

templates/node/src/services/template.ts.twig (1)

4-10: Node service enum imports now consistently use parameter.enumName

The new block:

{% if parameter.enumName not in added %}
import { {{ parameter.enumName | caseUcfirst }} } from '../enums/{{ parameter.enumName | caseKebab }}';
{% set added = added|merge([parameter.enumName]) %}
{% endif %}

is aligned with the parser’s enumName fallback and keeps enum import naming consistent across the Node SDK. Looks good.

templates/flutter/docs/example.md.twig (1)

24-28: Flutter examples now correctly reference enums via parameter.enumName

Routing enum arguments through {{ parameter.enumName | caseUcfirst | overrideIdentifier }}.{{ ... | caseEnumKey }} aligns the examples with the actual generated Flutter enums and fixes the bare .value-style output. This change is consistent with the new enumName handling in the spec parser.

Also applies to: 34-38, 48-52

templates/react-native/src/services/template.ts.twig (1)

8-15: React Native service enum imports aligned with centralized enumName handling

The new enum import block that uses parameter.enumName for deduplication, path (caseKebab), and symbol (caseUcfirst) matches the Node service template and the parser’s enumName semantics. This keeps enum handling consistent across TS targets.

templates/python/package/services/service.py.twig (1)

13-15: Enum import simplification aligns with broader refactor.

The removal of fallback logic is consistent with the centralized approach. Ensure the upstream Swagger2.php change guarantees enumName is never empty to prevent invalid imports like from ..enums. import .

templates/web/src/services/template.ts.twig (1)

9-11: TypeScript enum import refactor looks good.

The simplified logic correctly relies on parameter.enumName being consistently populated upstream. Confirm that all OpenAPI parsing paths in Swagger2.php set this field to avoid missing enum imports.

templates/android/docs/kotlin/example.md.twig (2)

11-13: Android Kotlin enum imports simplified correctly.

Direct parameter.enumName usage aligns with the broader refactor. Verify the Swagger2.php fallback ensures this field is always populated.


41-41: Enum reference updated consistently.

The parameter assignment correctly uses parameter.enumName directly, matching the import changes.

templates/deno/src/services/service.ts.twig (1)

39-41: Deno enum import handling simplified appropriately.

The change aligns with the centralized enumName approach across all platforms. Ensure upstream parsing always populates enumName.

templates/php/docs/example.md.twig (2)

11-13: PHP enum import logic correctly simplified.

The removal of fallback logic is appropriate given the centralized fix. Verify that parameter.enumName is always set by the parser.


37-37: Enum parameter rendering updated consistently.

Direct use of parameter.enumName matches the import changes.

templates/dart/docs/example.md.twig (1)

25-25: Dart enum reference simplified correctly.

The direct use of parameter.enumName is consistent with the broader refactor. Verify upstream parsing ensures this field is never empty.

templates/android/docs/java/example.md.twig (2)

11-13: Android Java enum imports refactored appropriately.

The simplified logic correctly assumes parameter.enumName is consistently populated. Confirm the Swagger2.php changes are in place.


45-46: Enum parameter usage updated consistently.

Direct parameter.enumName reference matches the import simplification.

@abnegate abnegate merged commit dc6720b into master Nov 18, 2025
52 checks passed
@abnegate abnegate deleted the fix-enum-rendering branch November 18, 2025 05:57
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.

3 participants