mirror of
https://github.com/appium/appium.git
synced 2026-10-17 04:41:24 +08:00
chore(appium,types,schema): create @appium/schema
`@appium/schema` is a package which was extracted from `appium`. It _only_ contains the schema. The impetus here was to avoid cyclical dependencies, since `appium` depends on `@appium/types`, and `@appium/types` depends on the schema. This package breaks the cycle. The `scripts/generate-schema-json.js` (which converts the compiled JS schema file into JSON) has moved into this package, and the generated JSON file is now under version control. This is because the `generate-schema-types.js` script (previously `generate-schema-declarations`) depends on it, and `@appium/types` depends on the generated types. The generated types are _also_ under version control. I do not expect the schema to change often, so I believe the tradeoff to be worth it. ## @appium/schema `lib/appium-config-schema.js` is the "single source of truth" for the schema. ## appium - Removed schema source - Removed namespaces from internal types because they suck (see change to `types/index.d.ts`) - Removed unused `continuation-local-storage` - Add dep for `@appium/schema` - Added a TS project dependency on `@appium/schema` ## @appium/types - The "sources" have moved from `src` to `lib` for consistency. - `lib/appium-config.ts` (the generated types) are now under version control. - `lib/schema/` has been removed (it previously held the JSON schema artifact) - `scripts/generate-schema-declarations.js` becomes `scripts/generate-schema-types.js` - Updated scripts in `package.json` - Added dep for `@appium/schema` - Added a TS project dependency on `@appium/schema` ## Other - Reorganize root `tsconfig.json`; add `schema` reference; remove unused `noEmit: true` - Sort root `package.json` - Remove schema JSON and schema declarations scripts, since those are now both handled in their respective packages - Remove `lint-staged` config for schema file, since it didn't work right anyway (still need to do something about this, but probably doesn't need to be in a precommit hook) - Remove stuff from `.gitignore`
This commit is contained in:
@@ -58,7 +58,4 @@ appium.zip
|
||||
*.lerna_backup
|
||||
**/build-fixtures/**
|
||||
*.tsbuildinfo
|
||||
packages/*/**/appium-config.schema.json
|
||||
packages/types/src/appium-config.ts
|
||||
packages/types/src/appium-config-schema.js
|
||||
packages/*/LICENSE
|
||||
|
||||
+3
-6
@@ -27,15 +27,12 @@
|
||||
"build": "run-s build:distfiles build:types",
|
||||
"build:distfiles": "lerna run --parallel --prefix --concurrency=8 build",
|
||||
"build:loose": "run-s -c build:distfiles build:types || true",
|
||||
"prebuild:schema": "node ./scripts/generate-schema-json.js",
|
||||
"build:schema": "lerna run --scope=@appium/types generate-schema-declarations",
|
||||
"prebuild:types": "npm run build:schema",
|
||||
"build:types": "tsc -b",
|
||||
"clean": "run-s clean:*",
|
||||
"clean:distfiles": "npx rimraf \"packages/*/build\"",
|
||||
"clean:monorepo": "npx rimraf node_modules package-lock.json",
|
||||
"clean:packages": "lerna clean -y && npx rimraf \"packages/*/package-lock.json\"",
|
||||
"clean:types": "tsc -b --clean",
|
||||
"clean:monorepo": "npx rimraf node_modules package-lock.json",
|
||||
"dev": "lerna run --parallel --prefix --concurrency=8 dev",
|
||||
"dev:types": "tsc -b --watch",
|
||||
"doctor": "node ./packages/doctor",
|
||||
@@ -85,8 +82,7 @@
|
||||
"precommit-lint"
|
||||
],
|
||||
"lint-staged": {
|
||||
"*.js": "eslint --fix",
|
||||
"./packages/appium/lib/schema/appium-config-schema.js": "npm run build:schema"
|
||||
"*.js": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/base-driver": "file:packages/base-driver",
|
||||
@@ -95,6 +91,7 @@
|
||||
"@appium/fake-driver": "file:packages/fake-driver",
|
||||
"@appium/gulp-plugins": "file:packages/gulp-plugins",
|
||||
"@appium/opencv": "file:packages/opencv",
|
||||
"@appium/schema": "file:packages/schema",
|
||||
"@appium/support": "file:packages/support",
|
||||
"@appium/test-support": "file:packages/test-support",
|
||||
"@appium/types": "file:packages/types",
|
||||
|
||||
@@ -211,28 +211,28 @@ export class DriverConfig extends ExtensionConfig {
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {import('../../types').ExternalManifest.ExtMetadata<T>} ExtMetadata
|
||||
* @typedef {import('../../types').ExtMetadata<T>} ExtMetadata
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {import('../../types').AppiumManifest.ExtManifest<T>} ExtManifest
|
||||
* @typedef {import('../../types').ExtManifest<T>} ExtManifest
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('../../types').AppiumManifest.ManifestData} ManifestData
|
||||
* @typedef {import('../../types').ManifestData} ManifestData
|
||||
* @typedef {import('../../types').DriverType} DriverType
|
||||
* @typedef {import('./manifest').Manifest} Manifest
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {import('../../types').AppiumManifest.ExtRecord<T>} ExtRecord
|
||||
* @typedef {import('../../types').ExtRecord<T>} ExtRecord
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {import('../../types').AppiumManifest.ExtName<T>} ExtName
|
||||
* @typedef {import('../../types').ExtName<T>} ExtName
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function loadExtensions (appiumHome) {
|
||||
*
|
||||
* @param {import('./plugin-config').PluginConfig} pluginConfig - a plugin extension config
|
||||
* @param {string[]} usePlugins
|
||||
* @returns {import('../../types').Extension.PluginClass[]}
|
||||
* @returns {import('../../types').PluginClass[]}
|
||||
*/
|
||||
export function getActivePlugins (pluginConfig, usePlugins = []) {
|
||||
return _.compact(
|
||||
|
||||
@@ -4,7 +4,7 @@ import addFormats from 'ajv-formats';
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import { DRIVER_TYPE, PLUGIN_TYPE } from '../constants';
|
||||
import appiumConfigSchema from './appium-config-schema';
|
||||
import { AppiumConfigJsonSchema } from '@appium/schema';
|
||||
import { APPIUM_CONFIG_SCHEMA_ID, ArgSpec, SERVER_PROP_NAME } from './arg-spec';
|
||||
import { keywords } from './keywords';
|
||||
|
||||
@@ -189,7 +189,7 @@ class AppiumSchema {
|
||||
const ajv = this._ajv;
|
||||
|
||||
// Ajv will _mutate_ the schema, so we need to clone it.
|
||||
const baseSchema = _.cloneDeep(appiumConfigSchema);
|
||||
const baseSchema = _.cloneDeep(AppiumConfigJsonSchema);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
import _ from 'lodash';
|
||||
import logger from './logger';
|
||||
// @ts-ignore
|
||||
import { processCapabilities, PROTOCOLS } from '@appium/base-driver';
|
||||
import { inspect as dump } from 'util';
|
||||
|
||||
@@ -37,7 +36,7 @@ const inspect = _.flow(
|
||||
* @param {any} jsonwpCapabilities
|
||||
* @param {W3CCapabilities} w3cCapabilities
|
||||
* @param {import('@appium/types').Constraints} constraints
|
||||
* @param {import('../types/appium-config').DefaultCapabilitiesConfig} [defaultCapabilities]
|
||||
* @param {import('@appium/types').DefaultCapabilitiesConfig} [defaultCapabilities]
|
||||
* @returns {ParsedDriverCaps|InvalidCaps}
|
||||
*/
|
||||
function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constraints = {}, defaultCapabilities = {}) {
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"dependencies": {
|
||||
"@appium/base-driver": "file:../base-driver",
|
||||
"@appium/base-plugin": "1.8.1",
|
||||
"@appium/schema": "file:../schema",
|
||||
"@appium/support": "file:../support",
|
||||
"@babel/runtime": "7.17.9",
|
||||
"@sidvind/better-ajv-errors": "1.1.1",
|
||||
@@ -60,7 +61,6 @@
|
||||
"asyncbox": "2.9.2",
|
||||
"axios": "0.26.1",
|
||||
"bluebird": "3.7.2",
|
||||
"continuation-local-storage": "3.2.1",
|
||||
"find-up": "5.0.0",
|
||||
"lilconfig": "2.0.5",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
// this fixture combines the base config schema and the fake-driver schema, as would happen in a real use case.
|
||||
import _ from 'lodash';
|
||||
import appiumConfigSchema from '../../lib/schema/appium-config-schema';
|
||||
import { AppiumConfigJsonSchema } from '@appium/schema';
|
||||
|
||||
// this must be a `require` because babel will not compile `node_modules`
|
||||
// TOOD: consider just copying this into fixtures so we can make it ESM
|
||||
const {default: fakeDriverSchema} = require('@appium/fake-driver/build/lib/fake-driver-schema');
|
||||
|
||||
const schema = _.cloneDeep(appiumConfigSchema);
|
||||
const schema = _.cloneDeep(AppiumConfigJsonSchema);
|
||||
_.set(schema, 'properties.driver.properties.fake', fakeDriverSchema);
|
||||
|
||||
export default schema;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import _ from 'lodash';
|
||||
import { createSandbox } from 'sinon';
|
||||
import { DRIVER_TYPE, PLUGIN_TYPE } from '../../../lib/constants';
|
||||
import appiumConfigSchema from '../../../lib/schema/appium-config-schema';
|
||||
import { AppiumConfigJsonSchema } from '@appium/schema';
|
||||
import { APPIUM_CONFIG_SCHEMA_ID } from '../../../lib/schema/arg-spec';
|
||||
import defaultArgsFixture from '../../fixtures/default-args';
|
||||
import DRIVER_SCHEMA_FIXTURE from '../../fixtures/driver.schema';
|
||||
@@ -232,7 +232,7 @@ describe('schema', function () {
|
||||
});
|
||||
|
||||
it('should return a schema', function () {
|
||||
expect(getSchema()).to.eql(appiumConfigSchema);
|
||||
expect(getSchema()).to.eql(AppiumConfigJsonSchema);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -244,7 +244,7 @@ describe('schema', function () {
|
||||
describe('when schema ID is the base schema ID', function () {
|
||||
it('should return the base schema', function () {
|
||||
expect(getSchema(APPIUM_CONFIG_SCHEMA_ID)).to.eql(
|
||||
appiumConfigSchema,
|
||||
AppiumConfigJsonSchema,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -256,7 +256,7 @@ describe('schema', function () {
|
||||
`${APPIUM_CONFIG_SCHEMA_ID}#/properties/server/properties/address`,
|
||||
),
|
||||
).to.exist.and.to.eql(
|
||||
appiumConfigSchema.properties.server.properties.address,
|
||||
AppiumConfigJsonSchema.properties.server.properties.address,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -394,7 +394,7 @@ describe('schema', function () {
|
||||
describe('when no extensions registered schemas', function () {
|
||||
it('should return a Record containing the single base schema', function () {
|
||||
expect(finalizeSchema()).to.eql({
|
||||
[APPIUM_CONFIG_SCHEMA_ID]: appiumConfigSchema,
|
||||
[APPIUM_CONFIG_SCHEMA_ID]: AppiumConfigJsonSchema,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -405,7 +405,7 @@ describe('schema', function () {
|
||||
});
|
||||
|
||||
it('should return a Record containing all extension schemas _and_ the base schema containing references to the extension schemas', function () {
|
||||
const baseSchemaWithRefs = _.cloneDeep(appiumConfigSchema);
|
||||
const baseSchemaWithRefs = _.cloneDeep(AppiumConfigJsonSchema);
|
||||
baseSchemaWithRefs.properties.server.properties.driver.properties.stuff =
|
||||
{$ref: 'driver-stuff.json', $comment: 'stuff'};
|
||||
expect(finalizeSchema()).to.eql({
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"paths": {
|
||||
"@appium/support": ["../support"],
|
||||
"@appium/base-driver": ["../base-driver"],
|
||||
"@appium/types": ["../types"]
|
||||
"@appium/types": ["../types"],
|
||||
"@appium/schema": ["../schema"]
|
||||
},
|
||||
"checkJs": true
|
||||
},
|
||||
@@ -14,6 +15,7 @@
|
||||
"references": [
|
||||
{"path": "../support"},
|
||||
{"path": "../base-driver"},
|
||||
{"path": "../types"}
|
||||
{"path": "../types"},
|
||||
{"path": "../schema"}
|
||||
]
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
import {SchemaObject} from 'ajv';
|
||||
import {CommonMetadata, ExtMetadata, SchemaMetadata} from './external-manifest';
|
||||
import {ExtensionType, DriverType, PluginType} from '.';
|
||||
import { CommonMetadata, ExtMetadata, SchemaMetadata } from './external-manifest';
|
||||
import { ExtensionType, DriverType, PluginType } from '.';
|
||||
|
||||
export type InstallType = 'npm' | 'git' | 'local' | 'github';
|
||||
|
||||
|
||||
Vendored
+4
-5
@@ -1,8 +1,7 @@
|
||||
export * as AppiumManifest from './appium-manifest';
|
||||
export * as ExternalManifest from './external-manifest';
|
||||
export * as Extension from './extension';
|
||||
export * as Cli from './cli';
|
||||
export * as Config from './appium-config';
|
||||
export * from './appium-manifest';
|
||||
export * from './external-manifest';
|
||||
export * from './extension';
|
||||
export * from './cli';
|
||||
export type DriverType = 'driver';
|
||||
export type PluginType = 'plugin';
|
||||
export type ExtensionType = DriverType | PluginType;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# @appium/schema
|
||||
|
||||
> JSON schema for [Appium](https://github.com/appium/appium) configuration files
|
||||
|
||||
## Description
|
||||
|
||||
This package is used internally by Appium, but can also be used to validate Appium configuration files in other contexts.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm i @appium/schema
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The schema is exported as a JS object:
|
||||
|
||||
```js
|
||||
const { AppiumConfigJsonSchema } = require('@appium/schema');
|
||||
```
|
||||
|
||||
It is also provided as a JSON file (since this is a JSON schema, after all):
|
||||
|
||||
```js
|
||||
const schema = require('@appium/schema/lib/appium-config.schema.json');
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
[@appium/types](https://npm.im/@appium/types) exports a TypeScript type `AppiumConfig` (generated from this package) for typesafe configuration objects; this may be useful if your Appium configuration is written in JS (e.g., `.appiumrc.js`). Example:
|
||||
|
||||
```js
|
||||
// @ts-check
|
||||
/** @type {import('@appium/types').AppiumConfig} */
|
||||
module.exports = {
|
||||
server: {
|
||||
port: 1234,
|
||||
host: '127.0.0.1'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
`lib/appium-config.schema.json` is generated by this package from `lib/appium-config-schema.js` (the single source of truth), but is under version control to avoid chicken-or-egg build problems.
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('./build/index.js');
|
||||
+8
-5
@@ -1,5 +1,10 @@
|
||||
/**
|
||||
* The single-source-of-truth of the Appium server configuration
|
||||
*
|
||||
* This defines _both_ what the CLI supports and what the config files support.
|
||||
*/
|
||||
|
||||
const schema = /** @type {const} */ ({
|
||||
export const AppiumConfigJsonSchema = /** @type {const} */({
|
||||
$schema: 'http://json-schema.org/draft-07/schema',
|
||||
additionalProperties: false,
|
||||
description: 'A schema for Appium configuration files',
|
||||
@@ -91,7 +96,7 @@ const schema = /** @type {const} */ ({
|
||||
driver: {
|
||||
description:
|
||||
'Driver-specific configuration. Keys should correspond to driver package names',
|
||||
properties: {},
|
||||
properties: /** @type {Record<string,import('json-schema').JSONSchema7>} */({}),
|
||||
title: 'driver config',
|
||||
type: 'object',
|
||||
},
|
||||
@@ -192,7 +197,7 @@ const schema = /** @type {const} */ ({
|
||||
plugin: {
|
||||
description:
|
||||
'Plugin-specific configuration. Keys should correspond to plugin package names',
|
||||
properties: {},
|
||||
properties: /** @type {Record<string,import('json-schema').JSONSchema7>} */({}),
|
||||
title: 'plugin config',
|
||||
type: 'object',
|
||||
},
|
||||
@@ -282,5 +287,3 @@ const schema = /** @type {const} */ ({
|
||||
title: 'Appium Configuration',
|
||||
type: 'object',
|
||||
});
|
||||
|
||||
export default schema;
|
||||
@@ -0,0 +1,278 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"additionalProperties": false,
|
||||
"description": "A schema for Appium configuration files",
|
||||
"properties": {
|
||||
"server": {
|
||||
"additionalProperties": false,
|
||||
"description": "Configuration when running Appium as a server",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$comment": "I think hostname covers both DNS and IPv4...could be wrong",
|
||||
"appiumCliAliases": [
|
||||
"a"
|
||||
],
|
||||
"default": "0.0.0.0",
|
||||
"description": "IP address to listen on",
|
||||
"format": "hostname",
|
||||
"title": "address config",
|
||||
"type": "string"
|
||||
},
|
||||
"allow-cors": {
|
||||
"description": "Whether the Appium server should allow web browser connections from any host",
|
||||
"title": "allow-cors config",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"allow-insecure": {
|
||||
"appiumCliTransformer": "csv",
|
||||
"default": [],
|
||||
"description": "Set which insecure features are allowed to run in this server's sessions. Features are defined on a driver level; see documentation for more details. Note that features defined via \"deny-insecure\" will be disabled, even if also listed here. If string, a path to a text file containing policy or a comma-delimited list.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "allow-insecure config",
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"base-path": {
|
||||
"appiumCliAliases": [
|
||||
"pa"
|
||||
],
|
||||
"default": "",
|
||||
"description": "Base path to use as the prefix for all webdriver routes running on the server",
|
||||
"title": "base-path config",
|
||||
"type": "string"
|
||||
},
|
||||
"callback-address": {
|
||||
"appiumCliAliases": [
|
||||
"ca"
|
||||
],
|
||||
"description": "Callback IP address (default: same as \"address\")",
|
||||
"title": "callback-address config",
|
||||
"type": "string"
|
||||
},
|
||||
"callback-port": {
|
||||
"appiumCliAliases": [
|
||||
"cp"
|
||||
],
|
||||
"default": 4723,
|
||||
"description": "Callback port (default: same as \"port\")",
|
||||
"maximum": 65535,
|
||||
"minimum": 1,
|
||||
"title": "callback-port config",
|
||||
"type": "integer"
|
||||
},
|
||||
"debug-log-spacing": {
|
||||
"default": false,
|
||||
"description": "Add exaggerated spacing in logs to help with visual inspection",
|
||||
"title": "debug-log-spacing config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"default-capabilities": {
|
||||
"$comment": "TODO",
|
||||
"appiumCliAliases": [
|
||||
"dc"
|
||||
],
|
||||
"description": "Set the default desired capabilities, which will be set on each session unless overridden by received capabilities. If a string, a path to a JSON file containing the capabilities, or raw JSON.",
|
||||
"title": "default-capabilities config",
|
||||
"type": "object"
|
||||
},
|
||||
"deny-insecure": {
|
||||
"$comment": "Allowed values are defined by drivers",
|
||||
"appiumCliTransformer": "csv",
|
||||
"default": [],
|
||||
"description": "Set which insecure features are not allowed to run in this server's sessions. Features are defined on a driver level; see documentation for more details. Features listed here will not be enabled even if also listed in \"allow-insecure\", and even if \"relaxed-security\" is enabled. If string, a path to a text file containing policy or a comma-delimited list.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "deny-insecure config",
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"driver": {
|
||||
"description": "Driver-specific configuration. Keys should correspond to driver package names",
|
||||
"properties": {},
|
||||
"title": "driver config",
|
||||
"type": "object"
|
||||
},
|
||||
"keep-alive-timeout": {
|
||||
"appiumCliAliases": [
|
||||
"ka"
|
||||
],
|
||||
"default": 600,
|
||||
"description": "Number of seconds the Appium server should apply as both the keep-alive timeout and the connection timeout for all requests. A value of 0 disables the timeout.",
|
||||
"minimum": 0,
|
||||
"title": "keep-alive-timeout config",
|
||||
"type": "integer"
|
||||
},
|
||||
"local-timezone": {
|
||||
"default": false,
|
||||
"description": "Use local timezone for timestamps",
|
||||
"title": "local-timezone config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"log": {
|
||||
"appiumCliAliases": [
|
||||
"g"
|
||||
],
|
||||
"appiumCliDest": "logFile",
|
||||
"description": "Also send log output to this file",
|
||||
"title": "log config",
|
||||
"type": "string"
|
||||
},
|
||||
"log-filters": {
|
||||
"$comment": "TODO",
|
||||
"description": "One or more log filtering rules",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "log-filters config",
|
||||
"type": "array"
|
||||
},
|
||||
"log-level": {
|
||||
"appiumCliDest": "loglevel",
|
||||
"default": "debug",
|
||||
"description": "Log level (console[:file])",
|
||||
"enum": [
|
||||
"info",
|
||||
"info:debug",
|
||||
"info:info",
|
||||
"info:warn",
|
||||
"info:error",
|
||||
"warn",
|
||||
"warn:debug",
|
||||
"warn:info",
|
||||
"warn:warn",
|
||||
"warn:error",
|
||||
"error",
|
||||
"error:debug",
|
||||
"error:info",
|
||||
"error:warn",
|
||||
"error:error",
|
||||
"debug",
|
||||
"debug:debug",
|
||||
"debug:info",
|
||||
"debug:warn",
|
||||
"debug:error"
|
||||
],
|
||||
"title": "log-level config",
|
||||
"type": "string"
|
||||
},
|
||||
"log-no-colors": {
|
||||
"default": false,
|
||||
"description": "Do not use color in console output",
|
||||
"title": "log-no-colors config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"log-timestamp": {
|
||||
"default": false,
|
||||
"description": "Show timestamps in console output",
|
||||
"title": "log-timestamp config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"long-stacktrace": {
|
||||
"default": false,
|
||||
"description": "Add long stack traces to log entries. Recommended for debugging only.",
|
||||
"title": "long-stacktrace config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"no-perms-check": {
|
||||
"default": false,
|
||||
"description": "Do not check that needed files are readable and/or writable",
|
||||
"title": "no-perms-check config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"nodeconfig": {
|
||||
"$comment": "Selenium Grid 3 is unmaintained and Selenium Grid 4 no longer supports this file.",
|
||||
"description": "Path to configuration JSON file to register Appium as a node with Selenium Grid 3; otherwise the configuration itself",
|
||||
"title": "nodeconfig config",
|
||||
"type": "object"
|
||||
},
|
||||
"plugin": {
|
||||
"description": "Plugin-specific configuration. Keys should correspond to plugin package names",
|
||||
"properties": {},
|
||||
"title": "plugin config",
|
||||
"type": "object"
|
||||
},
|
||||
"port": {
|
||||
"appiumCliAliases": [
|
||||
"p"
|
||||
],
|
||||
"default": 4723,
|
||||
"description": "Port to listen on",
|
||||
"maximum": 65535,
|
||||
"minimum": 1,
|
||||
"title": "port config",
|
||||
"type": "integer"
|
||||
},
|
||||
"relaxed-security": {
|
||||
"default": false,
|
||||
"description": "Disable additional security checks, so it is possible to use some advanced features, provided by drivers supporting this option. Only enable it if all the clients are in the trusted network and it's not the case if a client could potentially break out of the session sandbox. Specific features can be overridden by using \"deny-insecure\"",
|
||||
"title": "relaxed-security config",
|
||||
"type": "boolean",
|
||||
"appiumCliDest": "relaxedSecurityEnabled"
|
||||
},
|
||||
"session-override": {
|
||||
"default": false,
|
||||
"description": "Enables session override (clobbering)",
|
||||
"title": "session-override config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"strict-caps": {
|
||||
"default": false,
|
||||
"description": "Cause sessions to fail if desired caps are sent in that Appium does not recognize as valid for the selected device",
|
||||
"title": "strict-caps config",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tmp": {
|
||||
"appiumCliDest": "tmpDir",
|
||||
"description": "Absolute path to directory Appium can use to manage temp files. Defaults to C:\\Windows\\Temp on Windows and /tmp otherwise.",
|
||||
"title": "tmp config",
|
||||
"type": "string"
|
||||
},
|
||||
"trace-dir": {
|
||||
"description": "Absolute path to directory Appium can use to save iOS instrument traces; defaults to <tmp>/appium-instruments",
|
||||
"title": "trace-dir config",
|
||||
"type": "string"
|
||||
},
|
||||
"use-drivers": {
|
||||
"appiumCliDescription": "A list of drivers to activate. Can be a comma-delimited string or path to CSV file. By default, all installed drivers will be activated.",
|
||||
"default": [],
|
||||
"description": "A list of drivers to activate. By default, all installed drivers will be activated.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "use-drivers config",
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"use-plugins": {
|
||||
"appiumCliDescription": "A list of plugins to activate. Can be a comma-delimited string, path to CSV file, or the string \"all\" to use all installed plugins.",
|
||||
"default": [],
|
||||
"description": "A list of plugins to activate. To activate all plugins, the value should be an array with a single item \"all\".",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "use-plugins config",
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"webhook": {
|
||||
"$comment": "This should probably use a uri-template format to restrict the protocol to http/https",
|
||||
"appiumCliAliases": [
|
||||
"G"
|
||||
],
|
||||
"description": "Also send log output to this http listener",
|
||||
"format": "uri",
|
||||
"title": "webhook config",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": "server config",
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"title": "Appium Configuration",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './appium-config-schema';
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@appium/schema",
|
||||
"version": "0.0.0",
|
||||
"description": "Appium Configuration Schema",
|
||||
"keywords": [],
|
||||
"homepage": "https://appium.io",
|
||||
"bugs": {
|
||||
"url": "https://github.com/appium/appium/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appium/appium.git",
|
||||
"directory": "schema"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": "https://github.com/appium",
|
||||
"types": "./build/index.d.ts",
|
||||
"files": [
|
||||
"build",
|
||||
"lib",
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "run-s build:distfiles build:schema-json",
|
||||
"build:distfiles": "babel lib --root-mode=upward --out-dir=build",
|
||||
"build:schema-json": "node ./scripts/generate-schema-json.js",
|
||||
"dev": "npm run build -- --watch",
|
||||
"fix": "npm run lint -- --fix",
|
||||
"lint": "eslint -c ../../.eslintrc --ignore-path ../../.eslintignore ."
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"gitHead": "ec6a90a797d2dadb407922426be16efaec9def07"
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env node
|
||||
// @ts-check
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/**
|
||||
* This script takes the JSON schema `.js` artifact and converts it to JSON proper,
|
||||
* then outputs the result.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const {writeFile, mkdir} = require('fs').promises;
|
||||
const {info, success, error} = require('log-symbols');
|
||||
|
||||
/**
|
||||
* `@appium/schema` package root.
|
||||
*/
|
||||
const SCHEMA_ROOT = path.join(__dirname, '..');
|
||||
|
||||
/**
|
||||
* Dir which will contain output `.json`
|
||||
*/
|
||||
const OUTPUT_DIR = path.join(SCHEMA_ROOT, 'lib');
|
||||
|
||||
/**
|
||||
* Basename of exported `.json` file.
|
||||
*/
|
||||
const JSON_FILENAME = 'appium-config.schema.json';
|
||||
|
||||
/**
|
||||
* Path to the schema artifact.
|
||||
*/
|
||||
const SCHEMA_SRC = path.join(SCHEMA_ROOT, 'build', 'appium-config-schema.js');
|
||||
|
||||
/**
|
||||
* Full path to output `.json`
|
||||
*/
|
||||
const OUTPUT_PATH = path.join(OUTPUT_DIR, JSON_FILENAME);
|
||||
|
||||
async function write () {
|
||||
/** @type {typeof import('../lib/appium-config-schema').AppiumConfigJsonSchema} */
|
||||
let schema;
|
||||
try {
|
||||
({AppiumConfigJsonSchema: schema} = require(SCHEMA_SRC));
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`${error} Failed to read ${SCHEMA_SRC}; did you execute \`npm run build\` first?`,
|
||||
);
|
||||
}
|
||||
|
||||
const json = JSON.stringify(schema, null, 2);
|
||||
|
||||
try {
|
||||
await mkdir(OUTPUT_DIR, {recursive: true});
|
||||
await writeFile(OUTPUT_PATH, json);
|
||||
console.log(`${info} Wrote JSON schema to ${OUTPUT_PATH}`);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`${error} Failed to write JSON schema to ${OUTPUT_PATH}: ${err.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function main () {
|
||||
try {
|
||||
await write();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
console.log(`${success} Done.`);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {main, write};
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../config/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "lib",
|
||||
"outDir": "build",
|
||||
"checkJs": true
|
||||
},
|
||||
"include": ["./lib/**/*.js"]
|
||||
}
|
||||
@@ -14,6 +14,7 @@ npm install @appium/types -D
|
||||
|
||||
- The sources are `.ts` files, _not_ `.d.ts` files. This allows other packages in the root TypeScript "project" to define a dependency upon this one, and enables incremental builds an "watch" mode.
|
||||
- If there is a way to switch to `.d.ts` files and configure this package to work in our "project" context _without_ needing to actually "emit" anything, then we should do that instead. Help accepted!
|
||||
- `lib/appium-config.ts` is generated by this package from `@appium/schema`, but is under version control to avoid chicken-or-egg build problems.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import appiumConfigSchema from './appium-config-schema';
|
||||
import type { AppiumConfiguration, ServerConfig } from './appium-config';
|
||||
import type { AppiumConfigJsonSchema } from '@appium/schema';
|
||||
import { AppiumConfiguration, ServerConfig } from './appium-config';
|
||||
|
||||
/**
|
||||
* The Appium configuration as it would be in a user-provided configuration file.
|
||||
@@ -9,21 +9,21 @@ export type AppiumConfig = Partial<AppiumConfiguration>;
|
||||
/**
|
||||
* Derive the "constant" type of the server properties from the schema.
|
||||
*/
|
||||
type AppiumServerSchema =
|
||||
typeof appiumConfigSchema['properties']['server']['properties'];
|
||||
type AppiumServerJsonSchema =
|
||||
typeof AppiumConfigJsonSchema['properties']['server']['properties'];
|
||||
|
||||
/**
|
||||
* This type associates the types generated from the schema ({@linkcode AppiumConfiguration})
|
||||
* with the schema itself (beginning with the `server` prop).
|
||||
*/
|
||||
type ServerConfigMapping = Associated<ServerConfig, AppiumServerSchema>;
|
||||
type ServerConfigMapping = Associated<ServerConfig, AppiumServerJsonSchema>;
|
||||
|
||||
/**
|
||||
* Camel-cased server config. _Not_ flattened.
|
||||
*/
|
||||
export type NormalizedServerConfig = {
|
||||
[Prop in keyof ServerConfigMapping as AppiumServerSchema[Prop] extends WithDest
|
||||
? AppiumServerSchema[Prop]['appiumCliDest']
|
||||
[Prop in keyof ServerConfigMapping as AppiumServerJsonSchema[Prop] extends WithDest
|
||||
? AppiumServerJsonSchema[Prop]['appiumCliDest']
|
||||
: KebabToCamel<Prop>]: ServerConfig[Prop];
|
||||
};
|
||||
|
||||
@@ -40,8 +40,8 @@ export type NormalizedAppiumConfig = {
|
||||
* otherwise uses the camel-cased value of the key name.
|
||||
*/
|
||||
type SetKeyForProp<Prop extends keyof ServerConfigMapping> =
|
||||
AppiumServerSchema[Prop] extends WithDest
|
||||
? AppiumServerSchema[Prop]['appiumCliDest']
|
||||
AppiumServerJsonSchema[Prop] extends WithDest
|
||||
? AppiumServerJsonSchema[Prop]['appiumCliDest']
|
||||
: KebabToCamel<Prop>;
|
||||
|
||||
/**
|
||||
@@ -50,7 +50,7 @@ type SetKeyForProp<Prop extends keyof ServerConfigMapping> =
|
||||
* If no default value, just a type.
|
||||
*/
|
||||
type KeyOrDefaultForProp<Prop extends keyof ServerConfigMapping> =
|
||||
AppiumServerSchema[Prop] extends WithDefault
|
||||
AppiumServerJsonSchema[Prop] extends WithDefault
|
||||
? NonNullable<ServerConfig[Prop]>
|
||||
: ServerConfig[Prop];
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Capabilities, W3CCapabilities } from './capabilities';
|
||||
|
||||
export { AppiumW3CCapabilities } from './capabilities';
|
||||
export { AppiumConfig, NormalizedAppiumConfig } from './config';
|
||||
export * from './appium-config';
|
||||
export { DriverOpts, Capabilities, W3CCapabilities };
|
||||
|
||||
/**
|
||||
@@ -20,11 +20,13 @@
|
||||
"author": "https://github.com/appium",
|
||||
"files": [
|
||||
"build",
|
||||
"src",
|
||||
"schema"
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"generate-schema-declarations": "node ./scripts/generate-schema-declarations.js"
|
||||
"build": "node ./scripts/generate-schema-types.js",
|
||||
"dev": "npm run build -- --watch",
|
||||
"fix": "npm run lint -- --fix",
|
||||
"lint": "eslint -c ../../.eslintrc --ignore-path ../../.eslintignore ."
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
@@ -34,5 +36,8 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"gitHead": "ec6a90a797d2dadb407922426be16efaec9def07"
|
||||
"gitHead": "ec6a90a797d2dadb407922426be16efaec9def07",
|
||||
"dependencies": {
|
||||
"@appium/schema": "file:../schema"
|
||||
}
|
||||
}
|
||||
|
||||
+17
-8
@@ -11,21 +11,30 @@ const {promises: fs} = require('fs');
|
||||
const {info, success, error} = require('log-symbols');
|
||||
|
||||
/**
|
||||
* Path to `@appium/types` package
|
||||
* Path to `@appium/types` package root
|
||||
*/
|
||||
const TYPES_ROOT = path.join(__dirname, '..');
|
||||
|
||||
/**
|
||||
* Path to (generated) JSON schema.
|
||||
* Path to `@appium/schema` package root
|
||||
*/
|
||||
const JSON_SCHEMA_PATH = path.join(TYPES_ROOT, 'schema', 'appium-config.schema.json');
|
||||
const SCHEMA_ROOT = path.join(TYPES_ROOT, '..', 'schema');
|
||||
|
||||
/**
|
||||
* Path to generated declaration file.
|
||||
* Path to JSON schema.
|
||||
*
|
||||
* Generated by `./generate-schema-json.js`, which should be run first.
|
||||
*/
|
||||
const DECLARATIONS_PATH = path.join(
|
||||
const JSON_SCHEMA_PATH = path.join(SCHEMA_ROOT, 'lib', 'appium-config.schema.json');
|
||||
|
||||
/**
|
||||
* Path to generated file.
|
||||
*
|
||||
* This is a `.ts` file, _not_ a `.d.ts`; this is so it will be output as a `.d.ts` into `build` by `tsc`.
|
||||
*/
|
||||
const OUTPUT_PATH = path.join(
|
||||
TYPES_ROOT,
|
||||
'src',
|
||||
'lib',
|
||||
'appium-config.ts'
|
||||
);
|
||||
|
||||
@@ -38,11 +47,11 @@ async function main () {
|
||||
throw new Error(`${error} Could not convert Appium schema JSON to TypeScript: ${err.message}. Does it exist?`);
|
||||
}
|
||||
try {
|
||||
await fs.writeFile(DECLARATIONS_PATH, ts);
|
||||
await fs.writeFile(OUTPUT_PATH, ts);
|
||||
} catch (err) {
|
||||
throw new Error(`${error} Could not write Appium schema declaration file: ${err.message}`);
|
||||
}
|
||||
console.log(`${info} Wrote %s`, DECLARATIONS_PATH);
|
||||
console.log(`${info} Wrote %s`, OUTPUT_PATH);
|
||||
console.log(`${success} Done.`);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"extends": "../../config/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"rootDir": "lib",
|
||||
"outDir": "build",
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"declarationMap": true
|
||||
"paths": {
|
||||
"@appium/schema": ["../schema"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
"include": ["lib/**/*"],
|
||||
"references": [
|
||||
{"path": "../schema"}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* This script takes the JSON schema (which is actually JS) in `appium` and converts it to JSON proper,
|
||||
* then outputs the result in a couple places. It also copies the JSON schema into `@appium/types`
|
||||
* to avoid cyclical dependencies in TS.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const _ncp = require('ncp');
|
||||
const path = require('path');
|
||||
const {writeFile} = require('fs').promises;
|
||||
const {info, success, error} = require('log-symbols');
|
||||
|
||||
const ncp = require('util').promisify(_ncp);
|
||||
|
||||
/**
|
||||
* `appium` package root.
|
||||
*/
|
||||
const APPIUM_ROOT = path.join(__dirname, '..', 'packages', 'appium');
|
||||
|
||||
/**
|
||||
* Root of Appium artifacts.
|
||||
*/
|
||||
const APPIUM_BUILD_DIR = path.join(APPIUM_ROOT, 'build', 'lib');
|
||||
|
||||
/**
|
||||
* `@appium/types` package root
|
||||
*/
|
||||
const TYPES_ROOT = path.join(__dirname, '..', 'packages', 'types');
|
||||
|
||||
/**
|
||||
* Basename of exported `.json` file.
|
||||
*/
|
||||
const JSON_FILENAME = 'appium-config.schema.json';
|
||||
|
||||
/**
|
||||
* Path to source schema `.js`.
|
||||
*
|
||||
* This is the _build artifact_. Node can use ES modules, but it cannot use them unless one of two things is true:
|
||||
* - `type: module` in `package.json`
|
||||
* - file `.mjs` extension
|
||||
*
|
||||
* Neither of these things is true, so we have to use the build artifact.
|
||||
*/
|
||||
const SRC = path.join(APPIUM_BUILD_DIR, 'schema', 'appium-config-schema.js');
|
||||
|
||||
/**
|
||||
* Destination(s) for `.json` output.
|
||||
* the one in `types` is for its `generate-schema-declarations` script; the other one is for general consumer usage.
|
||||
* These paths should be in `.gitignore`
|
||||
*/
|
||||
const JSON_DESTS = [
|
||||
path.join(TYPES_ROOT, 'schema', JSON_FILENAME),
|
||||
path.join(APPIUM_BUILD_DIR, JSON_FILENAME),
|
||||
];
|
||||
|
||||
/**
|
||||
* In order to avoid a circular dependency, `@appium/types` needs this file, because it computes types from the constant sources. It is not possible to do this with a `.json` file, unfortunately.
|
||||
* Note that this is the _source_, not the build artifact. TS understands ESM better than Babel output, unsurprisingly.
|
||||
* See https://github.com/microsoft/TypeScript/issues/32063 for details
|
||||
*/
|
||||
const COPY_SRC = path.join(APPIUM_ROOT, 'lib', 'schema', 'appium-config-schema.js');
|
||||
|
||||
/**
|
||||
* It goes here. These should be in `.gitignore`
|
||||
*/
|
||||
const COPY_DESTS = [
|
||||
path.join(TYPES_ROOT, 'src', 'appium-config-schema.js')
|
||||
];
|
||||
|
||||
|
||||
async function write () {
|
||||
/** @type {typeof import('appium/lib/schema/appium-config-schema.js')} */
|
||||
let schema;
|
||||
try {
|
||||
schema = require(SRC).default;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`${error} Failed to read ${SRC}; did you execute \`npm run build\` first?`,
|
||||
);
|
||||
}
|
||||
|
||||
const json = JSON.stringify(schema, null, 2);
|
||||
|
||||
for await (const dest of JSON_DESTS) {
|
||||
try {
|
||||
await writeFile(dest, json);
|
||||
console.log(`${info} Wrote JSON schema to ${dest}`);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`${error} Failed to write JSON schema to ${dest}: ${err.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for await (const dest of COPY_DESTS) {
|
||||
try {
|
||||
await ncp(COPY_SRC, dest);
|
||||
console.log(`${info} Copied ${SRC} to ${dest}`);
|
||||
} catch (err) {
|
||||
throw new Error(`${error} Failed to copy schema module to ${dest}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main () {
|
||||
try {
|
||||
await write();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
console.log(`${success} Done.`);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {main, write};
|
||||
+21
-10
@@ -1,20 +1,31 @@
|
||||
{
|
||||
"exclude": ["packages/**/test/**", "packages/**/build/**"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./packages",
|
||||
"paths": {
|
||||
"@appium/support": ["support"],
|
||||
"@appium/base-driver": ["base-driver"],
|
||||
"appium": ["appium"],
|
||||
"@appium/types": ["types"]
|
||||
},
|
||||
"noEmit": true
|
||||
"@appium/schema": ["schema"],
|
||||
"@appium/support": ["support"],
|
||||
"@appium/types": ["types"],
|
||||
"appium": ["appium"]
|
||||
}
|
||||
},
|
||||
"exclude": ["packages/**/test/**", "packages/**/build/**"],
|
||||
"files": [],
|
||||
"references": [
|
||||
{"path": "packages/types"},
|
||||
{"path": "packages/support"},
|
||||
{"path": "packages/base-driver"},
|
||||
{"path": "packages/appium"}
|
||||
{
|
||||
"path": "packages/types"
|
||||
},
|
||||
{
|
||||
"path": "packages/support"
|
||||
},
|
||||
{
|
||||
"path": "packages/base-driver"
|
||||
},
|
||||
{
|
||||
"path": "packages/appium"
|
||||
},
|
||||
{
|
||||
"path": "packages/schema"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user