Skip to content

refactor: move ambient const enums into real modules#6089

Open
edusperoni wants to merge 2 commits into
NativeScript:mainfrom
edusperoni:refactor/const-enums
Open

refactor: move ambient const enums into real modules#6089
edusperoni wants to merge 2 commits into
NativeScript:mainfrom
edusperoni:refactor/const-enums

Conversation

@edusperoni

@edusperoni edusperoni commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

PR Checklist

  • The PR title follows our guidelines.
  • There is an issue for the bug/feature this PR is for. (no tracking issue — happy to open one)
  • You have signed the CLA.
  • All existing tests are passing (1513 passing, unchanged).
  • Tests for the changes are included. (behaviour-preserving refactor, covered by the existing suite)

What is the current behavior?

Twelve const enums are declared inside ambient .d.ts files and used in value positions, for example process.exit(ErrorCodes.UNHANDLED_REJECTION_FAILURE).

That only works because TypeScript has whole-program type information: it inlines the constant at compile time and erases the import entirely. declarations.d.ts produces no runtime module, so there is nothing to import at runtime.

Any file-local transpiler — esbuild, swc, tsx, vite, bun — cannot inline them. It leaves the import in place and resolution fails:

Error: Cannot find module './declarations' imported from lib/common/errors.ts

This makes the sources impossible to run through anything other than a full tsc pass, and it is also what isolatedModules disallows.

What is the new behavior?

The twelve ambient const enums now live in real modules:

  • the five in lib/common/declarations.d.ts → new lib/common/enums.ts
  • BuildNameslib/constants.ts, alongside the other build-related enums
  • detached-process-enums, system-warnings and google-analytics-custom-dimensions.d.ts renamed to .ts; they contained nothing but enums
  • SpecialKeyskey-commands.d.ts renamed to .ts, which already exported everything, so importers are unchanged

Four of those files were global ambient declarations with no imports, which is why their enums were visible everywhere without being imported. Consumers now import them explicitly.

Two incidental changes fall out of this:

  • GoogleAnalyticsCrossClientCustomDimensions is referenced nowhere. It is dropped rather than converted into a dead runtime module.
  • Renaming key-commands.d.ts to .ts surfaced two interface methods with no return type annotation, which an ambient context had allowed to be implicitly any. Both implementations return nothing, so they are annotated void.

tsc --noEmit is clean and the suite is unchanged at 1513 passing. Note that the .d.ts files here are hand-written rather than generated (declaration: false), but the package declares no types/typings entry and ships no lib/nativescript-cli-lib.d.ts, so they are not a consumable public type surface.

Summary by CodeRabbit

  • Bug Fixes

    • Improved cleanup request handling to correctly identify and remove registered requests.
  • Enhancements

    • Improved support for organizing iOS project targets under optional parent targets.
    • Standardized warning severity handling for clearer system and macOS diagnostics.
  • Refactor

    • Consolidated shared enums and updated internal references without changing command behavior.
    • Improved consistency across analytics, testing, cleanup, and build workflows.

Follow-up commit: enable isolatedModules

Moving these enums out of the ambient files removed the last blocker, so the flag is turned on in the same PR:

tsc --noEmit --isolatedModules
main 244 errors (all TS2748: Cannot access ambient const enums)
this branch 0

This part is not emit-neutral, so review it as a runtime change rather than a type-only one. With isolatedModules on, tsc stops inlining const enums: 33 emitted files change, consumers move from a baked-in literal to a property lookup, and lib/constants.js now emits ShouldMigrate, NativePlatformStatus, DebugTools, TrackActionNames, BuildStates and PlatformTypes as runtime objects.

Values are unchanged (verified at runtime), the suite is unchanged at 1513 passing, and the CLI still reports its version and renders the full help.

Arguably that convergence is the point: oxc and esbuild cannot inline a cross-file const enum, so today tsc's output disagrees with every other transpiler's for exactly those six enums. Now they agree.

It also makes the const modifier on the ten remaining declarations decorative, since it no longer buys inlining — converting them to plain enum is a sensible follow-up.

Happy to split this commit into its own PR stacked on this one if you would rather keep this change purely a refactor.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This change extracts shared enums into runtime-exported modules, updates imports and declaration formatting across CLI services, adds optional iOS target parenting, adjusts cleanup request handling, and aligns analytics and system-warning tests with the new enum locations.

Changes

Enum and contract migration

Layer / File(s) Summary
Shared enum definitions
lib/common/enums.ts, lib/constants.ts, lib/definitions/system-warnings.ts, lib/detached-processes/detached-process-enums.ts
Adds shared runtime enums and relocates existing build, warning, analytics, option, error, and detached-process values from ambient declarations.
Import and declaration updates
lib/commands/*, lib/services/*, lib/helpers/*, lib/common/declarations.d.ts
Updates consumers to import enums from their new modules and standardizes multiline signatures and trailing commas.
Cleanup and iOS target behavior
lib/detached-processes/cleanup-process.ts, lib/services/ios-native-target-service.ts
Changes cleanup request existence checking and adds an optional parent target to iOS project target creation.
Test alignment
test/options.ts, test/services/analytics/analytics-service.ts, test/sys-info.ts
Updates imports, mocks, setup arguments, emitted process messages, and warning severity values.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: nathanwalker

Poem

I hop through enums, neat and bright,
New imports guide the code just right.
A parent target joins the tree,
Cleanup checks what it should see.
Tests hum softly, green and true—
A rabbit’s cheer for work well through!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: moving ambient const enums into real modules.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/detached-processes/cleanup-process.ts`:
- Around line 229-249: Update the existence check in removeRequest to compare
each queued currentRequestInfo with the removal requestInfo, matching the
comparison already used by _.remove. Preserve the existing success and
absent-request logging behavior based on whether that matching request is
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c7665e5c-a52a-47d9-aa0e-dfd95c8fc810

📥 Commits

Reviewing files that changed from the base of the PR and between 1084bc7 and 10ebf46.

📒 Files selected for processing (38)
  • lib/commands/build.ts
  • lib/commands/debug.ts
  • lib/commands/deploy.ts
  • lib/commands/prepare.ts
  • lib/commands/test.ts
  • lib/common/declarations.d.ts
  • lib/common/definitions/key-commands.ts
  • lib/common/enums.ts
  • lib/common/errors.ts
  • lib/common/services/analytics/google-analytics-custom-dimensions.ts
  • lib/common/services/cancellation.ts
  • lib/common/services/commands-service.ts
  • lib/common/verify-node-version.ts
  • lib/constants.ts
  • lib/definitions/project.d.ts
  • lib/definitions/system-warnings.d.ts
  • lib/definitions/system-warnings.ts
  • lib/detached-processes/cleanup-js-subprocess.ts
  • lib/detached-processes/cleanup-process.ts
  • lib/detached-processes/detached-process-enums.ts
  • lib/detached-processes/file-log-service.ts
  • lib/helpers/livesync-command-helper.ts
  • lib/helpers/options-track-helper.ts
  • lib/nativescript-cli.ts
  • lib/options.ts
  • lib/services/analytics/analytics-broker-process.ts
  • lib/services/analytics/analytics-broker.ts
  • lib/services/analytics/analytics-service.ts
  • lib/services/analytics/google-analytics-cross-client-custom-dimensions.d.ts
  • lib/services/analytics/google-analytics-provider.ts
  • lib/services/cleanup-service.ts
  • lib/services/initialize-service.ts
  • lib/services/ios-native-target-service.ts
  • lib/services/test-execution-service.ts
  • lib/sys-info.ts
  • test/options.ts
  • test/services/analytics/analytics-service.ts
  • test/sys-info.ts
💤 Files with no reviewable changes (2)
  • lib/services/analytics/google-analytics-cross-client-custom-dimensions.d.ts
  • lib/definitions/system-warnings.d.ts

Comment thread lib/detached-processes/cleanup-process.ts
TypeScript inlines `const enum` values at compile time and erases the
import, so declaring them in .d.ts files worked only because tsc has
whole-program type information. Any file-local transpiler (esbuild, swc,
tsx, vite, bun) cannot inline them and fails to resolve the import, which
blocks running the sources without a full tsc pass.

The 12 ambient const enums now live in real modules:

- 5 from lib/common/declarations.d.ts  -> lib/common/enums.ts
- BuildNames                           -> lib/constants.ts, next to the
                                          other build-related enums
- detached-process-enums, system-warnings and
  google-analytics-custom-dimensions   -> .d.ts renamed to .ts; they held
                                          nothing but enums
- SpecialKeys                          -> key-commands.d.ts renamed to .ts,
                                          which already exported everything,
                                          so importers are unchanged

The four global files had no imports, making their enums globally visible;
consumers now import them explicitly.

GoogleAnalyticsCrossClientCustomDimensions is referenced nowhere and was
dropped rather than converted into a dead runtime module.

Renaming key-commands to .ts surfaced two interface methods whose missing
return types an ambient context had allowed; both implementations return
nothing, so they are annotated void.
Moving the ambient const enums into real modules removed the last thing
standing in the way: tsc --noEmit --isolatedModules reports 244 errors on
main (all TS2748, 'Cannot access ambient const enums') and none once they
are real modules.

This is not emit-neutral. With isolatedModules on, tsc stops inlining const
enums and emits them as runtime objects, so 33 files change: consumers go
from a baked-in literal to a property lookup, and lib/constants.js now emits
ShouldMigrate, NativePlatformStatus, DebugTools, TrackActionNames,
BuildStates and PlatformTypes. The values are unchanged - verified at
runtime - and the suite is unchanged at 1513 passing, with the CLI still
rendering help and reporting its version.

That change is arguably the point. oxc and esbuild cannot inline a const
enum across files, so today tsc's output and every other transpiler's output
disagree for exactly those six. Now they agree.

It also means the const modifier on the remaining ten declarations no longer
buys inlining, so it is decorative; converting them to plain enum is a
sensible follow-up.
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.

1 participant