-
Notifications
You must be signed in to change notification settings - Fork 221
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
Proposal: JSON configuration file to control plugins #74
base: master
Are you sure you want to change the base?
Conversation
@edsrzf I think it's a cool idea!
Agree, + probably we should try to surface errors, instead of running with default/invalid configuration. Wdyt about using Example:
|
Generally speaking, I'm in favor of JSON (or JSONC) over YAML, especially for tools in the JS/TS ecosystem. |
I am personally not a fan of YAML, but I won't argue against it if the consensus is that we should use it. |
Let's go with JSON then, if that's good with you. It would also be simpler in terms of parsing and consistent. |
Alright, so we're happy with JSON. We need better validation of plugin options. Is there anything else blocking this proposal? For plugin option validation, what would you think about adding something like this to the interface Plugin<TPluginOptions = unknown> {
// ...
/**
* Returns true if options is a valid options object for this plugin.
* If options is invalid, throws an exception with details of why options is invalid.
*
* This method must be implemented if TPluginOptions is anything other than unknown.
*/
validate?(options: unknown): options is TPluginOptions;
} I don't love the "return true or throw exception" behavior but it doesn't seem to be possible to combine TypeScript type predicates with union types (eg something like |
I think we're all good here!
In terms of validation, I agree with you. Your proposal is more explicit than |
This PR contains a proposal for a JSON configuration file format for ts-migrate, as well as a basic implementation of the proposal. If the proposal is acceptable, I can write documentation and add further validation to the implementation, if necessary.
I'm completely happy to receive feedback on any level of this proposal. Don't worry about my feelings too much. 😀
Context
I see these problems with ts-migrate:
It should be easy to run repeatable migrations and it should be easy to tweak plugin configurations to get the desired results.
There is currently limited ability to configure plugins, and doing it purely from the command line can be cumbersome. We can add more command-line flags to increase configurability, but this makes it more cumbersome.
It should be possible to control which plugins run and the order in which they run.
Currently the only way to do this is running multiple
ts-migrate migrate --plugin $plugin
commands.There should be a way to load custom or third-party plugins.
See #41. This proposal does not aim to solve this problem, but it's a step towards solving the problem.
Solution
I propose adding a JSON configuration format for ts-migrate that allows specifying which plugins run, in what order, and the options passed to them.
The
migrate
command has a new flag,--config/-c
, which specifies the path to the configuration file. If a configuration file is specified, other flags are ignored.The top-level configuration object has two properties:
plugins
- a JSON array of plugins to run. Each plugin is a JSON object, described below.globalOptions
(optional) - a JSON object of options which are passed to all plugins. Typically this is whereanyAlias
andanyFunctionAlias
would be defined, but technically any option may be defined here.A plugin object has two properties:
name
: The name of the plugin. For example,strip-ts-ignore
.options
(optional): The options to be passed to the plugin. Options specified here overrideglobalOptions
.Downsides
reignore
command cannot be expressed in terms of a configuration object due to the "higher-order" plugins it uses. (withChangeTracking
,eslintFixChangedPlugin
)Schema
Here is a basic JSON schema which describes the structure of the configuration object. See also the defined TypeScript types in the implementation.
Example
The configuration for the default
migrate
command would look like this: