You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: lead with the typed API for hooks and demote string tokens
extending-cli.md's in-process section now opens with the recommended
hook pattern (hookArgs parameter + $injector.di.get(Token)) and moves
parameter-name injection into a labeled legacy section. String-token
lookups are framed as the migration bridge throughout, not a co-equal
API.
Copy file name to clipboardExpand all lines: extending-cli.md
+36-31Lines changed: 36 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -77,15 +77,34 @@ Execute Hooks In-Process
77
77
78
78
When your hook is a Node.js script, the CLI executes it in-process. This gives you access to the entire internal state of the CLI and all of its functions.
79
79
80
-
The CLI assumes that this is a CommonJS module and calls its single exported function with four parameters. The type of the parameters is described in the `.d.ts` files which are part of the CLI source code [here](https://github.com/NativeScript/nativescript-cli/tree/master/lib/definitions) and [here](https://github.com/telerik/mobile-cli-lib/tree/master/definitions).
80
+
The CLI assumes that this is a CommonJS module and calls its single exported function.
81
+
82
+
## Writing a hook
83
+
84
+
Declare a `hookArgs` parameter if you need the payload of the operation being hooked, and resolve CLI services through the typed injection API: `global.$injector.di` is the CLI's container, and the `nativescript/contracts` subpath exports its tokens. See [dependency-injection.md](dependency-injection.md) for the full API.
const logger = di.get("logger"); // no typed token yet — registry name
94
+
95
+
logger.info("running my hook");
96
+
return doctorService.canExecuteLocalBuild();
97
+
};
98
+
```
99
+
100
+
*`hookArgs` contains the parameters of the CLI function being hooked; its shape depends on the hook point. Declare it only when you need it — a hook may also take no parameters at all.
101
+
* Tokens resolve by class first and by their canonical name on a miss, so this works even if your dependency tree carries its own copy of `nativescript` — a duplicated token class still resolves to the running CLI's service.
102
+
* Only a first tranche of services has typed tokens so far ([dependency-injection.md](dependency-injection.md#available-contracts) lists them); every other service is reachable by name — `di.get("logger")` returns the same instance as the legacy `$injector.resolve("logger")`.
103
+
* If you build your hook in TypeScript, add `nativescript` as a `devDependency` and import the same names: `import { DoctorService } from "nativescript/contracts"`.
104
+
*`inject()` itself requires an injection context, which hook invocation does not provide — use `di.get(...)` as above. A typed hook API that also replaces the `hookArgs` parameter with an explicit context is planned.
105
+
106
+
## The hook contract
81
107
82
-
Parameter | Type | Description
83
-
---|---|---
84
-
`$logger` | ILogger | Use the members of this class to show messages to the user cooperating with the CLI internal state.
85
-
`$projectData` | IProjectData | Contains data about the project, such as project directory, ID, dependencies, etc.
86
-
`$usbLiveSyncService` | ILiveSyncService | Use this variable to check whether a LiveSync or normal build is in progress.
87
-
`hookArgs` | Any | Contains all the parameters of the original function in the CLI which is being hooked.
88
-
89
108
The hook must return a Promise. If the hook succeeds, it must fullfil the promise, but the fullfilment value is ignored.
90
109
The hook can also reject the promise with an instance of Error. The returned error can have two optional members controlling the CLI.
91
110
@@ -95,33 +114,19 @@ Member | Type | Description
95
114
`errorAsWarning` | Boolean | Set this to treat the returned error as warning. The CLI prints the error.message colored as a warning and continues executing the current command.
96
115
97
116
If these two members are not set, the CLI prints the returned error colored as fatal error and stops executing the current command.
98
-
99
-
Furthermore, the global variable `$injector` of type `IInjector` provides access to the CLI Dependency Injector, through which all code services are available.
100
-
101
-
Using the Typed Injection API
102
-
==============================
103
117
104
-
The CLI also ships a typed, token-based injection API from the `nativescript/contracts` subpath, backed by the same container as `$injector` — a service resolved through a token is the identical instance you get by parametername. See [dependency-injection.md](dependency-injection.md) for the full API.
118
+
## Legacy: parameter-nameinjection
105
119
106
-
From a hook, access it through the injector's `di` container:
120
+
Historically, a hook received CLI services by naming them as parameters: the CLI parses the exported function's parameter names and injects the service registered under each name. Existing hooks written this way keep working unchanged, but **new hooks should use the pattern above** — parameter-name service injection is slated for deprecation, and hooks that use it are reported through the CLI's deprecation tracer (visible with `--log trace`, or as warnings with `NS_DEPRECATIONS=warn`).
`$logger` | ILogger | Use the members of this class to show messages to the user cooperating with the CLI internal state.
125
+
`$projectData` | IProjectData | Contains data about the project, such as project directory, ID, dependencies, etc.
126
+
`$usbLiveSyncService` | ILiveSyncService | Use this variable to check whether a LiveSync or normal build is in progress.
127
+
`hookArgs` | Any | Contains all the parameters of the original function in the CLI which is being hooked.
120
128
121
-
* Tokens resolve by class first and by their canonical name on a miss, so this works even if your dependency tree carries its own copy of `nativescript` — a duplicated token class still resolves to the running CLI's service.
122
-
* If you build your hook in TypeScript, add `nativescript` as a `devDependency` and import the same names: `import { DoctorService } from "nativescript/contracts"`.
123
-
*`inject()` itself requires an injection context, which the current hook invocation does not provide — hooks should use `$injector.di.get(...)` as above. A typed hook API that removes the parameter-name convention entirely is planned; until then, parameter-name injection remains fully supported, though its usage is traced for eventual deprecation (run the CLI with `--log trace` to see the reports, or set `NS_DEPRECATIONS=warn` to surface them).
124
-
* Only a first tranche of services has typed tokens so far ([dependency-injection.md](dependency-injection.md#available-contracts) lists them); every other service remains reachable by name — `$injector.di.get("logger")` and `$injector.resolve("logger")` are equivalent.
129
+
The type of the parameters is described in the `.d.ts` files which are part of the CLI source code [here](https://github.com/NativeScript/nativescript-cli/tree/master/lib/definitions). Any registered service name is injectable, not only the ones listed; the global variable `$injector` of type `IInjector` likewise remains available. A parameter the CLI cannot resolve causes the hook to be skipped with a warning.
0 commit comments