Jimp will not get upgraded so we need to do this to avoid the vuln in older versions of jpeg-js.
I also removed the relative deps from the monorepo root since they seemed to befoul the overrides. They are no longer needed due to workspaces (I think)
The big idea here is:
1. `desiredCapConstraints` should always contain the constraints _for that driver_; it no longer contains the "base" constraints. This is the only thing that really required any logic changes (though they are somewhat spread out). The "merged" constraints object is available via `_desiredCapConstraints`.
2. `Capabilities` and W3C-style `W3CCapabilities` are now _derived from_ constraints. This absolves us (and extension authors) from needing to create an interface describing their capabilities.
3. Changes to caps and constraints now reflect in `DriverOpts` (`this.opts`) in drivers
4. `caps` and `originalCaps` declarations have moved from `Core` to `Driver`
5. TypeScript compiles the JS output from `@appium/types` (which is just a static "constraints" object)
Resolves#17518
This change makes Appium recognize the existence of an extension in the current (or parent) dir, and automatically adds it to the extension manifest.
Resolution of Appium (e.g., _how_ Appium was installed) is no longer taken into account when determining if we're "in" a package that depends upon Appium. So you can easily `npm link appium` in an extension working copy if you wish, and this will not impact Appium's behavior.
To support this change, `hasAppiumDependency()` in `@appium/support`'s `env` has changed to be a wrapper around the new `findAppiumDependency()`. The strategy here is to use `npm list --long` to get detailed information about the current directory. The result will have an object with a `path` property, and that property points to the current workspace root (or current project root). We can then read the `package.json` in the `path` property--or just the CWD--to make the determination about an `appium` dependency (or lack thereof). For extension working copies, this will return `true` because `appium` will be present in `devDependencies`, `peerDependencies`, or both. For any other project, it will usually just be in `devDependencies`. If there's no `package.json` in the CWD and we're not in a workspace, Appium continues to use the default `APPIUM_HOME`.
One side effect of this is that running `appium` from the monorepo itself treats the dir hierarchy as a package which has an `appium` dependency (because it does!). To that end, the default `APPIUM_HOME` will _not_ be used when running `appium` from _anywhere in the monorepo_ unless you explicitly set `APPIUM_HOME` in an environment variable. Generally, our tests prescribe their own temporary `APPIUM_HOME` directories, so this should have no effect on them (in the general case). It _will_ have an effect on running `appium` manually in a development environment, as the workspace root will be treated as `APPIUM_HOME`; running `node ./packages/appium/index.js driver install uiautomator2` (or `npm start -- driver install uiautomator2`) will install that driver as a dev dependency (and save it). I could add a special case _just for the monorepo_ if we don't want this to happen, but it may introduce complexity we/I don't want to maintain, so I left it out. Furthermore, `npm start -- driver list` will show the `fake` driver, and `npm start -- plugin list` will show all of the plugins in `packages/`.
Regardless, I view this as a solid win for extension developers.
Bonus:
While I don't have benchmarks, this should considerably improve performance when detecting locally-installed (`node_modules/some-extension`) or extension working copies. Instead of using `klaw` to walk the filesystem (in serial!) we can just use `glob` to look for relevant `package.json` files. Instead of waiting until `glob` is completely finished searching, we can listen for its `match` evens and begin processing `package.json` files as soon as they are found. Because `@appium/support` only exposes a promisifed `glob()`--with no access to the `EventEmitter` it returns--`appium` depends on `glob` directly.