-
Notifications
You must be signed in to change notification settings - Fork 8
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
Improve API parameter types #41
base: main
Are you sure you want to change the base?
Conversation
to split data extraction from TS code formatting, and allow further improvements
- make some API parameters required, based on module information, - infer `action` and `format` parameter value depending on the params interface used - disable `tslint` rules in specific lines and not globally, so unintended error cas still be detected - add missing `fm` formats - fix some interfaces sharing the same name - sort interface to not mix up "action" and "format" interfaces
- use `ApiParams` instead of `UnknownApiParams` on functions doing an actual API query, since parameters need to be correct here, - do not auto-complete API params that API functions already specify - force some API params to be specified, when the functions throw an error if missing - remove JSON-format specific params, use `ApiFormatJsonParams` instead
feat: add more MediaWiki modules check other authors/commits at wikimedia-gadgets#41
Some methods of mwn (e.g. parseWikitext) provide a default value for |
At the same time, the "variant" property is missing. qiuwenbaike/QiuwenGadgets@6bd8000#diff-ad3705a25402295b5651e9eb78f318e7c91737361988b391165eeff64948fb32R12 |
Rewrite API queries to recursively retrieve all submodules, not only main modules and action=query submodules Not that a submodule hierarchy is built, so each submodule remembers where it comes from. This is not used for now, but will be used to fix some perfix & interface name issues in another commit.
Some websites may still be using Flow, but all types related to Flow have been removed in this change (including optional values of the The three interfaces Some properties should not strictly limit optional values (such as |
- make interface order deterministic, so alternatives are sorted alphabetically and submodules are next to their root module - fix action/format modules not being stored correctly in cache
check other authors/commits at wikimedia-gadgets#41
These changes try to fix a lot of issues with the previously proposed changes. Note that there are still issues remaining, so There are still issues, so this is still a work in progress. API modules: - extract all sub-module interfaces, not only action/command/format/list/meta/prop/submodule - change interface naming scheme to be closer to the actual API path and minimize conflicts Sub-modules: - duplicate interfaces, when they are used with different sub-modules (and property name prefixes) - add type mapping interfaces, so the list can be extended with other sub-modules - auto-complete sub-module name properties with mapping interface keys - allow unknown sub-modules to be specified again Parameters: - detect and generalize "slot"-type arguments, to allow other values than `main` and `*` - add types for templated parameters JSdoc: - add online doc links when some are specified - add `@deprecated` annotations to API parameters
As @AnYiEE reported, this causes a lot of issues with existing projects. This would require a more robust design and a lot more work to be of any use, so I remove it from this PR
Query API module data from multiple APIs at once, then merge the results. Queried APIs are determined by `SOURCES`. This allows to generate types for more diverse modules, including ones that were removed from wikipedia recently (e.g. Flow modules). On top of that, we can use the differences between APIs to detect enumerated parameters that are wiki-dependant (e.g. groups, skins). Other changes: - fix the script sometimes generating empty types, now it uses `never` in these cases, until a better solution is found. - generalize any enumerated parameter type with more than 100 possible values, to prevent generating lists of rights and languages.
- change module name capitalization algorithm, to search for pattern combinations in the name, instead of matching the full name once - add various basic patterns to fix (I hope all) badly capitalized interface names - fix some `undefined` errors when trying to merge modules from outdated APIs, which allows us to also use test wikis. - remove `NAME_TYPE_GENERALIZE` and `format` sub-module special cases, since the generator can now handle both of these properly
PR wikimedia-gadgets#41 also changes API parameter type names, to fix various name conflicts and parameter prefix issues, so I move it from this PR to PR wikimedia-gadgets#41.
- expose all types within `mw.Api` - split interface paths into sub-namespaces, allowing to use type aliases to reduce type names when desired - add deprecated type aliases, mapping old naming scheme to exposed (and renamed) types - fix handling of `required` values: if a site says a parameter is required and another one says it is optional, then we want to make it optional - cleaning up some stuff, started to document some things - move types to a separate declaration file to use the (easier to read) TS syntax
- rewrite ModuleMerger to make it easier to follow - add more strategies to handle incompatibilities between sites - fix ModuleLoader breaking the whole process when at least one site is unavailable (e.g. under maintenance, which appened a few days ago with labtestwikitech.wikimedia.org) - add missing API module parameter properties to the TS declaration file, not impacting the generated TS code for now
so we do not generate more than expected
Change parameter type system, to make better deductions & generate better TS code. Related changes: - detect and remove useless type enum members, that are already specified behind a type alias - fix enum type values wrongly disappearing when the value is generalized (e.g. string literals disappearing when the type is generalized to number) - fix some enum type members not being ordered properly Other changes: - use the default value of a module parameter to detect whether narrowed optional parameters should still be optional or not (i.e. if narrowed in a range that does not include the default values, then it no longer is optional) - show default values in JSdoc - show which parameters are sensible in JSdoc
Show numbers as numbers, fix empty strings by putting a text for now, and show arrays as a list of strings
Add a basic type replacement system to replace common parameter types. Currently used with namespaces and token types, will be expanded later.
- add `mw.Api.Toggle`, to simplify some enum types - expose, rename, and deprecate `ApiAssert` and `ApiLegacyTokenType` - rename `mw.Api.Token` to `mw.Api.TokenType`
Revert parameter strictness changes. This would require more work and is not a priority, so I remove it from this PR. Also remove the use of deprecated type aliases added in the last commits.
Split the code generation phase (`ModuleFormatter`) into a parsing phase, generating a more detailed type hierarchy (`ModuleFormatter`), and a final code generation phase (`ModuleGenerator`) This provides better control over how the TS types are stringified, so we can reorder and move these without having to modify the module hierarchy. For now, we use it to: - change the TS type ordering from depth-first to breadth-first, moving namespaces after all interfaces, but keeping the same order between interfaces and between namespaces. - generate and automatically download an `index.d.ts` file instead of printing the output in the console. Other unrelated changes: - simplify some stuff - fix some edge-cases where `never` types were badly generated
- if multiple APIs use a different `allspecifier`, then we take both into account - fix `allspecifier` being allowed in lists
so global declarations are visible when importing `types-mediawiki`
When deprecated type aliases refer to multiple interfaces, use the simpler ones in priority. This prevents using longer prefixes than expected. Also remove labtestwikitech from queried APIs.
- add module and parameter descriptions in JSdoc - make `mw.Api.Params` extend `mw.Api.UnknownParams`
So we can generalize skins and similar parameters. I looked at largest MW wikis, found Fandom and Graces Guide that have different skins, but Fandom also has a bunch of undocumented modules (or with broken types) so I only added Graces Guide. This also adds back imagerotate, but it causes links refer to Graces Guide, so not sure about that.
Changes (and slightly simplify) in which order modules are merged, to ensure modules are duplicated after being merged. This prevents the same module from appearing multiple times with different signatures.
- fix `UnknownApiParams` not allowing `File` objects - fix some logging error messages in the API types generator
Thank you very much @AnYiEE for your feedback and comments, I took my time with this. :) I've put aside the changes with issues for which I don't have a solution at the moment. I used MWN and QiuwenGadgets for usage reference, tried to fix everything I could find, feedbacks on the design or anything are more than welcome.
The issue is that the same interface or different ones can be used in different places with parameters of the same name, but with different prefixes. To avoid collisions, the proposed script duplicates interfaces according to where they are used. I proposed a different interface naming scheme to make it (I hope) more intuitive where to find the types with the right prefixes.
This should be fixed now, Flow is still used on other WMF sites than Wikipedia, so the script retrieves types from different APIs and merges the generated trees.
This should be fixed too, in the same way as the previous issue: enumerated parameters whose values differ between sites are generalized back to a For skins specifically, I tried to use a wiki with different available skins (so among the most visited MediaWiki sites outside WMF). I included Graces Guide, I also considered a Fandom site, but they seem to have a bunch of undocumented modules (or with broken/missing parameter types) so I didn't include any. The site list can be expanded, so if there are other modules to add, we can simply add a site that uses them. |
Replace timestamps with a fixed string to prevent these from being changed each time we re-run the script
4.4.2 was the 1st npm release to allow template string pattern index signatures, used in this PR. see microsoft/TypeScript#44512
Use JSdoc typedefs and JS classes instead The functional approach with ADTs makes the code way harder to read than it should be. This was originally designed when the script was only a few hundred lines, this is no longer the case at all, and will probably not be again.
|
A use case. We globally declare some types like |
I apologize for the late reply, and I assume also for my poor communication skills.
|
Improve the types of API parameters, by adding types for more modules and parameters, infering stricter types, and fixing some type issues.
To simplify the implementation of most of these changes, the
api_params
type generator has been rewritten. The changes proposed in this PR are mostly backwards-compatible (using some deprecation annotations), but some type fixes may break existing stuff. All changes are introduced below, potentially breaking changes are annotated with ⚠.Proposed changes
1. Extract modules from multiple APIs
Use multiple site APIs to generate types, allowing to generate types for extensions or modules that are not available on Wikipedia (including Flow and WikiBase).
This also provides a generic way for the type generator to detect which enum parameters are wiki-dependant (e.g. roles, namespaces, or languages). If incompatible types are detected, their type can be automatically generalized to
string
, so types are not over-specific. The proposed type generator queries module data on all sites independently, then merges the generated API trees together.The set of queried APIs can be extended with the
SOURCES
dict. In this PR it includes most english (and international) MediaWiki sites: MediaWiki, Wikipedia, Wikidata, Wikifunctions, Wikibooks, Wikimedia API Portal, Wikimedia Commons, Meta-Wiki, Wikinews, Wikiquote, Wikisource, Wikiversity, Wikivoyage, Wiktionary, and some test sites.2. Expose types
Expose all interface and enumeration types within the
mw.Api
/mw.Api.Params
namespaces.This part follows PR #40, in which API parameter types were left unchanged to prevent changing them twice with this proposal.
3. Change type names
Change the interface naming scheme to be based on the actual API path, and not on PHP class names.
This prevents the interface names from being changed when PHP files are renamed or moved (which will happen with MW 1.43, where various API files have changed name and been moved to the
MediaWiki\Api
namespace), and fixes some parameter interfaces sharing the same name and being merged together. In practice, the same API module can appear multiple times with different parameter prefixes, depending on the modules it is used with. By using API paths, a single module can generate multiple interfaces, preventing this issue.API paths are not extension-dependant, which allows to search for specific type interfaces more easily with auto-completion. For example:
format=…
interfaces are in themw.Api.Params.Format
namespace,action=query&list=…
interfaces in themw.Api.Params.Action.Query.List
namespace.Note that this makes most interfaces have longer names (e.g.
ApiQueryAllLinksParams
fully qualified becomesmw.Api.Params.Action.Query.List.AllLinks
), which may be mitigated by using namespace aliases.In this PR, current type names are still accepted and deprecated, using a (hardcoded) list of replacements.
4. Generate types for templated parameters ⚠
Various interfaces use templated parameters to let users specify a variable number of structured arguments. These are generally defined by using a
slots
parameter to specify a set of identifiers, then by using parameters multiple times, suffixed by one of the previously defined identifiers. For example, theaction=compare
API uses 2 set of templated parameters (from…
andto…
) to specify additional properties of one or multiples sources and targets.As a first approach, templated parameters are generated using template literal types in this PR. This only ensures properly-prefixed parameters have the correct types. For example, the following parameters are generated for the
action=compare
interface:This could be improved further, as this approach does not ensure parameter name suffixes are synchronized with each other.
5. Make API parameters stricter in types
Make parameters required, when mentioned on the API module declaration.
action
,format
, and similar parameter types are narrowed in sub-module interfaces. For example, usingmw.Api.Params.Action.Block | mw.Api.Params.Action.Unblock
only allowsaction: "block" | "unblock"
. ⚠For compatibility, exported (and deprecated) type aliases still have all their parameters optional.
6. Include a basic JSdoc
Generate JSdoc comments along with the module interfaces and parameters, to include information that can not be expressed with TS types.
In this PR, this includes:
This does not include:
Other changes
Params
interface. They may not be used with other formats, soParams.Format.Json
can be used instead. If a user wants to typecheckParams.Action.Move
with JSON-specific parameters,Params.Action.Move & Params.Format.Json
can be used instead.tslint
rules on specific lines and not for the entire file, so unintended error cas still be detected.