This adds a new package which consumers having TS sources can use. This does not affect current users of `@appium/eslint-config-appium`.
Due to the nature of TS, it can be a little more bold with fixes (e.g., changing let to const). I changed the following rules from the recommended settings:
no-empty-function: Reduced to a warning. It's likely we want the functions, but perhaps they should not be empty.
no-empty-interface: Disabled; we use these to merge mixin interfaces with driver classes.
no-explicit-any: Disabled; while transitioning from an untyped codebase to a typed one, we still need to use any in places. Eventually these should all be replaced.
no-non-null-assertion: Disabled; This allows us to continue use of the ! operator, which is handy when working with untyped or loosely-typed code (especially in tests).
no-var-requires: Reduced to a warning. Occasionally we may need to use require() instead of import.
Since the configuration extends our shared config, the following rules have been disabled:
import/no-unresolved: The eslint-plugin-import module cannot resolve TS modules.
no-unused-vars: This rule conflicts with typescript-eslint's rule, so it must be disabled per the documentation.
promise/no-native: In our TS-based packages, I haven't needed Bluebird, so it doesn't make sense to require it.
require-await: TS is much more aware of the return values of functions; this is not needed to avoid ambiguity (in TS code).
The main thrust of this was to resolve#18269.
Implementation-wise, we have to modify an `IntrinsicType` of which both `void` and `undefined` become. To make it `null`, we must create a new `LiteralType` (`null` is not an "intrinsic" type; I don't know why). I would think that TypeDoc wouldn't go around creating new `LiteralType`s every time it sees `null`, but I don't see it doing anything else. Anyway, if there is a "type cache" somewhere, I'm not sure how to get at it.
Additionally, the new reflections created for parameters and the call signature were not being "registered" properly with TypeDoc. So this adds a `static create` to both `CommandData` and `ExecMethodData` which wraps the constructor for each, respectively, then performs the registration. This keeps a `Context` object _out_ of `CommandData`/`ExecMethodData` instances (it would only be used once at time of instantiation anyway).
Un-memoized a couple methods in `BaseCommandData` since not necessary
This will automatically label PRs. We can update it to further automatically label issues at a later time, if necessary.
I have added labels for each package.
sometimes (when?) the smoke tests can pack the workspaces before they have actually been built, which will of course cause an error. this adds a prepack script to avoid the problem
removes pack-all script, which I added for reasons
While `findMatchingDriver()` returns a `MatchedDriver`--which is a wrapper around `DriverClass`--the instance of `DriverClass`' constructor is a `Driver`. But in the case of `AppiumDriver`, we know `InnerDriver` is actually an `ExternalDriver`; this is why we can assign to `server`, `serverHost`, etc.
moved method-map/execute-method-map-related stuff into its own file, and made the types more expressive. changed some default parameters to hopefully avoid errors about conflicting constraints
This changes the `fake-driver` implementation to use declaration merging instead of other alternatives to mixins.
History:
The original code simply assigned the mixin methods to `FakeDriver.prototype` after the `class` definition. In TS, this doesn't fly; you need to be explicit about what class members exist.
To get around this, we've tried multiple different approaches:
1. Use a "mixin pattern" as explained in the official TypeScript documentation, which involves _class factories_. This is tedious and difficult to reason about; each mixin must be passed to the next in-line, and we must be explicit about the base class and which _previous_ mixins any given mixin expects.
2. Use public class fields (a recent addition to JS). Basically, these do not work the way you want them to; if a subclass overrides a public field, a method in the superclass which refers to this public field _will use the field as defined in the superclass_--not the subclass. This is different than how methods and accessors work. This inhibits use of inheritance.
3. Add a method _for each method in each mixin_ to the base class, which simply calls `Function.prototype.apply` on the mixin with the context as the base class' `this`. This is too verbose.
There may be a better way to do this, but where we've landed is using _declaration merging_ in TypeScript. It allows us to add (but not remove, and I'm not sure about "modify") properties to the "FakeDriver interface", which seems to be the implicit TS interface created by the `class` keyword. Since the declaration merging syntax is not expressible in JavaScript, this requires a `.ts` file. To avoid creating _n_ extra files, it was easier to just make the mixins `.ts` files (you may note that we can mix-and-match JS and TS in our projects at will).
The implementation of each mixin uses `Object.assign()` to put new methods on the prototype, which are previously defined in the merged declaration above. Finally, a `satisfies` clause (which is a transient type-check; it does not change any types but it _will_ generate a compiler error) ensures the props being added to the prototype match what we've defined.
You'll also note that each method has a `this` parameter, which is not a "real" parameter--it's just an annotation for TS which tells the method what the context is. If we hate that, an alternative is to use `FakeDriver.prototype.method = <method>` instead of the `Object.assign` call. This feels marginally more tedious, but I could go either way.
These types were "wrong" in that it is exceedingly difficult to successfully implement `getLog()`, `getLogTypes()`, `supportLogTypes`, etc., in a third-party driver because you'd need to implement _all of it_ or _none of it_. It's especially bad because it does this without prescribing where the logs should be stored (which is by design). Oops.
This also moves some generics in the "find" mixins. This may change again later, but it's unclear that any given driver must declare what a "context" is, and that there can only be one per driver.