feat(commands): defineCommand — typed declarative commands via an ICommand adapter - #6101
Draft
edusperoni wants to merge 5 commits into
Draft
feat(commands): defineCommand — typed declarative commands via an ICommand adapter#6101edusperoni wants to merge 5 commits into
edusperoni wants to merge 5 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
5 tasks
edusperoni
force-pushed
the
feat/define-command
branch
3 times, most recently
from
July 30, 2026 02:27
74caa8f to
cafa737
Compare
…adapter Commands can now be declared as plain objects: a name, an option schema built from booleanOption/stringOption/numberOption/arrayOption, and a run function whose context carries the positional args plus the declared options, typed by inference from the schema. lib/common/define-command holds the types and the pure factories only, so it stays side-effect-free and can be re-exported from nativescript/contracts. The runtime bridge lives in lib/common/services/command-definition-adapter, which compiles a definition into the ICommand the legacy registry expects and runs it inside an injection context. canExecute is emitted only when the definition supplies one or opts into arguments: "any"; CommandsService skips all parameter validation as soon as canExecute exists, so omitting it is what lets the framework reject stray positional arguments for arguments: "none". Fully additive — existing ICommand classes are untouched.
…nitions A definition with no declared options must be executable in a container that has no options service registered - manifest-loaded extension commands run in exactly that situation.
The parent-dispatcher leak onto the module-level injector is fixed in the base branch, so the round-trip test no longer needs the global facade.
Yok extends Injector on the base branch; the di bridge is gone.
edusperoni
force-pushed
the
feat/define-command
branch
from
July 30, 2026 02:51
cafa737 to
a1ba0ef
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
What is the current behavior?
A command is a class implementing
ICommand, registered under a stringly-typed key, reading flags off the untyped global$optionsobject. The validation semantics carry a trap: declaringcanExecutesilently disablesallowedParametersvalidation, and an emptyallowedParametersmeans "reject all positional arguments" — none of which the types express.What is the new behavior?
defineCommand— a declarative, typed command definition that plugs into the existing registry through an adapter (createCommandFromDefinition/registerCommandDefinition). Fully additive: routing, validation, help, hooks, and analytics behavior are untouched, and legacyICommandclasses remain fully supported.dashedOptions, riding the CLI's existing option validation (declared flags accepted; unknown flags hard-fail with help, exactly as today).ctx.optionsis a typed view with real inference (pinned by an exactness type test, not a strict-off-friendly assignment).canExecutetrap is handled explicitly and documented as a constraint in the adapter:arguments: "none"(default) omitscanExecuteso the framework's own no-parameters validation applies;arguments: "any"or a usercanExecutetakes validation ownership wholesale.runexecutes in an injection context, soinject()works inside commands the same as everywhere else.lib/common/define-command.tsis side-effect-free and exported fromnativescript/contracts; definitions carry aSymbol.formarker so duplicated CLI copies interoperate.CommandsService.tryExecuteCommand.defining-commands.md.Two pre-existing registry quirks surfaced while testing, unchanged by this PR and worth their own issues: the synthesized hierarchical parent registers via the module-level global injector rather than the instance it was called on, and
registerCommandalone never populateshierarchicalCommandsrouting state (onlyrequireCommanddoes).Full suite: 110 files, 1616 passed / 38 skipped; yok oracle, public-API test, and compat fixtures untouched.