Compare commits

...
Author SHA1 Message Date
Christopher Hiller e9b50225dc chore: publish
- appium@2.0.0-beta.62
 - @appium/base-driver@9.3.6
 - @appium/base-plugin@2.2.6
 - @appium/doctor@2.0.12
 - @appium/docutils@0.3.5
 - @appium/driver-test-support@0.4.4
 - @appium/execute-driver-plugin@3.0.11
 - @appium/fake-plugin@3.1.10
 - @appium/plugin-test-support@0.3.12
 - @appium/strongbox@0.2.0
 - @appium/support@3.1.10
 - @appium/test-support@3.0.12
 - @appium/tsconfig@0.3.0
 - @appium/typedoc-plugin-appium@0.6.1
 - @appium/types@0.10.4
2023-04-10 16:43:21 -07:00
Christopher Hiller e9426fcfec fix(docutils): properly respects log levels
The resulting solution keeps a bunch of weak refs to `Consola` objects and sets the log level on all of them if it ever changes.

This is--at minimum--easier to understand than the broken `Proxy` implementation.
2023-04-10 15:58:58 -07:00
Christopher Hiller 5ab2fea576 feat(appium): make "ls" alias of "list"
This makes `ls` an alias of `list`; e.g., `appium driver ls`

While doing this I noticed a limitation of `argparser`, which is that an option (not a command) can only have a single (1) alias.  I have noted this behavior in a comment.

I also notice that we need to rewrite `ls` to be `list` ourselves, or we will have a bunch of conditionals checking for both values scattered around.

We need to use yargs...
2023-04-10 15:36:34 -07:00
Christopher Hiller 377e9825de feat(strongbox): export BaseItem
This exports `BaseItem`, the builtin implementation of `Item`.
2023-04-10 13:28:51 -07:00
renovate[bot] 116c9a66e2 chore(workflows): update egmacke/action-check-label action to v2 2023-04-10 13:01:51 -07:00
renovate[bot] 04b542cfcd chore(deps): update dependency eslint to v8.38.0 2023-04-09 08:21:43 +00:00
renovate[bot] c39be81d04 fix(support): update dependency shell-quote to v1.8.1 2023-04-08 16:49:21 +00:00
renovate[bot] efc847380a chore(deps): update dependency lint-staged to v13.2.1 2023-04-08 12:27:01 +00:00
renovate[bot] cf7b4d84af chore(docutils): update dependency mkdocs-material to v9.1.6 2023-04-08 09:33:44 +00:00
renovate[bot] 5a3666f653 chore(workflows): update egmacke/action-check-label digest to b6f12c1 2023-04-08 09:26:17 +00:00
renovate[bot] 5790924bf8 fix(execute-driver-plugin): update dependency vm2 to v3.9.15 2023-04-08 00:25:27 +00:00
Christopher Hiller 39b7cd5084 chore: update wallaby config 2023-04-07 12:38:29 -07:00
Christopher Hiller fd912346fa feat(strongbox): create @appium/strongbox
This PR creates a new package `@appium/strongbox`, which provides a generic persistence store for Appium extensions.
2023-04-07 12:38:29 -07:00
Christopher Hiller 1d5070e891 chore(ci): replace label checker action
This replaces [danielchabr/pr-labels-checker](/danielchabr/pr-labels-checker) with [egmacke/action-check-label](/egmacke/action-check-label).  There are many such actions.  Maybe this one won't give us problems.
2023-04-07 11:38:31 -07:00
Christopher Hiller 42953b2add chore(ci): revert to source repo of rossjrw/pr-preview-action
A bugfix PR of mine was merged into this repo, so we can use it again.
2023-04-07 11:31:28 -07:00
renovate[bot] d0f479f7a8 chore(workflows): update boneskull/pr-preview-action digest to 9dac5c4 2023-04-07 11:30:11 +00:00
Christopher Hiller e67890f463 chore(ci): use boneskull fork of pr-preview-action
My fork should fix the bug in the action.  See https://github.com/rossjrw/pr-preview-action/pull/36
2023-04-06 16:06:32 -07:00
renovate[bot] ff46dfa814 chore(workflows): pin rossjrw/pr-preview-action action to 9dac5c4 2023-04-06 16:06:32 -07:00
Christopher Hiller afc7e34402 chore(ci): try to fix on-hold workflow
permissions issues, but unclear which
2023-04-06 12:24:07 -07:00
Christopher Hiller eef4e3447a chore(ci): make docs preview job run in master only
since it writes to gh-pages branch
2023-04-06 12:23:58 -07:00
renovate[bot] d6c42e99c0 fix(types): update dependency type-fest to v3.8.0 2023-04-06 17:04:42 +00:00
renovate[bot] 6cf14802b7 fix(support): update dependency axios to v1.3.5 2023-04-06 13:47:58 +00:00
renovate[bot] d5090155ad chore(deps): update dependency eslint-import-resolver-typescript to v3.5.5 2023-04-06 09:56:04 +00:00
67 changed files with 1226 additions and 283 deletions
+5
View File
@@ -147,3 +147,8 @@ labels:
sync: true
matcher:
files: ['packages/universal-xml-plugin/**']
- label: '@appium/strongbox'
sync: true
matcher:
files: ['packages/strongbox/**']
+2 -18
View File
@@ -1,23 +1,7 @@
name: Build Docs
on:
push:
# this list of paths could potentially impact doc generation.
paths:
- '**/typedoc.json'
- '**/tsconfig*.json'
- '**/package*.json'
- '**/*mkdocs*.ya?ml'
- 'packages/docutils/requirements.txt'
- 'packages/*/README.md'
- 'packages/*/docs/**'
- 'packages/*/**/*.ts'
- 'packages/*/**/*.js'
- '.github/workflows/docs.yml' # this file
- '!**/test/**'
- '!**/sample-code/**'
pull_request:
pull_request_target:
paths:
- '**/typedoc.json'
- '**/tsconfig*.json'
@@ -56,7 +40,7 @@ jobs:
- name: Build Docs
run: npm run docs:preview
- name: Deploy Preview
uses: rossjrw/pr-preview-action@v1 # v1
uses: rossjrw/pr-preview-action@2a652922e9b9c53e7e5ea62fa38da744de09043c # v1
with:
source-dir: ./packages/appium/docs/site
custom-url: 'appium.github.io/appium'
+4 -9
View File
@@ -4,17 +4,12 @@ on:
types: [opened, labeled, unlabeled, synchronize]
branches: [master]
permissions: read-all
jobs:
label-check:
permissions:
pull-requests: write
checks: write
runs-on: ubuntu-latest
steps:
- uses: danielchabr/pr-labels-checker@e1d7e79aa0933af1728011705a30528a279874fd # v3.1
- name: Check for "On Hold" label
uses: egmacke/action-check-label@0eb29f801fb482a95c9bd2dd22834ecc8f4e8af9 # v2
with:
id: check-labels
hasNone: On Hold
githubToken: ${{ secrets.GITHUB_TOKEN }}
label: On Hold
state: absent
+5 -5
View File
@@ -17,9 +17,9 @@ module.exports = (wallaby) => {
},
files: [
'./packages/*/build/**/*',
'./packages/*/lib/**/*.(j|t)s',
'./packages/*/test/**/*helper*.(j|t)s',
'./packages/*/test/**/*mock*.(j|t)s',
'./packages/*/lib/**/*.{js,ts}',
'./packages/*/test/**/*helper*.{js,ts}',
'./packages/*/test/**/*mock*.{js,ts}',
'./packages/*/package.json',
'./packages/*/tsconfig*.json',
'./packages/*/test/**/fixture?(s)/**/*',
@@ -44,11 +44,11 @@ module.exports = (wallaby) => {
pattern: './packages/typedoc-plugin-appium/lib/theme/resources/**',
},
'!./packages/*/test/**/*-specs.js',
'!./packages/*/test/**/*.e2e.spec.(j|t)s',
'!./packages/*/test/**/*.e2e.spec.{js,ts}',
'!**/local_appium_home/**',
],
testFramework: 'mocha',
tests: ['./packages/*/test/unit/**/*.spec.(j|t)s', '!**/local_appium_home/**'],
tests: ['./packages/*/test/unit/**/*.spec.{js,ts}', '!**/local_appium_home/**'],
workers: {
// restart: true,
},
+124 -86
View File
@@ -34,10 +34,10 @@
"chai-as-promised": "7.1.1",
"chai-webdriverio-async": "2.7.0",
"cpy-cli": "4.2.0",
"eslint": "8.37.0",
"eslint": "8.38.0",
"eslint-config-prettier": "8.8.0",
"eslint-find-rules": "4.1.0",
"eslint-import-resolver-typescript": "3.5.4",
"eslint-import-resolver-typescript": "3.5.5",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-mocha": "10.1.0",
"eslint-plugin-promise": "6.1.1",
@@ -48,7 +48,7 @@
"husky": "8.0.3",
"json-schema-to-typescript": "12.0.0",
"lerna": "6.6.1",
"lint-staged": "13.2.0",
"lint-staged": "13.2.1",
"log-symbols": "4.1.0",
"midnight-smoker": "2.0.1",
"mjpeg-consumer": "2.0.0",
@@ -139,6 +139,10 @@
"resolved": "packages/schema",
"link": true
},
"node_modules/@appium/strongbox": {
"resolved": "packages/strongbox",
"link": true
},
"node_modules/@appium/support": {
"resolved": "packages/support",
"link": true
@@ -771,9 +775,9 @@
"license": "MIT"
},
"node_modules/@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
@@ -5620,9 +5624,9 @@
}
},
"node_modules/axios": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
"integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@@ -8018,8 +8022,8 @@
},
"node_modules/env-paths": {
"version": "2.2.1",
"dev": true,
"license": "MIT",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"engines": {
"node": ">=6"
}
@@ -8193,14 +8197,14 @@
}
},
"node_modules/eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -8472,12 +8476,13 @@
}
},
"node_modules/eslint-import-resolver-typescript": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.4.tgz",
"integrity": "sha512-9xUpnedEmSfG57sN1UvWPiEhfJ8bPt0Wg2XysA7Mlc79iFGhmJtRUg9LxtkK81FhMUui0YuR2E8iUsVhePkh4A==",
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz",
"integrity": "sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==",
"dependencies": {
"debug": "^4.3.4",
"enhanced-resolve": "^5.12.0",
"eslint-module-utils": "^2.7.4",
"get-tsconfig": "^4.5.0",
"globby": "^13.1.3",
"is-core-module": "^2.11.0",
@@ -12461,9 +12466,9 @@
"license": "MIT"
},
"node_modules/lint-staged": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.0.tgz",
"integrity": "sha512-GbyK5iWinax5Dfw5obm2g2ccUiZXNGtAS4mCbJ0Lv4rq6iEtfBSjOYdcbOtAIFtM114t0vdpViDDetjVTSd8Vw==",
"version": "13.2.1",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.1.tgz",
"integrity": "sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==",
"dev": true,
"dependencies": {
"chalk": "5.2.0",
@@ -12503,9 +12508,9 @@
}
},
"node_modules/lint-staged/node_modules/execa": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.0.0.tgz",
"integrity": "sha512-tQbH0pH/8LHTnwTrsKWideqi6rFB/QNUawEwrn+WHyz7PX1Tuz2u7wfTvbaNBdP5JD5LVWxNo8/A8CHNZ3bV6g==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz",
"integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -12526,9 +12531,9 @@
}
},
"node_modules/lint-staged/node_modules/human-signals": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.0.tgz",
"integrity": "sha512-zyzVyMjpGBX2+6cDVZeFPCdtOtdsxOeseRhB9tkQ6xXmGUNrcnBzdEKPy3VPNYz+4gy1oukVOXcrJCunSyc6QQ==",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
"integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==",
"dev": true,
"engines": {
"node": ">=14.18.0"
@@ -17270,8 +17275,9 @@
}
},
"node_modules/shell-quote": {
"version": "1.8.0",
"license": "MIT",
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -17597,6 +17603,14 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"dev": true,
@@ -19002,9 +19016,9 @@
}
},
"node_modules/type-fest": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.7.2.tgz",
"integrity": "sha512-f9BHrLjRJ4MYkfOsnC/53PNDzZJcVo14MqLp2+hXE39p5bgwqohxR5hDZztwxlbxmIVuvC2EFAKrAkokq23PLA==",
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.8.0.tgz",
"integrity": "sha512-FVNSzGQz9Th+/9R6Lvv7WIAkstylfHN2/JYxkyhhmKFYh9At2DST8t6L6Lref9eYO8PXFTfG9Sg1Agg0K3vq3Q==",
"engines": {
"node": ">=14.16"
},
@@ -19352,8 +19366,9 @@
"license": "MIT"
},
"node_modules/vm2": {
"version": "3.9.14",
"license": "MIT",
"version": "3.9.15",
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.15.tgz",
"integrity": "sha512-XqNqknHGw2avJo13gbIwLNZUumvrSHc9mLqoadFZTpo3KaNEJoe1I0lqTFhRXmXD7WkLyG01aaraXdXT0pa4ag==",
"dependencies": {
"acorn": "^8.7.0",
"acorn-walk": "^8.2.0"
@@ -20009,16 +20024,16 @@
}
},
"packages/appium": {
"version": "2.0.0-beta.61",
"version": "2.0.0-beta.62",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@appium/base-driver": "^9.3.5",
"@appium/base-plugin": "^2.2.5",
"@appium/docutils": "^0.3.4",
"@appium/base-driver": "^9.3.6",
"@appium/base-plugin": "^2.2.6",
"@appium/docutils": "^0.3.5",
"@appium/schema": "^0.2.6",
"@appium/support": "^3.1.9",
"@appium/types": "^0.10.3",
"@appium/support": "^3.1.10",
"@appium/types": "^0.10.4",
"@sidvind/better-ajv-errors": "2.1.0",
"@types/argparse": "2.0.10",
"@types/bluebird": "3.5.38",
@@ -20031,7 +20046,7 @@
"argparse": "2.0.1",
"async-lock": "1.4.0",
"asyncbox": "2.9.4",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"cross-env": "7.0.3",
"find-up": "5.0.0",
@@ -20045,7 +20060,7 @@
"semver": "7.3.8",
"source-map-support": "0.5.21",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"winston": "3.8.2",
"wrap-ansi": "7.0.0",
"yaml": "2.2.1"
@@ -20199,11 +20214,11 @@
},
"packages/base-driver": {
"name": "@appium/base-driver",
"version": "9.3.5",
"version": "9.3.6",
"license": "Apache-2.0",
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/types": "^0.10.3",
"@appium/support": "^3.1.10",
"@appium/types": "^0.10.4",
"@colors/colors": "1.5.0",
"@types/async-lock": "1.4.0",
"@types/bluebird": "3.5.38",
@@ -20212,7 +20227,7 @@
"@types/serve-favicon": "2.5.3",
"async-lock": "1.4.0",
"asyncbox": "2.9.4",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"body-parser": "1.20.2",
"es6-error": "4.1.1",
@@ -20224,7 +20239,7 @@
"morgan": "1.10.0",
"serve-favicon": "2.5.0",
"source-map-support": "0.5.21",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"validate.js": "0.13.1"
},
"engines": {
@@ -20252,23 +20267,33 @@
},
"packages/base-plugin": {
"name": "@appium/base-plugin",
"version": "2.2.5",
"version": "2.2.6",
"license": "Apache-2.0",
"dependencies": {
"@appium/base-driver": "^9.3.5",
"@appium/support": "^3.1.9"
"@appium/base-driver": "^9.3.6",
"@appium/support": "^3.1.10"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
}
},
"packages/doctor": {
"name": "@appium/doctor",
"version": "2.0.11",
"packages/clerk": {
"name": "@appium/clerk",
"version": "0.1.0",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"@appium/support": "^3.1.9",
"env-paths": "2.2.1",
"slugify": "1.6.6"
}
},
"packages/doctor": {
"name": "@appium/doctor",
"version": "2.0.12",
"license": "Apache-2.0",
"dependencies": {
"@appium/support": "^3.1.10",
"@colors/colors": "1.5.0",
"@types/bluebird": "3.5.38",
"@types/teen_process": "2.0.0",
@@ -20290,12 +20315,12 @@
},
"packages/docutils": {
"name": "@appium/docutils",
"version": "0.3.4",
"version": "0.3.5",
"license": "Apache-2.0",
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/tsconfig": "^0.2.4",
"@appium/typedoc-plugin-appium": "^0.6.0",
"@appium/support": "^3.1.10",
"@appium/tsconfig": "^0.3.0",
"@appium/typedoc-plugin-appium": "^0.6.1",
"@sliphua/lilconfig-ts-loader": "3.2.2",
"chalk": "4.1.2",
"consola": "2.15.3",
@@ -20311,7 +20336,7 @@
"semver": "7.3.8",
"source-map-support": "0.5.21",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"typedoc": "0.23.28",
"typedoc-plugin-markdown": "3.14.0",
"typedoc-plugin-resolve-crossmodule-references": "0.3.3",
@@ -20394,13 +20419,13 @@
},
"packages/driver-test-support": {
"name": "@appium/driver-test-support",
"version": "0.4.3",
"version": "0.4.4",
"license": "Apache-2.0",
"dependencies": {
"@appium/types": "^0.10.3",
"@appium/types": "^0.10.4",
"@types/lodash": "4.14.192",
"@types/stoppable": "1.1.1",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"chai": "4.3.7",
"get-port": "5.1.1",
@@ -20408,7 +20433,7 @@
"sinon": "15.0.3",
"source-map-support": "0.5.21",
"stoppable": "1.1.0",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
@@ -20467,14 +20492,14 @@
},
"packages/execute-driver-plugin": {
"name": "@appium/execute-driver-plugin",
"version": "3.0.10",
"version": "3.0.11",
"license": "Apache-2.0",
"dependencies": {
"@types/bluebird": "3.5.38",
"bluebird": "3.7.2",
"lodash": "4.17.21",
"source-map-support": "0.5.21",
"vm2": "3.9.14",
"vm2": "3.9.15",
"webdriverio": "7.30.2"
},
"engines": {
@@ -20511,11 +20536,11 @@
},
"packages/fake-plugin": {
"name": "@appium/fake-plugin",
"version": "3.1.9",
"version": "3.1.10",
"license": "Apache-2.0",
"dependencies": {
"@appium/base-plugin": "^2.2.5",
"@appium/support": "^3.1.9",
"@appium/base-plugin": "^2.2.6",
"@appium/support": "^3.1.10",
"@types/bluebird": "3.5.38",
"bluebird": "3.7.2",
"lodash": "4.17.21",
@@ -20574,10 +20599,10 @@
},
"packages/plugin-test-support": {
"name": "@appium/plugin-test-support",
"version": "0.3.11",
"version": "0.3.12",
"license": "Apache-2.0",
"dependencies": {
"@appium/types": "^0.10.3",
"@appium/types": "^0.10.4",
"get-port": "5.1.1",
"log-symbols": "4.1.0",
"source-map-support": "0.5.21",
@@ -20622,13 +20647,26 @@
"npm": ">=8"
}
},
"packages/support": {
"name": "@appium/support",
"version": "3.1.9",
"packages/strongbox": {
"name": "@appium/strongbox",
"version": "0.2.0",
"license": "Apache-2.0",
"dependencies": {
"@appium/tsconfig": "^0.2.4",
"@appium/types": "^0.10.3",
"env-paths": "2.2.1",
"slugify": "1.6.6"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
}
},
"packages/support": {
"name": "@appium/support",
"version": "3.1.10",
"license": "Apache-2.0",
"dependencies": {
"@appium/tsconfig": "^0.3.0",
"@appium/types": "^0.10.4",
"@colors/colors": "1.5.0",
"@types/archiver": "5.3.2",
"@types/base64-stream": "1.0.2",
@@ -20649,7 +20687,7 @@
"@types/teen_process": "2.0.0",
"@types/uuid": "9.0.1",
"archiver": "5.3.1",
"axios": "1.3.4",
"axios": "1.3.5",
"base64-stream": "1.0.0",
"bluebird": "3.7.2",
"bplist-creator": "0.1.1",
@@ -20677,11 +20715,11 @@
"rimraf": "3.0.2",
"sanitize-filename": "1.6.3",
"semver": "7.3.8",
"shell-quote": "1.8.0",
"shell-quote": "1.8.1",
"source-map-support": "0.5.21",
"supports-color": "8.1.1",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"uuid": "9.0.0",
"which": "3.0.0",
"yauzl": "2.10.0"
@@ -20845,10 +20883,10 @@
},
"packages/test-support": {
"name": "@appium/test-support",
"version": "3.0.11",
"version": "3.0.12",
"license": "Apache-2.0",
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/support": "^3.1.10",
"@colors/colors": "1.5.0",
"bluebird": "3.7.2",
"lodash": "4.17.21",
@@ -20867,7 +20905,7 @@
},
"packages/tsconfig": {
"name": "@appium/tsconfig",
"version": "0.2.4",
"version": "0.3.0",
"license": "Apache-2.0",
"dependencies": {
"@tsconfig/node14": "1.0.3"
@@ -20879,13 +20917,13 @@
},
"packages/typedoc-plugin-appium": {
"name": "@appium/typedoc-plugin-appium",
"version": "0.6.0",
"version": "0.6.1",
"license": "Apache-2.0",
"dependencies": {
"handlebars": "4.7.7",
"lodash": "4.17.21",
"pluralize": "8.0.0",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
@@ -20901,15 +20939,15 @@
},
"packages/types": {
"name": "@appium/types",
"version": "0.10.3",
"version": "0.10.4",
"license": "Apache-2.0",
"dependencies": {
"@appium/schema": "^0.2.6",
"@appium/tsconfig": "^0.2.4",
"@appium/tsconfig": "^0.3.0",
"@types/express": "4.17.17",
"@types/npmlog": "4.1.4",
"@types/ws": "8.5.4",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
+3 -3
View File
@@ -106,10 +106,10 @@
"chai-as-promised": "7.1.1",
"chai-webdriverio-async": "2.7.0",
"cpy-cli": "4.2.0",
"eslint": "8.37.0",
"eslint": "8.38.0",
"eslint-config-prettier": "8.8.0",
"eslint-find-rules": "4.1.0",
"eslint-import-resolver-typescript": "3.5.4",
"eslint-import-resolver-typescript": "3.5.5",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-mocha": "10.1.0",
"eslint-plugin-promise": "6.1.1",
@@ -120,7 +120,7 @@
"husky": "8.0.3",
"json-schema-to-typescript": "12.0.0",
"lerna": "6.6.1",
"lint-staged": "13.2.0",
"lint-staged": "13.2.1",
"log-symbols": "4.1.0",
"midnight-smoker": "2.0.1",
"mjpeg-consumer": "2.0.0",
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.0.0-beta.62](https://github.com/appium/appium/compare/appium@2.0.0-beta.61...appium@2.0.0-beta.62) (2023-04-10)
### Bug Fixes
* **support:** update dependency axios to v1.3.5 ([6cf1480](https://github.com/appium/appium/commit/6cf14802b70a462beffc12a1134476596060c005))
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
### Features
* **appium:** make "ls" alias of "list" ([5ab2fea](https://github.com/appium/appium/commit/5ab2fea5768ef8c67270d49c920b9515ca1ff1e4))
# [2.0.0-beta.61](https://github.com/appium/appium/compare/appium@2.0.0-beta.60...appium@2.0.0-beta.61) (2023-04-05)
**Note:** Version bump only for package appium
+1 -1
View File
@@ -294,5 +294,5 @@ export {getServerArgs, getExtensionArgs};
/**
* A tuple of argument aliases and argument options
* @typedef {Map<string[],import('argparse').ArgumentOptions>} ArgumentDefinitions
* @typedef {Map<[name: string]|[name: string, alias: string],import('argparse').ArgumentOptions>} ArgumentDefinitions
*/
+16 -5
View File
@@ -101,6 +101,13 @@ class ArgParser {
try {
const parsed = this.parser.parse_known_args(args);
const [knownArgs, unknownArgs] = parsed;
// XXX: you'd think that argparse, when given an alias for a subcommand,
// would set this value to the original subcommand name, but it doesn't.
if (knownArgs?.driverCommand === 'ls') {
knownArgs.driverCommand = 'list';
} else if (knownArgs?.pluginCommand === 'ls') {
knownArgs.pluginCommand = 'list';
}
if (
unknownArgs?.length &&
(knownArgs.driverCommand === 'run' || knownArgs.pluginCommand === 'run')
@@ -210,13 +217,14 @@ class ArgParser {
});
const extensionArgs = getExtensionArgs();
/**
* @type { {command: import('appium/types').CliExtensionSubcommand, args: import('./args').ArgumentDefinitions, help: string}[] }
* @type { {command: import('appium/types').CliExtensionSubcommand, args: import('./args').ArgumentDefinitions, help: string, aliases?: import('argparse').SubArgumentParserOptions['aliases']}[] }
*/
const parserSpecs = [
{
command: 'list',
args: extensionArgs[type].list,
help: `List available and installed ${type}s`,
aliases: ['ls'],
},
{
command: 'install',
@@ -242,15 +250,18 @@ class ArgParser {
},
];
for (const {command, args, help} of parserSpecs) {
const parser = extSubParsers.add_parser(command, {help});
for (const {command, args, help, aliases} of parserSpecs) {
const parser = extSubParsers.add_parser(command, {help, aliases: aliases ?? []});
ArgParser._patchExit(parser);
for (const [flagsOrNames, opts] of args) {
// add_argument mutates params so make sure to send in copies instead
// @ts-ignore
parser.add_argument(...flagsOrNames, {...opts});
if (flagsOrNames.length === 2) {
parser.add_argument(flagsOrNames[0], flagsOrNames[1], {...opts});
} else {
parser.add_argument(flagsOrNames[0], {...opts});
}
}
}
}
+5 -2
View File
@@ -94,7 +94,7 @@ function makeDescription(schema) {
* as understood by `argparse`.
* @param {AppiumJSONSchema} subSchema - JSON schema for the option
* @param {ArgSpec} argSpec - Argument spec tuple
* @returns {[string[], import('argparse').ArgumentOptions]} Tuple of flag and options
* @returns {[[string]|[string, string], import('argparse').ArgumentOptions]} Tuple of flag and options
*/
function subSchemaToArgDef(subSchema, argSpec) {
let {type, appiumCliAliases, appiumCliTransformer, enum: enumValues} = subSchema;
@@ -207,7 +207,10 @@ function subSchemaToArgDef(subSchema, argSpec) {
}
}
return [aliases, argOpts];
// TODO: argparse only accepts the command name and a single alias; any extra aliases
// will be silently discarded.
const finalAliases = /** @type {[string]|[string, string]} */ (aliases);
return [finalAliases, argOpts];
}
/**
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "appium",
"version": "2.0.0-beta.61",
"version": "2.0.0-beta.62",
"description": "Automation for Apps.",
"keywords": [
"automation",
@@ -60,12 +60,12 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/base-driver": "^9.3.5",
"@appium/base-plugin": "^2.2.5",
"@appium/docutils": "^0.3.4",
"@appium/base-driver": "^9.3.6",
"@appium/base-plugin": "^2.2.6",
"@appium/docutils": "^0.3.5",
"@appium/schema": "^0.2.6",
"@appium/support": "^3.1.9",
"@appium/types": "^0.10.3",
"@appium/support": "^3.1.10",
"@appium/types": "^0.10.4",
"@sidvind/better-ajv-errors": "2.1.0",
"@types/argparse": "2.0.10",
"@types/bluebird": "3.5.38",
@@ -78,7 +78,7 @@
"argparse": "2.0.1",
"async-lock": "1.4.0",
"asyncbox": "2.9.4",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"cross-env": "7.0.3",
"find-up": "5.0.0",
@@ -92,7 +92,7 @@
"semver": "7.3.8",
"source-map-support": "0.5.21",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"winston": "3.8.2",
"wrap-ansi": "7.0.0",
"yaml": "2.2.1"
+8
View File
@@ -264,6 +264,14 @@ describe('parser', function () {
const args = p.parseArgs([DRIVER_TYPE, 'list', '--updates']);
args.showUpdates.should.eql(true);
});
it('should allow "ls" as an alias for "list"', function () {
const args = p.parseArgs([DRIVER_TYPE, 'ls']);
args.subcommand.should.eql(DRIVER_TYPE);
args.driverCommand.should.eql('list');
args.showInstalled.should.eql(false);
args.showUpdates.should.eql(false);
args.json.should.eql(false);
});
});
describe('install', function () {
it('should not allow an empty argument list', function () {
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [9.3.6](https://github.com/appium/appium/compare/@appium/base-driver@9.3.5...@appium/base-driver@9.3.6) (2023-04-10)
### Bug Fixes
* **support:** update dependency axios to v1.3.5 ([6cf1480](https://github.com/appium/appium/commit/6cf14802b70a462beffc12a1134476596060c005))
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
## [9.3.5](https://github.com/appium/appium/compare/@appium/base-driver@9.3.4...@appium/base-driver@9.3.5) (2023-04-03)
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/base-driver",
"version": "9.3.5",
"version": "9.3.6",
"description": "Base driver class for Appium drivers",
"keywords": [
"automation",
@@ -44,8 +44,8 @@
"test:types": "tsd"
},
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/types": "^0.10.3",
"@appium/support": "^3.1.10",
"@appium/types": "^0.10.4",
"@colors/colors": "1.5.0",
"@types/async-lock": "1.4.0",
"@types/bluebird": "3.5.38",
@@ -54,7 +54,7 @@
"@types/serve-favicon": "2.5.3",
"async-lock": "1.4.0",
"asyncbox": "2.9.4",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"body-parser": "1.20.2",
"es6-error": "4.1.1",
@@ -66,7 +66,7 @@
"morgan": "1.10.0",
"serve-favicon": "2.5.0",
"source-map-support": "0.5.21",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"validate.js": "0.13.1"
},
"engines": {
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.6](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.5...@appium/base-plugin@2.2.6) (2023-04-10)
**Note:** Version bump only for package @appium/base-plugin
## [2.2.5](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.4...@appium/base-plugin@2.2.5) (2023-04-03)
**Note:** Version bump only for package @appium/base-plugin
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/base-plugin",
"version": "2.2.5",
"version": "2.2.6",
"description": "The base plugin used to create Appium 2.0 plugins",
"keywords": [
"automation",
@@ -40,8 +40,8 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/base-driver": "^9.3.5",
"@appium/support": "^3.1.9"
"@appium/base-driver": "^9.3.6",
"@appium/support": "^3.1.10"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.0.12](https://github.com/appium/appium/compare/@appium/doctor@2.0.11...@appium/doctor@2.0.12) (2023-04-10)
**Note:** Version bump only for package @appium/doctor
## [2.0.11](https://github.com/appium/appium/compare/@appium/doctor@2.0.10...@appium/doctor@2.0.11) (2023-04-03)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/doctor",
"version": "2.0.11",
"version": "2.0.12",
"description": "Test environment for fitness to run Appium",
"keywords": [
"automation",
@@ -44,7 +44,7 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/support": "^3.1.10",
"@colors/colors": "1.5.0",
"@types/bluebird": "3.5.38",
"@types/teen_process": "2.0.0",
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.3.5](https://github.com/appium/appium/compare/@appium/docutils@0.3.4...@appium/docutils@0.3.5) (2023-04-10)
### Bug Fixes
* **docutils:** properly respects log levels ([e9426fc](https://github.com/appium/appium/commit/e9426fcfecc1d47ab503fc72af4236c4f1ac4b1e))
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
## [0.3.4](https://github.com/appium/appium/compare/@appium/docutils@0.3.3...@appium/docutils@0.3.4) (2023-04-05)
**Note:** Version bump only for package @appium/docutils
+4 -3
View File
@@ -17,10 +17,10 @@ import {
} from '../constants';
import {DocutilsError} from '../error';
import {findMkDocsYml, readPackageJson, whichMike} from '../fs';
import logger from '../logger';
import {getLogger} from '../logger';
import {argify, spawnBackgroundProcess, SpawnBackgroundProcessOpts, stopwatch} from '../util';
const log = logger.withTag('builder:deploy');
const log = getLogger('builder:deploy');
/**
* Runs `mike serve`
@@ -124,6 +124,7 @@ export async function deploy({
// unsure about how SIGHUP is handled here
await doServe(mikeArgs, serveOpts);
} else {
log.info('Deploying into branch %s', branch);
const mikeArgs = [
...argify(
_.omitBy(
@@ -138,7 +139,7 @@ export async function deploy({
}
await doDeploy(mikeArgs, execOpts);
log.success('Mike finished deployment into branch %s (%dms)', branch, stop());
log.success('Finished deployment into branch %s (%dms)', branch, stop());
}
}
+2 -2
View File
@@ -25,11 +25,11 @@ import {
safeWriteFile,
stringifyYaml,
} from '../fs';
import logger from '../logger';
import {getLogger} from '../logger';
import {MkDocsYml, MkDocsYmlNav} from '../model';
import {relative} from '../util';
const log = logger.withTag('builder:nav');
const log = getLogger('builder:nav');
/**
* Gets a list of `.md` files relative to `docs_dir`
+2 -2
View File
@@ -16,10 +16,10 @@ import {
} from '../constants';
import {DocutilsError} from '../error';
import {findTypeDocJsonPath, readTypedocJson} from '../fs';
import logger from '../logger';
import {getLogger} from '../logger';
import {argify, relative, stopwatch} from '../util';
const log = logger.withTag('builder:reference');
const log = getLogger('builder:reference');
/**
* Executes TypeDoc _in the current process_
+5 -5
View File
@@ -5,16 +5,15 @@
* @module
*/
import {spawn, SpawnOptions} from 'node:child_process';
import path from 'node:path';
import {exec, TeenProcessExecOptions} from 'teen_process';
import {NAME_BIN, NAME_MKDOCS, NAME_MKDOCS_YML, NAME_THEME} from '../constants';
import {NAME_BIN, NAME_MKDOCS_YML, NAME_THEME} from '../constants';
import {DocutilsError} from '../error';
import {findMkDocsYml, readMkDocsYml, whichMkDocs} from '../fs';
import logger from '../logger';
import {getLogger} from '../logger';
import {relative, spawnBackgroundProcess, SpawnBackgroundProcessOpts, stopwatch} from '../util';
const log = logger.withTag('mkdocs');
const log = getLogger('mkdocs');
/**
* Runs `mkdocs serve`
@@ -81,6 +80,7 @@ export async function buildSite({
// unsure about how SIGHUP is handled here
await doServe(mkdocsArgs, serveOpts);
} else {
log.info('Building site into %s (%dms)');
await doBuild(mkdocsArgs, execOpts);
let relSiteDir;
if (siteDir) {
@@ -90,7 +90,7 @@ export async function buildSite({
log.debug('Found site_dir %s', siteDir);
relSiteDir = relative(path.dirname(mkDocsYmlPath), siteDir!);
}
log.success('MkDocs finished building into %s (%dms)', relSiteDir, stop());
log.success('Finnished building site into %s (%dms)', relSiteDir, stop());
}
}
+2 -2
View File
@@ -6,9 +6,9 @@
import {fs, util} from '@appium/support';
import _ from 'lodash';
import type {Options} from 'yargs';
import logger from '../logger';
import {getLogger} from '../logger';
const log = logger.withTag('check');
const log = getLogger('check');
/**
* Given a list of objects with `id` and `path` props, filters out the ones that do not exist
+3 -2
View File
@@ -7,11 +7,11 @@ import path from 'node:path';
import type {CommandModule, InferredOptionTypes, Options} from 'yargs';
import {buildReferenceDocs, buildSite, deploy, updateNav} from '../../builder';
import {NAME_BIN} from '../../constants';
import logger from '../../logger';
import {getLogger} from '../../logger';
import {stopwatch} from '../../util';
import {checkMissingPaths} from '../check';
const log = logger.withTag('build');
const log = getLogger('build');
enum BuildCommandGroup {
Build = 'Build Config:',
@@ -220,6 +220,7 @@ export default {
);
},
async handler(args) {
log.info('Building docs...');
const stop = stopwatch('build');
log.debug('Build command called with args: %O', args);
if (!args.site && !args.reference) {
+2 -2
View File
@@ -6,11 +6,11 @@
import _ from 'lodash';
import type {CommandModule, InferredOptionTypes, Options} from 'yargs';
import {init} from '../../init';
import logger from '../../logger';
import {getLogger} from '../../logger';
import {stopwatch} from '../../util';
import {checkMissingPaths} from '../check';
const log = logger.withTag('init');
const log = getLogger('init');
enum InitCommandGroup {
MkDocs = 'MkDocs Config:',
@@ -7,10 +7,10 @@ import {util} from '@appium/support';
import type {CommandModule, InferredOptionTypes, Options} from 'yargs';
import {DocutilsError} from '../../error';
import {DocutilsValidator, ValidationKind} from '../../validate';
import logger from '../../logger';
import {getLogger} from '../../logger';
import {checkMissingPaths} from '../check';
const log = logger.withTag('validate');
const log = getLogger('validate');
enum ValidateCommandGroup {
Behavior = 'Validation Behavior:',
+17 -5
View File
@@ -11,10 +11,11 @@ import path from 'node:path';
import YAML from 'yaml';
import parser from 'yargs-parser';
import {hideBin} from 'yargs/helpers';
import {NAME_BIN} from '../constants';
import logger from '../logger';
import {DEFAULT_LOG_LEVEL, LogLevelMap, NAME_BIN} from '../constants';
import {getLogger, initLogger, isLogLevelString} from '../logger';
import {relative} from '../util';
const log = logger.withTag('config');
const log = getLogger('config');
/**
* `lilconfig` loader for YAML
@@ -43,8 +44,19 @@ const loadEsm: Loader = (filepath: string) => import(filepath);
export async function findConfig(argv: string[] = hideBin(process.argv)) {
const preArgs = parser(argv);
if (preArgs.verbose || preArgs.logLevel === 'debug') {
log.level = LogLevel.Debug;
// if --verbose is used, set the log level to debug.
// otherwise use --log-level or the default.
let logLevel: LogLevel | keyof typeof LogLevelMap;
if (preArgs.verbose) {
logLevel = LogLevel.Debug;
} else {
// if the loglevel is valid, use it, otherwise use the default
logLevel = isLogLevelString(preArgs.logLevel) ? preArgs.logLevel : DEFAULT_LOG_LEVEL;
}
initLogger(logLevel);
if (preArgs.noConfig) {
log.debug('Not loading config because --no-config was provided');
}
return preArgs.noConfig || preArgs.help || preArgs.version
+8 -19
View File
@@ -6,7 +6,7 @@
* @module
*/
import logger from '../logger';
import {getLogger} from '../logger';
import _ from 'lodash';
import {hideBin} from 'yargs/helpers';
@@ -20,7 +20,7 @@ import {sync as readPkg} from 'read-pkg';
const pkg = readPkg({cwd: fs.findRoot(__dirname)});
const log = logger.withTag('cli');
const log = getLogger('cli');
export async function main(argv = hideBin(process.argv)) {
const config = await findConfig(argv);
@@ -56,24 +56,14 @@ export async function main(argv = hideBin(process.argv)) {
describe: 'Disable config file discovery',
},
})
.middleware([
.middleware(
/**
* Configures logging; `--verbose` implies `--log-level=debug`
* Writes a startup message
*/
(argv) => {
if (argv.verbose) {
argv.logLevel = 'debug';
log.debug('Debug logging enabled via --verbose');
}
log.level = LogLevelMap[argv.logLevel];
},
/**
* Writes a startup message, if logging is enabled
*/
async () => {
() => {
log.info(`${pkg.name} @ v${pkg.version} (Node.js ${process.version})`);
},
])
}
)
.epilog(`Please report bugs at ${pkg.bugs?.url}`)
.fail(
/**
@@ -85,8 +75,7 @@ export async function main(argv = hideBin(process.argv)) {
log.error(error.message);
} else {
y.showHelp();
console.log();
log.error(msg ?? error.message);
log.error(`\n\n${msg ?? error.message}`);
}
y.exit(1, error);
}
+2 -2
View File
@@ -12,7 +12,7 @@ import {fs} from '@appium/support';
import * as JSON5 from 'json5';
import _ from 'lodash';
import _pkgDir from 'pkg-dir';
import logger from './logger';
import {getLogger} from './logger';
import {Application, TypeDocReader} from 'typedoc';
import {
NAME_TYPEDOC_JSON,
@@ -26,7 +26,7 @@ import {
import {DocutilsError} from './error';
import {MkDocsYml} from './model';
const log = logger.withTag('fs');
const log = getLogger('fs');
/**
* Finds path to closest `package.json`
+1
View File
@@ -8,3 +8,4 @@ export * from './builder';
export * from './validate';
export * from './scaffold';
export * from './constants';
export * from './logger';
+3 -3
View File
@@ -17,7 +17,7 @@ import {exec} from 'teen_process';
import {Simplify} from 'type-fest';
import {DocutilsError} from './error';
import {createScaffoldTask, ScaffoldTaskOptions} from './scaffold';
import logger from './logger';
import {getLogger} from './logger';
import {MkDocsYml, TsConfigJson, TypeDocJson} from './model';
import _ from 'lodash';
import {stringifyJson5, stringifyYaml} from './fs';
@@ -54,8 +54,8 @@ const BASE_TSCONFIG_JSON: Readonly<TsConfigJson> = Object.freeze({
},
});
const log = logger.withTag('init');
const dryRunLog = log.withTag('dry-run');
const log = getLogger('init');
const dryRunLog = getLogger('dry-run', log);
const DEFAULT_INCLUDE = ['lib', 'test', 'index.js'];
/**
+50 -49
View File
@@ -137,57 +137,58 @@ class DocutilsReporter extends FancyReporter {
let globalLevel: LogLevel = LogLevelMap[DEFAULT_LOG_LEVEL];
/**
* The logger from which all loggers are created. This one uses a unique tag and our custom reporter.
* Type guard to see if a string is a recognized log level
* @param level any value
*/
const rootLogger = createLogProxy(
consola.create({defaults: {tag: 'docutils'}, reporters: [new DocutilsReporter()]})
);
/**
* @summary Creates a log-level-propagating proxy for a {@linkcode Consola} logger.
* @description
* Alright. So when you create a new logger via {@linkcode Consola.create}, it's basically a clone
* of its parent with a new set of options.
*
* If we change the log level of the root logger (which we do: see `cli/index.ts`), we may (almost
* certainly) have
* child loggers which: a) have already been created and b) have inherited the old/default log level
* from the root logger. We don't _want_ that (though this is likely a reasonable use case) for our
* purposes.
*
* The implementation below solves the problem by maintaining its own singleton log level value, and
* intercepts the `level` property of any logger created from the root logger.
*
* There are other ways to go about this which may be better, but this seemed pretty straightforward.
*/
function createLogProxy(logger: Consola): Consola {
return new Proxy(logger, {
get(target, prop, receiver) {
if (prop === 'level') {
return globalLevel;
}
if (prop === 'create') {
const create = Reflect.get(target, prop, receiver) as Consola['create'];
return (opts: ConsolaOptions) => createLogProxy(create.call(receiver, opts));
}
if (prop === '_defaults') {
const defaults = Reflect.get(target, prop, receiver);
return {...defaults, level: globalLevel};
}
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
if (prop === 'level') {
globalLevel = value as LogLevel;
return true;
}
return Reflect.set(target, prop, value, receiver);
},
});
export function isLogLevelString(level: any): level is keyof typeof LogLevelMap {
return level in LogLevelMap;
}
/**
* The proxied root logger
* @see {createLogProxy}
* The logger from which all loggers are created. This one uses a unique tag and our custom reporter.
*/
export default rootLogger;
const rootLogger = consola.create({
defaults: {tag: 'docutils'},
reporters: [new DocutilsReporter()],
level: globalLevel,
});
// this prevents logging before `initLogger` is called
rootLogger.pause();
/**
* A map of tags to loggers
*/
const loggers: Map<string, WeakRef<Consola>> = new Map();
export function getLogger(tag: string, parent = rootLogger) {
if (loggers.has(tag)) {
const logger = loggers.get(tag)?.deref();
if (logger) {
return logger;
}
}
const logger = parent.withTag(tag);
logger.level = globalLevel;
loggers.set(tag, new WeakRef(logger));
return logger;
}
/**
* Initialize the logging system.
*
* This should only be called once. The loglevel cannot be changed once it is set.
*
* @remarks Child loggers seem to inherit the "paused" state of the parent, so when this is called, we must resume all of them.
*/
export const initLogger = _.once((level: keyof typeof LogLevelMap | LogLevel) => {
globalLevel = isLogLevelString(level) ? LogLevelMap[level] : level;
rootLogger.level = globalLevel;
rootLogger.resume();
for (const ref of loggers.values()) {
const logger = ref.deref();
if (logger) {
logger.level = globalLevel;
logger.resume();
}
}
});
+3 -3
View File
@@ -4,7 +4,7 @@
*/
import {fs} from '@appium/support';
import logger from './logger';
import {getLogger} from './logger';
import path from 'node:path';
import {createPatch} from 'diff';
import {NormalizedPackageJson} from 'read-pkg';
@@ -15,8 +15,8 @@ import _ from 'lodash';
import {stringifyJson, readPackageJson, safeWriteFile} from './fs';
import {NAME_ERR_ENOENT, NAME_ERR_EEXIST} from './constants';
const log = logger.withTag('init');
const dryRunLog = log.withTag('dry-run');
const log = getLogger('init');
const dryRunLog = getLogger('dry-run', log);
/**
* Creates a unified patch for display in "dry run" mode
+2 -2
View File
@@ -40,7 +40,7 @@ import {
whichPython,
readMkDocsYml,
} from './fs';
import logger from './logger';
import {getLogger} from './logger';
import {MkDocsYml, PipPackage, TypeDocJson} from './model';
import {relative} from './util';
@@ -64,7 +64,7 @@ const TYPEDOC_VERSION_REGEX = /TypeDoc\s(\d+\.\d+\..+)/;
*/
const MKDOCS_VERSION_REGEX = /mkdocs,\s+version\s+(\d+\.\d+\.\S+)/;
const log = logger.withTag('validate');
const log = getLogger('validate');
/**
* The "kinds" of validation which were requested to be performed
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/docutils",
"version": "0.3.4",
"version": "0.3.5",
"description": "Documentation generation utilities for Appium and related projects",
"keywords": [
"automation",
@@ -49,9 +49,9 @@
"start": "node ./build/lib/cli/index.js"
},
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/tsconfig": "^0.2.4",
"@appium/typedoc-plugin-appium": "^0.6.0",
"@appium/support": "^3.1.10",
"@appium/tsconfig": "^0.3.0",
"@appium/typedoc-plugin-appium": "^0.6.1",
"@sliphua/lilconfig-ts-loader": "3.2.2",
"chalk": "4.1.2",
"consola": "2.15.3",
@@ -67,7 +67,7 @@
"semver": "7.3.8",
"source-map-support": "0.5.21",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"typedoc": "0.23.28",
"typedoc-plugin-markdown": "3.14.0",
"typedoc-plugin-resolve-crossmodule-references": "0.3.3",
+1 -1
View File
@@ -1,4 +1,4 @@
mkdocs==1.4.2
mkdocs-material==9.1.5
mkdocs-material==9.1.6
mkdocs-material-extensions==1.1.1
mike==1.1.2
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.4.4](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.3...@appium/driver-test-support@0.4.4) (2023-04-10)
### Bug Fixes
* **support:** update dependency axios to v1.3.5 ([6cf1480](https://github.com/appium/appium/commit/6cf14802b70a462beffc12a1134476596060c005))
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
## [0.4.3](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.2...@appium/driver-test-support@0.4.3) (2023-04-03)
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/driver-test-support",
"version": "0.4.3",
"version": "0.4.4",
"description": "Test utilities for Appium drivers",
"keywords": [
"automation",
@@ -41,10 +41,10 @@
},
"types": "./build/lib/index.d.ts",
"dependencies": {
"@appium/types": "^0.10.3",
"@appium/types": "^0.10.4",
"@types/lodash": "4.14.192",
"@types/stoppable": "1.1.1",
"axios": "1.3.4",
"axios": "1.3.5",
"bluebird": "3.7.2",
"chai": "4.3.7",
"get-port": "5.1.1",
@@ -52,7 +52,7 @@
"sinon": "15.0.3",
"source-map-support": "0.5.21",
"stoppable": "1.1.0",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"peerDependencies": {
"appium": "^2.0.0-beta.43",
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.0.11](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.10...@appium/execute-driver-plugin@3.0.11) (2023-04-10)
### Bug Fixes
* **execute-driver-plugin:** update dependency vm2 to v3.9.15 ([5790924](https://github.com/appium/appium/commit/5790924bf89d55352bd5e20b14377b2bffc0cbf1))
## [3.0.10](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.9...@appium/execute-driver-plugin@3.0.10) (2023-04-03)
**Note:** Version bump only for package @appium/execute-driver-plugin
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/execute-driver-plugin",
"version": "3.0.10",
"version": "3.0.11",
"description": "Plugin for batching and executing driver commands with Appiums",
"keywords": [
"automation",
@@ -42,7 +42,7 @@
"bluebird": "3.7.2",
"lodash": "4.17.21",
"source-map-support": "0.5.21",
"vm2": "3.9.14",
"vm2": "3.9.15",
"webdriverio": "7.30.2"
},
"peerDependencies": {
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.1.10](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.9...@appium/fake-plugin@3.1.10) (2023-04-10)
**Note:** Version bump only for package @appium/fake-plugin
## [3.1.9](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.8...@appium/fake-plugin@3.1.9) (2023-04-03)
**Note:** Version bump only for package @appium/fake-plugin
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/fake-plugin",
"version": "3.1.9",
"version": "3.1.10",
"description": "A fake Appium 2.0 plugin",
"keywords": [
"automation",
@@ -39,8 +39,8 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/base-plugin": "^2.2.5",
"@appium/support": "^3.1.9",
"@appium/base-plugin": "^2.2.6",
"@appium/support": "^3.1.10",
"@types/bluebird": "3.5.38",
"bluebird": "3.7.2",
"lodash": "4.17.21",
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.3.12](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.11...@appium/plugin-test-support@0.3.12) (2023-04-10)
**Note:** Version bump only for package @appium/plugin-test-support
## [0.3.11](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.10...@appium/plugin-test-support@0.3.11) (2023-04-03)
**Note:** Version bump only for package @appium/plugin-test-support
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/plugin-test-support",
"version": "0.3.11",
"version": "0.3.12",
"description": "Testing utilities for Appium plugins",
"keywords": [
"automation",
@@ -41,7 +41,7 @@
"test:unit": "exit 0"
},
"dependencies": {
"@appium/types": "^0.10.3",
"@appium/types": "^0.10.4",
"get-port": "5.1.1",
"log-symbols": "4.1.0",
"source-map-support": "0.5.21",
+12
View File
@@ -0,0 +1,12 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 0.2.0 (2023-04-10)
### Features
* **strongbox:** create @appium/strongbox ([fd91234](https://github.com/appium/appium/commit/fd912346fade8f29f5b4d1458828ea677d7e9fcc))
* **strongbox:** export BaseItem ([377e982](https://github.com/appium/appium/commit/377e9825de74d9929631fb331e6d348c9df0964e))
+96
View File
@@ -0,0 +1,96 @@
# @appium/strongbox
> Persistent storage for Appium extensions
## Summary
This package is intended to be used in [Appium](https://appium.io) extensions which need to persist data between Appium runs. An example of such data may be a device token or key.
`@appium/strongbox` provides a simple and extensible API for managing such data, while abstracting the underlying storage mechanism.
_Note:_ This module is not intended for storing sensitive data.
## Usage
First, create an instance of `Strongbox`:
```ts
import {strongbox} from '@appium/strongbox';
const box = strongbox('my-pkg');
```
This instance corresponds to a unique collection of data.
From here, create a placeholder for data (you will need to provide the type of data you intend to store):
```ts
const item = await box.createItem<string>('my unique name');
```
...or, if you already have the data on-hand:
```ts
const item: Buffer|string = getSomeData();
const item = await box.createItemWithContents('my unique name', data);
```
Either way, you can read its contents:
```ts
// if the item doesn't exist, this result will be undefined
const contents = await item.read();
```
Or write new data to the item:
```ts
await item.write('new stuff');
```
The last-read contents of the `Item` will be available on the `contents` property, but the value of this property is only current as of the last `read()`:
```ts
const {contents} = item;
```
## API
In lieu of actual documentation, look at the type definitions that this package ships.
## Customization
1. Create a class that implements the `Item` interface:
```ts
import {strongbox, Item} from '@appium/strongbox';
import {Foo, getFoo} from 'somewhere/else';
class FooItem implements Item<Foo> {
// ...
}
```
2. Provide this class as the `defaultCtor` option to `strongbox()`:
```ts
const box = strongbox('my-pkg', {defaultCtor: FooItem});
```
3. Use like you would any other `Strongbox` instance:
```ts
const foo: Foo = getFoo();
const item = await box.createItemWithValue('my unique name', Foo);
```
## Default Behavior, For the Curious
Out-of-the-box, a `Strongbox` instance corresponds to a directory on-disk, and each `Item` (returned by `createItem()/createItemWithContents()`) corresponds to a file within that directory.
The directory of the `Strongbox` instance is determined by the [env-paths](https://www.npmjs.com/package/env-paths) package, and is platform-specific.
## License
Copyright © 2023 OpenJS Foundation. Licensed Apache-2.0
+95
View File
@@ -0,0 +1,95 @@
import {mkdir, readFile, unlink, writeFile} from 'node:fs/promises';
import path from 'node:path';
import type {Item, ItemEncoding, Value} from '.';
import {slugify} from './util';
/**
* Base item implementation
*
* @remarks This class is not intended to be instantiated directly
* @typeParam T - Type of data stored in the `Item`
*/
export class BaseItem<T extends Value> implements Item<T> {
/**
* {@inheritdoc Item.value}
*/
protected _value?: T | undefined;
/**
* Unique slugified identifier
*/
public readonly id: string;
/**
* {@inheritdoc Item.value}
*/
public readonly value: T | undefined;
/**
* Slugifies the name
* @param name Name of instance
* @param container Slugified name of container
* @param encoding Defaults to `utf8`
*/
constructor(
public readonly name: string,
public readonly container: string,
public readonly encoding: ItemEncoding = 'utf8'
) {
this.id = path.join(container, slugify(name));
Object.defineProperties(this, {
value: {
get() {
return this._value;
},
enumerable: true,
},
_value: {
enumerable: false,
writable: true,
},
});
}
/**
* {@inheritdoc Item.read}
*/
public async read(): Promise<T | undefined> {
try {
this._value = (await readFile(this.id, {
encoding: this.encoding,
})) as T;
} catch (e) {
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
throw e;
}
}
return this._value;
}
/**
* {@inheritdoc Item.write}
*/
public async write(value: T): Promise<void> {
if (this._value !== value) {
await mkdir(path.dirname(this.id), {recursive: true});
await writeFile(this.id, value, this.encoding);
this._value = value;
}
}
/**
* {@inheritdoc Item.clear}
*/
public async clear(): Promise<void> {
try {
await unlink(this.id);
this._value = undefined;
} catch (e) {
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
throw e;
}
}
}
}
+293
View File
@@ -0,0 +1,293 @@
import envPaths from 'env-paths';
import path from 'node:path';
import {BaseItem} from './base-item';
import {slugify, slugifyPath} from './util';
/**
* Valid file encodings.
*
* `null` means the file should be read and written as a `Buffer`.
*/
export type ItemEncoding = BufferEncoding | null;
/**
* Valid value wrapped by {@linkcode Item}. Can be an encoded string or `Buffer`
*/
export type Value = string | Buffer;
/**
* An object representing a persisted item containing something of type `T` (which can be a {@linkcode Buffer} or an encoded string; see {@linkcode ItemEncoding}).
*
* A {@linkcode Item} does not know anything about where it is stored, or how it is stored.
* @typeParam T - Type of data stored in the item
*/
export interface Item<T extends Value> {
/**
* Encoding of underlying value
*/
encoding: ItemEncoding;
/**
* Slugified name
*/
id: string;
/**
* Name of item
*/
name: string;
/**
* Reads value
*/
read(): Promise<T | undefined>;
/**
* Writes value
* @param value New value
*/
write(value: T): Promise<void>;
/**
* Deletes the item.
*/
clear(): Promise<void>;
/**
* Last known value (stored in memory)
*
* @remarks A custom {@linkcode Item} meant to handle very large files should probably not implement this.
*/
value?: T | undefined;
}
/**
* Set of known `Item` encodings
* @internal
*/
const ITEM_ENCODINGS: Readonly<Set<ItemEncoding>> = new Set([
'ascii',
'utf8',
'utf-8',
'utf16le',
'ucs2',
'ucs-2',
'base64',
'base64url',
'latin1',
'binary',
'hex',
null,
]);
/**
* Type guard for encodings
* @param value any
* @returns `true` is `value` is a valid file encoding
*/
function isEncoding(value: any): value is ItemEncoding {
return ITEM_ENCODINGS.has(value);
}
/**
* @see {@linkcode StrongboxOpts}
*/
export const DEFAULT_SUFFIX = 'strongbox';
/**
* A constructor function which instantiates a {@linkcode Item}.
*/
export type ItemCtor<T extends Value> = new (
name: string,
container: string,
encoding?: ItemEncoding
) => Item<T>;
/**
* Main entry point for use of this module
*
* Manages multiple {@linkcode Item}s.
*/
export class Strongbox {
/**
* Default {@linkcode ItemCtor} to use when creating new {@linkcode Item}s
*/
protected defaultItemCtor: ItemCtor<any>;
/**
* Slugified name of this instance; corresponds to the directory name.
*
* If `dir` is provided, this value is unused.
* If `suffix` is provided, then this will be the parent directory of `suffix`.
*/
public readonly id: string;
/**
* Override the directory of this container.
*
* If this is present, both `suffix` and `containerId` are unused.
*/
public readonly container: string;
/**
* Store of known {@linkcode Item}s
* @internal
*/
protected items: Map<string, WeakRef<Item<any>>>;
/**
* Slugifies the name & determines the directory
* @param name Name of instance
* @param opts Options
*/
protected constructor(
public readonly name: string,
{
container,
suffix = DEFAULT_SUFFIX,
defaultItemCtor: defaultCtor = BaseItem,
}: StrongboxOpts = {}
) {
this.id = slugify(name);
this.defaultItemCtor = defaultCtor;
this.items = new Map();
this.container = container
? slugifyPath(container)
: path.join(envPaths(this.id).data, slugify(suffix));
}
/**
* Creates a new {@linkcode Strongbox}
* @param name Name of instance
* @param opts Options
* @returns New instance
*/
public static create(name: string, opts?: StrongboxOpts) {
return new Strongbox(name, opts);
}
/**
* Create a new {@linkcode Item}.
*
* Reads the item, if it is already persisted. Does not throw if missing.
* @param name Unique name of item
* @param encoding Encoding of item; defaults to `utf8`
* @returns New `Item`
* @typeParam T - Type of data stored in the `Item`
*/
async createItem<T extends Value>(
name: string,
ctor?: ItemCtor<T>,
encoding?: ItemEncoding
): Promise<Item<T>>;
async createItem<T extends Value>(name: string, encoding?: ItemEncoding): Promise<Item<T>>;
async createItem<T extends Value>(
name: string,
encodingOrCtor?: ItemEncoding | ItemCtor<T>,
encoding?: ItemEncoding
): Promise<Item<T>> {
if (isEncoding(encodingOrCtor)) {
encoding = encodingOrCtor;
encodingOrCtor = this.defaultItemCtor;
}
const item = new (encodingOrCtor ?? (this.defaultItemCtor as ItemCtor<T>))(
name,
this.container,
encoding
);
if (this.items.has(item.id)) {
throw new ReferenceError(`Item with id "${item.id}" already exists`);
}
try {
await item.read();
} catch (e) {
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
throw e;
}
}
this.items.set(item.id, new WeakRef(item));
return item;
}
/**
* Creates a {@linkcode Item} then immediately writes value to it.
*
* If it exists already, it will be overwritten.
* @param name Name of `Item`
* @param value File value to write
* @param ctor Specific {@linkcode ItemCtor} to use
* @param encoding File encoding
* @returns New `Item` w/ value of `value`
*/
async createItemWithValue<T extends Value>(
name: string,
value: T,
ctor: ItemCtor<T>,
encoding?: ItemEncoding
): Promise<Item<T>>;
async createItemWithValue<T extends Value>(
name: string,
value: T,
encoding?: ItemEncoding
): Promise<Item<T>>;
async createItemWithValue<T extends Value>(
name: string,
value: T,
encodingOrCtor?: ItemEncoding | ItemCtor<T>,
encoding?: ItemEncoding
): Promise<Item<T>> {
const item = isEncoding(encodingOrCtor)
? await this.createItem<T>(name, encodingOrCtor)
: await this.createItem<T>(name, encodingOrCtor, encoding);
await item.write(value);
return item;
}
/**
* Attempts to retrieve an {@linkcode Item} by its `id`.
* @param id ID of item
* @returns An `Item`, if found
*/
public getItem(id: string): Item<any> | undefined {
const ref = this.items.get(id);
return ref?.deref();
}
/**
* Clears _all_ items, as well as the container.
*/
public async clearAll(): Promise<void> {
const items = [...this.items.values()].map((ref) => ref.deref()).filter(Boolean) as Item<any>[];
await Promise.all(items.map((item) => item.clear()));
}
}
/**
* Options for {@linkcode strongbox}
*/
export interface StrongboxOpts {
/**
* Default {@linkcode Item} constructor.
*
* Unless a constructor is specified when calling {@linkcode Strongbox.createItem} or {@linkcode Strongbox.createItemWithValue}, this will be used.
* @defaultValue BaseItem
*/
defaultItemCtor?: ItemCtor<any>;
/**
* Override default container, which is chosen according to environment
*/
container?: string;
/**
* Extra subdir to append to the auto-generated file directory hierarchy.
*
* This is ignored if `container` is provided.
* @defaultValue 'strongbox'
*/
suffix?: string;
}
/**
* {@inheritdoc Strongbox.create}
*/
export const strongbox = Strongbox.create;
/**
* This can be subclassed if needed.
*/
export {BaseItem};
+10
View File
@@ -0,0 +1,10 @@
import path from 'node:path';
import slug from 'slugify';
export function slugify(value: string) {
return slug(value, {lower: true});
}
export function slugifyPath(filepath: string) {
return filepath.split(path.sep).map(slugify).join(path.sep);
}
+56
View File
@@ -0,0 +1,56 @@
{
"name": "@appium/strongbox",
"version": "0.2.0",
"description": "Persistent storage for Appium extensions",
"keywords": [
"automation",
"javascript",
"selenium",
"webdriver",
"ios",
"android",
"firefoxos",
"testing"
],
"homepage": "https://appium.io",
"bugs": {
"url": "https://github.com/appium/appium/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/appium/appium.git",
"directory": "packages/strongbox"
},
"license": "Apache-2.0",
"author": "https://github.com/appium",
"main": "./build/lib/index.js",
"types": "./build/lib/index.d.ts",
"directories": {
"lib": "lib"
},
"files": [
"build/lib",
"lib",
"tsconfig.json"
],
"scripts": {
"test": "run-p test:unit test:types",
"test:smoke": "node .",
"test:unit": "mocha \"test/unit/**/*.spec.ts\"",
"test:types": "tsd"
},
"dependencies": {
"env-paths": "2.2.1",
"slugify": "1.6.6"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
},
"publishConfig": {
"access": "public"
},
"tsd": {
"directory": "test/types"
}
}
@@ -0,0 +1,10 @@
import {expectAssignable, expectNotAssignable} from 'tsd';
import {Item, BaseItem, Value} from '../..';
expectAssignable<Item<string>>(new BaseItem('foo', 'some-container'));
expectNotAssignable<Value>(1);
expectAssignable<Value>('foo');
expectNotAssignable<Value>(true);
expectAssignable<Value>(Buffer.from('foo'));
expectNotAssignable<Value>({});
@@ -0,0 +1,156 @@
import path from 'node:path';
import rewiremock from 'rewiremock/node';
import type {Strongbox as TStrongbox, StrongboxOpts} from '../../lib';
import {createSandbox, SinonSandbox, SinonStubbedMember} from 'sinon';
import type fs from 'node:fs/promises';
const {expect} = chai;
type MockFs = {
[K in keyof typeof fs]: SinonStubbedMember<(typeof fs)[K]>;
};
describe('Strongbox', function () {
let strongbox: (name: string, opts?: StrongboxOpts) => TStrongbox;
let Strongbox: new (name: string, opts?: StrongboxOpts) => TStrongbox;
let sandbox: SinonSandbox;
let DEFAULT_SUFFIX: string;
let MockFs: MockFs = {} as any;
const DATA_DIR = '/some/dir';
beforeEach(function () {
sandbox = createSandbox();
({strongbox, DEFAULT_SUFFIX, Strongbox} = rewiremock.proxy(() => require('../../lib'), (r) => ({
// all of these props are async functions
'node:fs/promises': r
.mockThrough((prop) => {
MockFs = {...MockFs, [prop]: sandbox.stub().resolves()};
return MockFs[prop as keyof typeof fs];
})
.dynamic(), // this allows us to change the mock behavior on-the-fly
'env-paths': sandbox.stub().returns({data: DATA_DIR}),
})));
});
describe('static method', function () {
describe('create()', function () {
it('should return a new Strongbox', function () {
const box = strongbox('test');
expect(box).to.be.an.instanceOf(Strongbox);
});
});
});
describe('instance method', function () {
let box: TStrongbox;
beforeEach(function () {
box = strongbox('test');
});
describe('createItem()', function () {
describe('when a Item with the same id does not exist', function () {
describe('when the file does not exist', function () {
it('should create an empty Item', async function () {
const item = await box.createItem('SLUG test');
expect(item).to.eql({
id: '/some/dir/strongbox/slug-test',
name: 'SLUG test',
encoding: 'utf8',
value: undefined,
container: '/some/dir/strongbox',
});
});
});
describe('when the file exists', function () {
beforeEach(function () {
MockFs.readFile.resolves('foo bar');
});
it('should read its value', async function () {
const item = await box.createItem('SLUG test');
expect(item).to.eql({
id: '/some/dir/strongbox/slug-test',
name: 'SLUG test',
encoding: 'utf8',
value: 'foo bar',
container: '/some/dir/strongbox',
});
});
});
describe('when a value is written to the Item', function () {
it('should write a string value to the underlying file', async function () {
const item = await box.createItem('test');
await item.write('boo bah');
expect(MockFs.writeFile).to.have.been.calledWith(
path.join(DATA_DIR, DEFAULT_SUFFIX, 'test'),
'boo bah',
'utf8'
);
});
it('should update the underlying value', async function () {
const item = await box.createItem('test');
await item.write('boo bah');
expect(item.value).to.equal('boo bah');
});
});
});
describe('when a Item with the same id already exists', function () {
it('should throw an error', async function () {
await box.createItem('test');
await expect(box.createItem('test')).to.be.rejectedWith(
Error,
'Item with id "/some/dir/strongbox/test" already exists'
);
});
});
});
describe('clearAll()', function () {
let clear: sinon.SinonStub<never[], Promise<void>>;
beforeEach(async function () {
const item = await box.createItem<string>('SLUG test');
clear = sandbox.stub(item, 'clear');
});
it('should call clear() on each item', async function () {
await box.clearAll();
expect(clear).to.have.been.calledOnce;
});
describe('when there is some other error', function () {
beforeEach(function () {
clear.rejects(new Error('ETOOMANYGOATS'));
});
it('should reject', async function () {
await expect(box.clearAll()).to.be.rejected;
});
});
});
describe('createItemWithValue()', function () {
it('should create a Item with the given value', async function () {
const item = await box.createItemWithValue('test', 'value');
expect(item.value).to.equal('value');
});
it('should write the value to disk', async function () {
await box.createItemWithValue('test', 'value');
expect(MockFs.writeFile).to.have.been.calledWith(
path.join(DATA_DIR, DEFAULT_SUFFIX, 'test'),
'value'
);
});
});
});
afterEach(function () {
sandbox.restore();
});
});
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "@appium/tsconfig/tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "build",
"strict": true,
"types": ["node", "mocha", "chai", "chai-as-promised", "sinon-chai"]
},
"include": ["lib", "test"],
"exclude": ["**/*.test-d.ts"]
}
+13
View File
@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.1.10](https://github.com/appium/appium/compare/@appium/support@3.1.9...@appium/support@3.1.10) (2023-04-10)
### Bug Fixes
* **support:** update dependency axios to v1.3.5 ([6cf1480](https://github.com/appium/appium/commit/6cf14802b70a462beffc12a1134476596060c005))
* **support:** update dependency shell-quote to v1.8.1 ([c39be81](https://github.com/appium/appium/commit/c39be81d04b9738cd639bb5dd82adf584f691f8f))
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
## [3.1.9](https://github.com/appium/appium/compare/@appium/support@3.1.8...@appium/support@3.1.9) (2023-04-03)
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/support",
"version": "3.1.9",
"version": "3.1.10",
"description": "Support libs used across appium packages",
"keywords": [
"automation",
@@ -41,8 +41,8 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/tsconfig": "^0.2.4",
"@appium/types": "^0.10.3",
"@appium/tsconfig": "^0.3.0",
"@appium/types": "^0.10.4",
"@colors/colors": "1.5.0",
"@types/archiver": "5.3.2",
"@types/base64-stream": "1.0.2",
@@ -63,7 +63,7 @@
"@types/teen_process": "2.0.0",
"@types/uuid": "9.0.1",
"archiver": "5.3.1",
"axios": "1.3.4",
"axios": "1.3.5",
"base64-stream": "1.0.0",
"bluebird": "3.7.2",
"bplist-creator": "0.1.1",
@@ -91,11 +91,11 @@
"rimraf": "3.0.2",
"sanitize-filename": "1.6.3",
"semver": "7.3.8",
"shell-quote": "1.8.0",
"shell-quote": "1.8.1",
"source-map-support": "0.5.21",
"supports-color": "8.1.1",
"teen_process": "2.0.2",
"type-fest": "3.7.2",
"type-fest": "3.8.0",
"uuid": "9.0.0",
"which": "3.0.0",
"yauzl": "2.10.0"
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.0.12](https://github.com/appium/appium/compare/@appium/test-support@3.0.11...@appium/test-support@3.0.12) (2023-04-10)
**Note:** Version bump only for package @appium/test-support
## [3.0.11](https://github.com/appium/appium/compare/@appium/test-support@3.0.10...@appium/test-support@3.0.11) (2023-04-03)
**Note:** Version bump only for package @appium/test-support
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/test-support",
"version": "3.0.11",
"version": "3.0.12",
"description": "A collection of test utilities used across Appium packages",
"keywords": [
"automation",
@@ -45,7 +45,7 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/support": "^3.1.9",
"@appium/support": "^3.1.10",
"@colors/colors": "1.5.0",
"bluebird": "3.7.2",
"lodash": "4.17.21",
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [0.3.0](https://github.com/appium/appium/compare/@appium/tsconfig@0.2.4...@appium/tsconfig@0.3.0) (2023-04-10)
### Features
* **strongbox:** create @appium/strongbox ([fd91234](https://github.com/appium/appium/commit/fd912346fade8f29f5b4d1458828ea677d7e9fcc))
## [0.2.4](https://github.com/appium/appium/compare/@appium/tsconfig@0.2.3...@appium/tsconfig@0.2.4) (2023-02-09)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/tsconfig",
"version": "0.2.4",
"version": "0.3.0",
"description": "Shared TypeScript Config for Appium",
"main": "tsconfig.json",
"keywords": [
+2 -1
View File
@@ -16,6 +16,7 @@
"sourceMap": true,
"removeComments": false,
"strict": false,
"types": ["node"]
"types": ["node"],
"lib": ["es2020", "ES2021.WeakRef"]
}
}
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.6.1](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.0...@appium/typedoc-plugin-appium@0.6.1) (2023-04-10)
### Bug Fixes
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
# [0.6.0](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.5.4...@appium/typedoc-plugin-appium@0.6.0) (2023-04-05)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/typedoc-plugin-appium",
"version": "0.6.0",
"version": "0.6.1",
"description": "TypeDoc plugin for Appium & its extensions",
"homepage": "https://appium.io",
"license": "Apache-2.0",
@@ -63,7 +63,7 @@
"handlebars": "4.7.7",
"lodash": "4.17.21",
"pluralize": "8.0.0",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"gitHead": "8480a85ce2fa466360e0fb1a7f66628331907f02"
}
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.10.4](https://github.com/appium/appium/compare/@appium/types@0.10.3...@appium/types@0.10.4) (2023-04-10)
### Bug Fixes
* **types:** update dependency type-fest to v3.8.0 ([d6c42e9](https://github.com/appium/appium/commit/d6c42e99c08efce0b34796d5982ce379fca044d3))
## [0.10.3](https://github.com/appium/appium/compare/@appium/types@0.10.2...@appium/types@0.10.3) (2023-04-03)
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/types",
"version": "0.10.3",
"version": "0.10.4",
"description": "Various type declarations used across Appium",
"keywords": [
"automation",
@@ -39,11 +39,11 @@
},
"dependencies": {
"@appium/schema": "^0.2.6",
"@appium/tsconfig": "^0.2.4",
"@appium/tsconfig": "^0.3.0",
"@types/express": "4.17.17",
"@types/npmlog": "4.1.4",
"@types/ws": "8.5.4",
"type-fest": "3.7.2"
"type-fest": "3.8.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
+3
View File
@@ -67,6 +67,9 @@
},
{
"path": "packages/doctor"
},
{
"path": "packages/strongbox"
}
]
}
+2 -1
View File
@@ -18,7 +18,8 @@
"./packages/driver-test-support",
"./packages/test-support",
"./packages/plugin-test-support",
"./packages/opencv"
"./packages/opencv",
"./packages/strongbox"
],
"name": "Appium",
"out": "./packages/appium/docs/en/reference",