Full Code of apache/cordova-lib for AI

master 1df24469dac9 cached
278 files
745.1 KB
182.0k tokens
179 symbols
1 requests
Download .txt
Showing preview only (827K chars total). Download the full file or copy to clipboard to get everything.
Repository: apache/cordova-lib
Branch: master
Commit: 1df24469dac9
Files: 278
Total size: 745.1 KB

Directory structure:
gitextract_tgy_emxc/

├── .asf.yaml
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG_REPORT.md
│   │   ├── FEATURE_REQUEST.md
│   │   └── SUPPORT_QUESTION.md
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── ci.yml
│       └── release-audit.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .ratignore
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASENOTES.md
├── cordova-lib.js
├── eslint.config.js
├── integration-tests/
│   ├── HooksRunner.spec.js
│   ├── fetch.spec.js
│   ├── pkgJson.spec.js
│   ├── platform.spec.js
│   ├── plugin.spec.js
│   ├── plugman_fetch.spec.js
│   └── plugman_uninstall.spec.js
├── licence_checker.yml
├── package.json
├── spec/
│   ├── common.js
│   ├── cordova/
│   │   ├── build.spec.js
│   │   ├── compile.spec.js
│   │   ├── cordova-lib.spec.js
│   │   ├── emulate.spec.js
│   │   ├── fixtures/
│   │   │   ├── basePkgJson/
│   │   │   │   ├── config.xml
│   │   │   │   ├── package.json
│   │   │   │   ├── plugins/
│   │   │   │   │   └── .svn
│   │   │   │   └── www/
│   │   │   │       ├── css/
│   │   │   │       │   └── index.css
│   │   │   │       ├── index.html
│   │   │   │       ├── js/
│   │   │   │       │   └── index.js
│   │   │   │       └── spec.html
│   │   │   ├── plugins/
│   │   │   │   ├── @cordova/
│   │   │   │   │   └── plugin-test-dummy/
│   │   │   │   │       ├── package.json
│   │   │   │   │       └── plugin.xml
│   │   │   │   ├── com.plugin.withhooks/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   └── scripts/
│   │   │   │   │       ├── android/
│   │   │   │   │       │   └── androidBeforeBuild.js
│   │   │   │   │       ├── beforeBuild.bat
│   │   │   │   │       ├── beforeBuild.js
│   │   │   │   │       ├── beforeBuild.sh
│   │   │   │   │       └── windows/
│   │   │   │   │           └── windowsBeforeBuild.js
│   │   │   │   ├── cordova-lib-test-plugin/
│   │   │   │   │   ├── LICENSE
│   │   │   │   │   ├── NOTICE
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   ├── fake1/
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   ├── org.test.defaultvariables/
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   └── test/
│   │   │   │       ├── package.json
│   │   │   │       ├── plugin.xml
│   │   │   │       └── www/
│   │   │   │           └── test.js
│   │   │   ├── projectHooks/
│   │   │   │   ├── android/
│   │   │   │   │   ├── appAndroidBeforeBuild.bat
│   │   │   │   │   ├── appAndroidBeforeBuild.js
│   │   │   │   │   └── appAndroidBeforeBuild.sh
│   │   │   │   ├── appBeforeBuild02.js
│   │   │   │   ├── appBeforeBuild1.bat
│   │   │   │   ├── appBeforeBuild1.sh
│   │   │   │   ├── fail.js
│   │   │   │   ├── orderLogger.js
│   │   │   │   └── windows/
│   │   │   │       ├── appWindowsBeforeBuild.bat
│   │   │   │       ├── appWindowsBeforeBuild.js
│   │   │   │       └── appWindowsBeforeBuild.sh
│   │   │   └── projects/
│   │   │       ├── ProjectMetadata/
│   │   │       │   └── config.xml
│   │   │       └── platformApi/
│   │   │           └── platforms/
│   │   │               └── windows/
│   │   │                   └── cordova/
│   │   │                       └── Api.js
│   │   ├── platform/
│   │   │   ├── addHelper.spec.js
│   │   │   ├── getPlatformDetailsFromDir.spec.js
│   │   │   ├── index.spec.js
│   │   │   ├── list.spec.js
│   │   │   ├── listDeprecated.spec.js
│   │   │   └── remove.spec.js
│   │   ├── platforms/
│   │   │   └── platforms.spec.js
│   │   ├── plugin/
│   │   │   ├── add.getFetchVersion.spec.js
│   │   │   ├── add.spec.js
│   │   │   ├── index.spec.js
│   │   │   ├── list.spec.js
│   │   │   ├── plugin_spec_parser.spec.js
│   │   │   ├── remove.spec.js
│   │   │   └── util.spec.js
│   │   ├── prepare/
│   │   │   └── platforms.spec.js
│   │   ├── prepare.spec.js
│   │   ├── project-metadata-apis.spec.js
│   │   ├── requirements.spec.js
│   │   ├── restore-util.spec.js
│   │   ├── run.spec.js
│   │   └── util.spec.js
│   ├── fixture-helper.js
│   ├── helper.js
│   ├── helpers.js
│   ├── hooks/
│   │   └── Context.spec.js
│   ├── plugman/
│   │   ├── install.spec.js
│   │   ├── plugins/
│   │   │   ├── com.adobe.vars/
│   │   │   │   └── plugin.xml
│   │   │   ├── com.cordova.engine/
│   │   │   │   ├── megaBoringVersion
│   │   │   │   ├── megaFunVersion
│   │   │   │   └── plugin.xml
│   │   │   ├── com.cordova.engine-android/
│   │   │   │   └── plugin.xml
│   │   │   ├── dependencies/
│   │   │   │   ├── A/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── A.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── APluginCommand.h
│   │   │   │   │   │       └── APluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-a.js
│   │   │   │   ├── B/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── B.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── BPluginCommand.h
│   │   │   │   │   │       └── BPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-b.js
│   │   │   │   ├── C/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── C.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── CPluginCommand.h
│   │   │   │   │   │       └── CPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-c.js
│   │   │   │   ├── C@1.0.0/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── C.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── CPluginCommand.h
│   │   │   │   │   │       └── CPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-c.js
│   │   │   │   ├── D/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── D.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── DPluginCommand.h
│   │   │   │   │   │       └── DPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-d.js
│   │   │   │   ├── E/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── E.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── EPluginCommand.h
│   │   │   │   │   │       └── EPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-d.js
│   │   │   │   ├── F/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── F.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── FPluginCommand.h
│   │   │   │   │   │       └── FPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-f.js
│   │   │   │   ├── G/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── G.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── EPluginCommand.m
│   │   │   │   │   │       └── GPluginCommand.h
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-g.js
│   │   │   │   ├── H/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── H.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── HPluginCommand.h
│   │   │   │   │   │       └── HPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-h.js
│   │   │   │   ├── I/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── I.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── IPluginCommand.h
│   │   │   │   │   │       └── IPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-i.js
│   │   │   │   ├── README.md
│   │   │   │   ├── Test1/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test1.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test2/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test2.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test3/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test3.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test4/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test4.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── meta/
│   │   │   │   │   ├── D/
│   │   │   │   │   │   ├── plugin.xml
│   │   │   │   │   │   ├── src/
│   │   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   │   └── D.java
│   │   │   │   │   │   │   └── ios/
│   │   │   │   │   │   │       ├── DPluginCommand.h
│   │   │   │   │   │   │       └── DPluginCommand.m
│   │   │   │   │   │   └── www/
│   │   │   │   │   │       └── plugin-d.js
│   │   │   │   │   └── subdir/
│   │   │   │   │       └── E/
│   │   │   │   │           ├── plugin.xml
│   │   │   │   │           ├── src/
│   │   │   │   │           │   ├── android/
│   │   │   │   │           │   │   └── E.java
│   │   │   │   │           │   └── ios/
│   │   │   │   │           │       ├── EPluginCommand.h
│   │   │   │   │           │       └── EPluginCommand.m
│   │   │   │   │           └── www/
│   │   │   │   │               └── plugin-e.js
│   │   │   │   └── subdir/
│   │   │   │       └── E/
│   │   │   │           ├── plugin.xml
│   │   │   │           ├── src/
│   │   │   │           │   ├── android/
│   │   │   │           │   │   └── E.java
│   │   │   │           │   └── ios/
│   │   │   │           │       ├── EPluginCommand.h
│   │   │   │           │       └── EPluginCommand.m
│   │   │   │           └── www/
│   │   │   │               └── plugin-e.js
│   │   │   ├── org.test.androidonly/
│   │   │   │   ├── plugin.xml
│   │   │   │   └── www/
│   │   │   │       └── android.js
│   │   │   ├── org.test.defaultvariables/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.no.platform/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.no.scriptSrc/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.script/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.plugins.childbrowser/
│   │   │   │   ├── package.json
│   │   │   │   ├── plugin.xml
│   │   │   │   ├── src/
│   │   │   │   │   ├── android/
│   │   │   │   │   │   └── ChildBrowser.java
│   │   │   │   │   └── ios/
│   │   │   │   │       ├── ChildBrowserCommand.h
│   │   │   │   │       ├── ChildBrowserCommand.m
│   │   │   │   │       ├── ChildBrowserViewController.h
│   │   │   │   │       ├── ChildBrowserViewController.m
│   │   │   │   │       ├── ChildBrowserViewController.xib
│   │   │   │   │       ├── TargetDirTest.h
│   │   │   │   │       ├── TargetDirTest.m
│   │   │   │   │       └── preserveDirs/
│   │   │   │   │           ├── PreserveDirsTest.h
│   │   │   │   │           └── PreserveDirsTest.m
│   │   │   │   └── www/
│   │   │   │       ├── childbrowser.js
│   │   │   │       └── childbrowser_file.html
│   │   │   ├── org.test.plugins.dummyplugin/
│   │   │   │   ├── android-resource.xml
│   │   │   │   ├── extra.gradle
│   │   │   │   ├── plugin-lib/
│   │   │   │   │   ├── AndroidManifest.xml
│   │   │   │   │   ├── libFile
│   │   │   │   │   └── project.properties
│   │   │   │   ├── plugin-lib2/
│   │   │   │   │   ├── AndroidManifest.xml
│   │   │   │   │   ├── libFile
│   │   │   │   │   └── project.properties
│   │   │   │   ├── plugin.xml
│   │   │   │   ├── src/
│   │   │   │   │   ├── android/
│   │   │   │   │   │   └── DummyPlugin.java
│   │   │   │   │   └── ios/
│   │   │   │   │       ├── Custom.framework/
│   │   │   │   │       │   ├── someFheader.h
│   │   │   │   │       │   └── somebinlib
│   │   │   │   │       ├── DummyPlugin.bundle
│   │   │   │   │       ├── DummyPluginCommand.h
│   │   │   │   │       ├── DummyPluginCommand.m
│   │   │   │   │       ├── SourceWithFramework.m
│   │   │   │   │       ├── TargetDirTest.h
│   │   │   │   │       └── TargetDirTest.m
│   │   │   │   └── www/
│   │   │   │       └── dummyplugin.js
│   │   │   ├── pkgjson-test-plugin/
│   │   │   │   ├── package.json
│   │   │   │   └── plugin.xml
│   │   │   └── recursivePlug/
│   │   │       ├── asset.txt
│   │   │       ├── demo/
│   │   │       │   └── config.xml
│   │   │       ├── package.json
│   │   │       └── plugin.xml
│   │   ├── util/
│   │   │   ├── dependencies.spec.js
│   │   │   └── metadata.spec.js
│   │   └── variable-merge.spec.js
│   ├── project-test-helpers.js
│   └── support/
│       └── jasmine.json
└── src/
    ├── cordova/
    │   ├── build.js
    │   ├── clean.js
    │   ├── compile.js
    │   ├── cordova.js
    │   ├── emulate.js
    │   ├── platform/
    │   │   ├── addHelper.js
    │   │   ├── getPlatformDetailsFromDir.js
    │   │   ├── index.js
    │   │   ├── list.js
    │   │   └── remove.js
    │   ├── plugin/
    │   │   ├── add.js
    │   │   ├── index.js
    │   │   ├── list.js
    │   │   ├── plugin_spec_parser.js
    │   │   ├── remove.js
    │   │   └── util.js
    │   ├── prepare/
    │   │   └── platforms.js
    │   ├── prepare.js
    │   ├── project_metadata.js
    │   ├── requirements.js
    │   ├── restore-util.js
    │   ├── run.js
    │   ├── targets.js
    │   └── util.js
    ├── hooks/
    │   ├── Context.js
    │   ├── HooksRunner.js
    │   └── scriptsFinder.js
    ├── platforms/
    │   ├── index.js
    │   ├── platforms.js
    │   └── platformsConfig.json
    ├── plugman/
    │   ├── fetch.js
    │   ├── install.js
    │   ├── plugman.js
    │   ├── uninstall.js
    │   ├── util/
    │   │   ├── default-engines.js
    │   │   ├── dep-graph.js
    │   │   ├── dependencies.js
    │   │   └── metadata.js
    │   └── variable-merge.js
    └── util/
        └── promise-util.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .asf.yaml
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

github:
  description: Apache Cordova Tooling Library
  homepage: https://cordova.apache.org/

  labels:
    - cordova
    - mobile
    - javascript
    - nodejs
    - hacktoberfest

  features:
    wiki: false
    issues: true
    projects: true

  enabled_merge_buttons:
    squash: true
    merge: false
    rebase: false

notifications:
  commits:              commits@cordova.apache.org
  issues:               issues@cordova.apache.org
  pullrequests_status:  issues@cordova.apache.org
  pullrequests_comment: issues@cordova.apache.org


================================================
FILE: .gitattributes
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

* text=auto eol=lf


================================================
FILE: .github/ISSUE_TEMPLATE/BUG_REPORT.md
================================================
---
name: 🐛 Bug Report
about: If something isn't working as expected.

---

# Bug Report

## Problem

### What is expected to happen?



### What does actually happen?



## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->



### Command or Code
<!-- What command or code is needed to reproduce the problem? -->



### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->



### Version information
<!-- 
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins 
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->



## Checklist
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->

- [ ] I searched for existing GitHub issues
- [ ] I updated all Cordova tooling to most recent version
- [ ] I included all the necessary information above


================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
================================================
---
name: 🚀 Feature Request
about: A suggestion for a new functionality

---

# Feature Request

## Motivation Behind Feature
<!-- Why should this feature be implemented? What problem does it solve? -->



## Feature Description
<!-- 
Describe your feature request in detail
Please provide any code examples or screenshots of what this feature would look like
Are there any drawbacks? Will this break anything for existing users? 
-->



## Alternatives or Workarounds
<!-- 
Describe alternatives or workarounds you are currently using 
Are there ways to do this with existing functionality?
-->




================================================
FILE: .github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
================================================
---
name: 💬 Support Question
about: If you have a question, please check out our Slack or StackOverflow!

---

<!------------^ Click "Preview" for a nicer view! -->

Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
For usage and support questions, please check out the resources below. Thanks!

---

You can get answers to your usage and support questions about **Apache Cordova** on:

* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`

---

If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:

* **Ionic Framework**
  * [Ionic Community Forum](https://forum.ionicframework.com/)
  * [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
* **PhoneGap**
  * [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
We very much prefer issues created by using one of these templates.
-->

### Issue Type
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->

- [ ] Bug Report
- [ ] Feature Request
- [ ] Support Question

## Description

## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->

### Command or Code
<!-- What command or code is needed to reproduce the problem? -->

### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->



### Version information
<!-- 
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins 
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->



## Checklist
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->

- [ ] I searched for already existing GitHub issues about this
- [ ] I updated all Cordova tooling to their most recent version
- [ ] I included all the necessary information above


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:

http://cordova.apache.org/contribute/contribute_guidelines.html

Thanks!
-->

### Platforms affected



### Motivation and Context
<!-- Why is this change required? What problem does it solve? -->
<!-- If it fixes an open issue, please link to the issue here. -->



### Description
<!-- Describe your changes in detail -->



### Testing
<!-- Please describe in detail how you tested your changes. -->



### Checklist

- [ ] I've run the tests to see all new and existing tests pass
- [ ] I added automated test coverage as appropriate for this change
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
- [ ] I've updated the documentation if necessary


================================================
FILE: .github/workflows/ci.yml
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: Node CI

on:
  push:
    branches-ignore:
      - 'dependabot/**'
  pull_request:
    branches:
      - '*'

permissions:
  contents: read
  security-events: write

jobs:
  test:
    name: NodeJS ${{ matrix.node-version }} on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        node-version: [20.x, 22.x, 24.x]
        os: [ubuntu-latest, windows-latest, macos-15]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: Environment Information
        run: |
          node --version
          npm --version

      - uses: github/codeql-action/init@v3
        with:
          languages: javascript
          queries: security-and-quality
          config: |
            paths-ignore:
              - coverage
              - node_modules
              - spec/plugman/plugins/recursivePlug/demo

      - name: npm install and test
        run: npm cit
        env:
          CI: true

      - uses: github/codeql-action/analyze@v3

      # v4.6.0
      - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238
        if: success()
        with:
          name: ${{ runner.os }} node.js ${{ matrix.node-version }}
          token: ${{ secrets.CORDOVA_CODECOV_TOKEN }}
          fail_ci_if_error: false


================================================
FILE: .github/workflows/release-audit.yml
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: Release Auditing

on:
  push:
    branches-ignore:
      - 'dependabot/**'
  pull_request:
    branches:
      - '*'

permissions:
  contents: read

jobs:
  test:
    name: Audit Licenses
    runs-on: ubuntu-latest
    steps:
      # Checkout project
      - uses: actions/checkout@v6

      # Check license headers (v2.0.0)
      - uses: erisu/apache-rat-action@46fb01ce7d8f76bdcd7ab10e7af46e1ea95ca01c

      # Setup environment with node
      - uses: actions/setup-node@v6
        with:
          node-version: 24

      # Install node packages
      - name: npm install packages
        run: npm ci

      # Check node package licenses (v2.0.1)
      - uses: erisu/license-checker-action@99cffa11264fe545fd0baa6c13bca5a00ae608f2
        with:
          license-config: 'licence_checker.yml'
          include-asf-category-a: true


================================================
FILE: .gitignore
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage
coverage/
lcov.info
lib-cov

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# System Files
.DS_Store

# Temp files and folders
temp

# Editor related files and folders
.idea
.vscode

# Other files
**/*.swp
*.jar

# Test related files and folders
spec/plugman/plugins/recursivePlug/demo/fetch.json
spec/plugman/plugins/recursivePlug/demo/test-recursive


================================================
FILE: .npmignore
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

.*
spec
integration-tests
coverage
temp
eslint.config.js
licence_checker.yml

# Output of 'npm pack'
*.tgz


================================================
FILE: .npmrc
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

registry=https://registry.npmjs.org


================================================
FILE: .ratignore
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

.git/
coverage/
node_modules/
spec/cordova/fixtures/
spec/plugman/plugins/


================================================
FILE: CONTRIBUTING.md
================================================
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
-->

# Contributing to Apache Cordova

Anyone can contribute to Cordova. And we need your contributions.

There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
  
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).

The details are explained there, but the important items are:
 - Check for Github issues that corresponds to your contribution and link or create them if necessary.
 - Run the tests so your patch doesn't break existing functionality.

We look forward to your contributions!



================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: NOTICE
================================================
Apache Cordova
Copyright 2012 The Apache Software Foundation

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).


================================================
FILE: README.md
================================================
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
-->

[![Build status](https://ci.appveyor.com/api/projects/status/hovrl5rwj03co6oa/branch/master?svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-lib/branch/master)
[![Build Status](https://travis-ci.org/apache/cordova-lib.svg?branch=master)](https://travis-ci.org/apache/cordova-lib)
[![Code coverage](https://codecov.io/github/apache/cordova-lib/coverage.svg?branch=master)](https://codecov.io/github/apache/cordova-lib?branch=master)
[![NPM](https://nodei.co/npm/cordova.png)](https://nodei.co/npm/cordova/)

# cordova-lib
Contains npm modules used primarily by [cordova](https://github.com/apache/cordova-cli/) and [plugman](https://github.com/apache/cordova-plugman/).

## Setup from a cloned repo
* Clone this repository onto your local machine.
    `git clone https://github.com/apache/cordova-lib.git`
* Install dependencies and npm-link
    `npm install && npm link`

## Setup from npm
* `npm install cordova-lib`

> Note: you will likely also want to get github.com/apache/cordova-common, github.com/apache/cordova-create, github.com/apache/cordova-serve which previously lived in this repo but have since been moved.

## npm commands

This package exposes the following commands;

* `npm run lint` - runs a linter (eslint) on relevant source and test code
* `npm run unit-tests` - runs the unit tests (via jasmine) from the `spec/` directory
* `npm run cover` - runs istanbul code coverage tool to measure unit test code coverage
* `npm run e2e-tests` - runs heavy integration tests from the `integration-tests/` directory (WARNING: these take a long time to run and rely on file and network I/O)
* `npm test` - shortcut for running the linter, the unit tests and the integration tests


================================================
FILE: RELEASENOTES.md
================================================
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
-->
# Cordova-lib Release Notes

### 13.0.0 (Oct 29, 2025)

**Breaking Changes:**

* [GH-964](https://github.com/apache/cordova-lib/pull/964) chore(npm)!: bump `write-file-atomic@7.0.0`
* [GH-961](https://github.com/apache/cordova-lib/pull/961) chore!: update dependencies & node requirement
* [GH-957](https://github.com/apache/cordova-lib/pull/957) feat!: remove `cordova serve` command
* [GH-955](https://github.com/apache/cordova-lib/pull/955) chore(npm)!: bump various packages
* [GH-953](https://github.com/apache/cordova-lib/pull/953) feat(plugman)!: remove `create plugin` support
* [GH-949](https://github.com/apache/cordova-lib/pull/949) chore!: bump node requirement & npm dependencies
* [GH-958](https://github.com/apache/cordova-lib/pull/958) chore!: remove deprecated platform data
* [GH-959](https://github.com/apache/cordova-lib/pull/959) chore!: remove unused templates

**Features:**

* [GH-952](https://github.com/apache/cordova-lib/pull/952) feat: replace `dep-graph` dependency w/ custom class

**Fixes:**

* [GH-944](https://github.com/apache/cordova-lib/pull/944) fix(emulator): Support listing emulators with `--list`

**Chores:**

* [GH-963](https://github.com/apache/cordova-lib/pull/963) chore: update `package-lock.json`
* [GH-960](https://github.com/apache/cordova-lib/pull/960) chore: various updates to the root files
* [GH-956](https://github.com/apache/cordova-lib/pull/956) chore(npm): bump `@cordova/eslint-config@6.0.0`
* [GH-946](https://github.com/apache/cordova-lib/pull/946) chore(deps-dev): bump `brace-expansion` from 1.1.11 to 1.1.12
* [GH-939](https://github.com/apache/cordova-lib/pull/939) chore(deps): bump `path-to-regexp` and express
* [GH-937](https://github.com/apache/cordova-lib/pull/937) chore(deps): bump `cross-spawn` from 7.0.3 to 7.0.6
* [GH-938](https://github.com/apache/cordova-lib/pull/938) chore(ci): Fix failing dependabot PRs

**CI & Others:**

* [GH-954](https://github.com/apache/cordova-lib/pull/954) ci: various workflow improvements
* [GH-950](https://github.com/apache/cordova-lib/pull/950) ci(workflow): update release-audit & license config
* [GH-945](https://github.com/apache/cordova-lib/pull/945) ci: Add node 22 and 24 to CI testing matrix
* [GH-941](https://github.com/apache/cordova-lib/pull/941) Keep final new line in `package.json`
* [GH-942](https://github.com/apache/cordova-lib/pull/942) Persist relative paths on disk

### 12.0.2 (Oct 29, 2024)

**Fixes:**

* [GH-935](https://github.com/apache/cordova-lib/pull/935) fix: platform & plugin prerelease package support
* [GH-933](https://github.com/apache/cordova-lib/pull/933) fix(ios): Prevent mix build phases
* [GH-913](https://github.com/apache/cordova-lib/pull/913) fix: uninstalling plugin with platform separated required variables

**Chores:**

* [GH-934](https://github.com/apache/cordova-lib/pull/934) chore(deps): bump cookie and express
* [GH-928](https://github.com/apache/cordova-lib/pull/928) chore(deps): bump micromatch from 4.0.5 to 4.0.8
* [GH-925](https://github.com/apache/cordova-lib/pull/925) chore(deps): bump braces from 3.0.2 to 3.0.3
* [GH-924](https://github.com/apache/cordova-lib/pull/924) chore(deps): Update some dependencies, add Node 20 to CI

**CI:**

* [GH-926](https://github.com/apache/cordova-lib/pull/926) ci(release-audit): add license header and dependency checker
* [GH-923](https://github.com/apache/cordova-lib/pull/923) ci: update codecov@v4 w/ token

### 12.0.1 (May 19, 2023)

* [GH-918](https://github.com/apache/cordova-lib/pull/918) fix: platform add with tarball & directory

### 12.0.0 (May 13, 2023)

**Features:**

* [GH-917](https://github.com/apache/cordova-lib/pull/917) feat!(`run`): call platform api to list targets
* [GH-894](https://github.com/apache/cordova-lib/pull/894) feat!: remove platform pinning
* [GH-896](https://github.com/apache/cordova-lib/pull/896) feat!: remove **OSX** & **Windows** platform

**Dependencies:**

* [GH-915](https://github.com/apache/cordova-lib/pull/915) dep!: bump `@cordova/eslint-config@latest@5.0.0` w/ automatic fix
* [GH-914](https://github.com/apache/cordova-lib/pull/914) dep!: packages upgrade & requirements
  * Bumped Packages
    * `cordova-common@5.0.0`
    * `cordova-fetch@4.0.0`
    * `cordova-serve@4.0.1`
    * `init-package-json@5.0.0`
    * `jasmine@4.6.0`
    * `semver@7.5.0`
  * Rebuilt `package-lock.json`
  * Bumped `node` engine requirement `>=16.13.0`
* [GH-910](https://github.com/apache/cordova-lib/pull/910) dep(npm): bump all dependencies to next major
  * `fs-extra@^11.1.0`
  * `write-file-atomic@^5.0.0`
  * `cordova-android@^11.0.0`
  * `jasmine@^4.5.0`
  * `jasmine-spec-reporter@^7.0.0`
  * `rewire@^6.0.0`
  * `init-package-json@^4.0.1`

**Others:**

* [GH-916](https://github.com/apache/cordova-lib/pull/916) fix(node-18): hook tests
* [GH-905](https://github.com/apache/cordova-lib/pull/905) ci(workflow): update codecov action usage
* [GH-903](https://github.com/apache/cordova-lib/pull/903) ci(workflow): update node support & action dependencies
* [GH-911](https://github.com/apache/cordova-lib/pull/911) test: temporary disable broken spec#012

### 11.1.0 (Dec 26, 2022)

* [GH-904](https://github.com/apache/cordova-lib/pull/904) dep(npm): bump `cordova-fetch@3.1.0` w/ package-lock rebuild
* [GH-901](https://github.com/apache/cordova-lib/pull/901) feat: bump dependencies to latest minor & patch revision
  * `fs-extra@^10.1.0`
  * `globby@^11.1.0`
  * `semver@^7.3.8`
  * `cordova-android@10.1.2`
  * `jasmine@^3.99.0`
* [GH-899](https://github.com/apache/cordova-lib/pull/899) feat: bump `cordova-common@4.1.0`
* [GH-852](https://github.com/apache/cordova-lib/pull/852) feat(windows): deprecate platform
* [GH-851](https://github.com/apache/cordova-lib/pull/851) feat(osx): deprecate platform

### 11.0.0 (Dec 14, 2021)

* [GH-889](https://github.com/apache/cordova-lib/pull/889) bump(platform): bump **Electron** & **Android** to latest release
* [GH-890](https://github.com/apache/cordova-lib/pull/890) chore: rebuild `package-lock`
* [GH-888](https://github.com/apache/cordova-lib/pull/888) dep(dev)!: bump `@cordova/eslint-config@^4.0.0` w/ fix
* [GH-887](https://github.com/apache/cordova-lib/pull/887) dep!: update dependencies
* [GH-873](https://github.com/apache/cordova-lib/pull/873) ci: switch to GitHub Actions
* [GH-884](https://github.com/apache/cordova-lib/pull/884) chore!: drop support for Node.js 10

### 10.1.0 (Sep 29, 2021)

**Features:**

* [GH-885](https://github.com/apache/cordova-lib/pull/885) feat: bump platform pinning
* [GH-860](https://github.com/apache/cordova-lib/pull/860) feat(`cordova/util`): support loading platform API from `node_modules`

**Fixes:**

* [GH-880](https://github.com/apache/cordova-lib/pull/880) fix(`restore-util`): properly support long and short platform names
* [GH-874](https://github.com/apache/cordova-lib/pull/874) fix: Platforms restored from both dev and normal dependencies.
* [GH-871](https://github.com/apache/cordova-lib/pull/871) fix: remove undeclared dependency on `underscore`
* [GH-856](https://github.com/apache/cordova-lib/pull/856) fix(`cordova/util`): version detection for legacy platforms

**Chores & Refactor Changes:**

* [GH-886](https://github.com/apache/cordova-lib/pull/886) chore: update dependencies w/ `package-lock` rebuild & test update
* [GH-881](https://github.com/apache/cordova-lib/pull/881) chore: `npmrc`
* [GH-879](https://github.com/apache/cordova-lib/pull/879) chore: `package-lock` update
* [GH-858](https://github.com/apache/cordova-lib/pull/858) chore: clean up `package.json`
* [GH-882](https://github.com/apache/cordova-lib/pull/882) refactor(`addHelper`): more concise `package.json` spec lookup

**CI, Test & Doc Changes:**

* [GH-862](https://github.com/apache/cordova-lib/pull/862) ci: add node-14.x to workflow
* [GH-870](https://github.com/apache/cordova-lib/pull/870) test(`plugin.spec`): fix version change in test fixture
* [GH-865](https://github.com/apache/cordova-lib/pull/865) test(`pkgJson`): make expectations work for npm 5 to 7
* [GH-864](https://github.com/apache/cordova-lib/pull/864) test(`pkgJson`): fix test after release of geolocation plugin v4.1.0
* [GH-855](https://github.com/apache/cordova-lib/pull/855) test: fix missing stack traces in jasmine output
* [GH-853](https://github.com/apache/cordova-lib/pull/853) test: unit test deprecated platforms
* [GH-877](https://github.com/apache/cordova-lib/pull/877) docs: correct linter command in `README`

### 10.0.0 (Jul 22, 2020)

* [GH-846](https://github.com/apache/cordova-lib/pull/846) breaking: remove `cordova info` logic from `lib`
* [GH-849](https://github.com/apache/cordova-lib/pull/849) breaking: bump dependencies
* [GH-847](https://github.com/apache/cordova-lib/pull/847) chore: update dev dependencies
* [GH-848](https://github.com/apache/cordova-lib/pull/848) chore: bump `cordova-eslint` w/ automatic fixes
* [GH-843](https://github.com/apache/cordova-lib/pull/843) test(`fixture-helper`): install **Android** platform by name again
* [GH-844](https://github.com/apache/cordova-lib/pull/844) fix: remove unused dependency on `cordova-create`
* [GH-841](https://github.com/apache/cordova-lib/pull/841) chore: add `package-lock.json`
* [GH-840](https://github.com/apache/cordova-lib/pull/840) chore: use short notation in `package.json`
* [GH-839](https://github.com/apache/cordova-lib/pull/839) chore: stop testing with nightly
* [GH-838](https://github.com/apache/cordova-lib/pull/838) chore: update **Android** platform pinning to 9.0.0
* [GH-837](https://github.com/apache/cordova-lib/pull/837) chore: update **OSX** platform pinning to 6.0.0
* [GH-836](https://github.com/apache/cordova-lib/pull/836) chore: update **iOS** platform pinning to 6.1.0
* [GH-835](https://github.com/apache/cordova-lib/pull/835) GH-832: Look at devDeps for restoring platforms
* [GH-833](https://github.com/apache/cordova-lib/pull/833) breaking: upgrade cordova dependencies for next major
* [GH-831](https://github.com/apache/cordova-lib/pull/831) test: use `expectAsync` for rejections
* [GH-825](https://github.com/apache/cordova-lib/pull/825) test(e2e): improve `HooksRunner.spec`
* [GH-828](https://github.com/apache/cordova-lib/pull/828) chore: consolidate eslint configs
* [GH-803](https://github.com/apache/cordova-lib/pull/803) test: move `cordova/platform/{platform => addHelper}`
* [GH-827](https://github.com/apache/cordova-lib/pull/827) fix: plugin installation from `git` url w/ `semver`
* [GH-826](https://github.com/apache/cordova-lib/pull/826) test: use `fs.copySync` for increased performance
* [GH-823](https://github.com/apache/cordova-lib/pull/823) test(e2e): re-enable HooksRunner#12 and move it to plugin#14
* [GH-824](https://github.com/apache/cordova-lib/pull/824) style: fix linting violations
* [GH-821](https://github.com/apache/cordova-lib/pull/821) feat: proper support for scoped plugins
* [GH-822](https://github.com/apache/cordova-lib/pull/822) refactor: `eslint` setup
* [GH-820](https://github.com/apache/cordova-lib/pull/820) refactor: remove stub interface to `cordova-create`
* [GH-819](https://github.com/apache/cordova-lib/pull/819) refactor: use `execa`'s cross-platform shebang support in `HooksRunner`
* [GH-812](https://github.com/apache/cordova-lib/pull/812) chore: replace `superspawn` with `execa`
* [GH-781](https://github.com/apache/cordova-lib/pull/781) chore: remove `plugin save`
* [GH-780](https://github.com/apache/cordova-lib/pull/780) chore: deprecate `plugin save` command
* [GH-818](https://github.com/apache/cordova-lib/pull/818) Extend and improve plugin tests in preparation of supporting scoped plugins
* [GH-810](https://github.com/apache/cordova-lib/pull/810) chore: bump production dependencies
* [GH-816](https://github.com/apache/cordova-lib/pull/816) Simplify `jasmine` configuration
* [GH-817](https://github.com/apache/cordova-lib/pull/817) Remove dead code in `integration-tests/plugin.spec`
* [GH-815](https://github.com/apache/cordova-lib/pull/815) Do not spawn child process to get platform version
* [GH-813](https://github.com/apache/cordova-lib/pull/813) `plugman_fetch.spec` cleanup
* [GH-814](https://github.com/apache/cordova-lib/pull/814) Remove obsolete and duplicate ignore entries
* [GH-809](https://github.com/apache/cordova-lib/pull/809) chore: improve npm ignore list
* [GH-811](https://github.com/apache/cordova-lib/pull/811) chore: update `jasmine` dependencies
* [GH-808](https://github.com/apache/cordova-lib/pull/808) Remove unused module plugman/platforms/common
* [GH-807](https://github.com/apache/cordova-lib/pull/807) Break dependency cycles
* [GH-804](https://github.com/apache/cordova-lib/pull/804) Fix `cordova/emulate.spec`
* [GH-806](https://github.com/apache/cordova-lib/pull/806) Remove unused exports from `cordova/util`
* [GH-805](https://github.com/apache/cordova-lib/pull/805) Remove support for obsolete `<project>/.cordova/config.json`
* [GH-802](https://github.com/apache/cordova-lib/pull/802) Minor code cleanup
* [GH-797](https://github.com/apache/cordova-lib/pull/797) Do not run legacy hooks from dirs anymore
* [GH-800](https://github.com/apache/cordova-lib/pull/800) Remove `platform.check`
* [GH-765](https://github.com/apache/cordova-lib/pull/765) Remove code to handle plugins that were added by cordova@<5.4.0
* [GH-766](https://github.com/apache/cordova-lib/pull/766) Remove parts of plugman that have been moved to the plugman repo
* [GH-772](https://github.com/apache/cordova-lib/pull/772) Replace underscore with modern JS
* [GH-799](https://github.com/apache/cordova-lib/pull/799) chore: drop node 6 and 8 support
* [GH-798](https://github.com/apache/cordova-lib/pull/798) chore: bump version to 10.0.0-dev
* [GH-770](https://github.com/apache/cordova-lib/pull/770) Use up-to-date fixtures in tests
* [GH-796](https://github.com/apache/cordova-lib/pull/796) HooksRunner code & spec cleanup
* [GH-791](https://github.com/apache/cordova-lib/pull/791) fix: error message during plugin installation w/ missing engine
* [GH-777](https://github.com/apache/cordova-lib/pull/777) chore: add Node.js 12 to CI services
* [GH-786](https://github.com/apache/cordova-lib/pull/786) Quick workaround for e2e failure on AppVeyor CI
* [GH-783](https://github.com/apache/cordova-lib/pull/783) `nyc@14` update in devDependencies
* [GH-775](https://github.com/apache/cordova-lib/pull/775) chore: cleanup `plugman.createPackageJson`
* [GH-767](https://github.com/apache/cordova-lib/pull/767) Simpler and better `cordova/util.getPlatformApiFunction`
* [GH-774](https://github.com/apache/cordova-lib/pull/774) Make `src/plugman/init-defaults.js` lintable
* [GH-773](https://github.com/apache/cordova-lib/pull/773) Have `plugman.createPackageJson` create file in plugin dir, not in cwd
* [GH-771](https://github.com/apache/cordova-lib/pull/771) Prevent masking of errors during testing
* [GH-768](https://github.com/apache/cordova-lib/pull/768) Proper async code in `src/plugman/createpackagejson.js`
* [GH-764](https://github.com/apache/cordova-lib/pull/764) chore: expressive `pkgJson.spec`
* [GH-763](https://github.com/apache/cordova-lib/pull/763) Remove unnecessary spy
* [GH-762](https://github.com/apache/cordova-lib/pull/762) Remove unused fixtures
* [GH-761](https://github.com/apache/cordova-lib/pull/761) chore: various test improvements
  * Fix some test descriptions in `cordova/util.spec`
  * Stop `cordova/util.spec` from messing with the user's home directory!
  * Proper temp folder usage in `cordova/util.spec`
  * Remove outdated test from `cordova/util.spec`
  * Remove `rewire`/`revert` anti-pattern
  * Remove `superspawn` faking from `HooksRunner.spec`
* [GH-760](https://github.com/apache/cordova-lib/pull/760) Minor cleanup of CI configs

### 9.0.1 (Mar 31, 2019)
* [GH-759](https://github.com/apache/cordova-lib/pull/759) Fix faulty Promise handling in plugman.uninstall
* [GH-752](https://github.com/apache/cordova-lib/pull/752) Fix restoring plugins from `package.json`
* [GH-754](https://github.com/apache/cordova-lib/issues/754) [GH-755](https://github.com/apache/cordova-lib/issues/755) Do not wrap engine script path in quotes

### 9.0.0 (Mar 15, 2019)

* [GH-750](https://github.com/apache/cordova-lib/pull/750) Remove saving platforms/plugins to `config.xml`
* [GH-751](https://github.com/apache/cordova-lib/pull/751) Pass project `config.xml` path to platform's prepare
* [GH-749](https://github.com/apache/cordova-lib/pull/749) Cordova Lib Release Preparation (Cordova 9)
  * Remove unused property `apiCompatibleSince` from `platformsConfig.json`
  * Fix plugin dependency tests when using `npm >= 5`
  * Bumped Platform Pinning and Support Minor SemVer
    * `cordova-android@^8.0.0`
    * `cordova-browser@^6.0.0`
    * `cordova-electron@^1.0.0`
    * `cordova-ios@^5.0.0`
    * `cordova-osx@^5.0.0`
    * `cordova-windows@^7.0.0`
  * Bumped dependencies
    * `jasmine@^3.3.1`
    * `globby@^9.1.0`
    * `underscore@^1.9.1`
    * `semver@^5.6.0`
    * `read-chunk@^3.1.0`
    * `init-package-json@^1.10.3`
    * `fs-extra@^7.0.1`
  * Dev Dependencies
    * Updated `nyc` Code Coverage
    * Updated ESlint with lint corrections
    * Added missing module `shelljs` to fix test failures
  * Updated Package Cordova Dependencies
    * `cordova-common@^3.1.0`
    * `cordova-create@^2.0.0`
    * `cordova-fetch@^2.0.0`
    * `cordova-serve@^3.0.0`
* [GH-748](https://github.com/apache/cordova-lib/pull/748) Remove handling of legacy `.fetch.json` files
* [GH-709](https://github.com/apache/cordova-lib/pull/709) `hooks/Context` Improvements
* [GH-622](https://github.com/apache/cordova-lib/pull/622) [CB-14166](https://issues.apache.org/jira/browse/CB-14166) (cli) Fixed issue when install plugins on **Windows**
* [GH-744](https://github.com/apache/cordova-lib/pull/744) Add **Electron** Platform
* [GH-743](https://github.com/apache/cordova-lib/pull/743) Updated Platform Config Git URL Paths
* [GH-742](https://github.com/apache/cordova-lib/pull/742) Cleanup indentation spacing in `*/jasmine.json`
* [GH-741](https://github.com/apache/cordova-lib/pull/741) Fix crash in `cordova requirements` due to an unbound function
* [GH-711](https://github.com/apache/cordova-lib/pull/711) Fix 2 integration tests failures on **macOS**
* [GH-710](https://github.com/apache/cordova-lib/pull/710) Drop `Q` Dependency and Use Native Promises
* [GH-687](https://github.com/apache/cordova-lib/pull/687) Test, Fix and Cleanup `cordova serve`
* [GH-707](https://github.com/apache/cordova-lib/pull/707) Deprecate `requireCordovaModule` for non-Cordova modules
* [GH-705](https://github.com/apache/cordova-lib/pull/705) Dereference possible symlinks when copying plugin
* [GH-699](https://github.com/apache/cordova-lib/pull/699) Increase timeout for `cordova.platform` e2e tests
* [GH-698](https://github.com/apache/cordova-lib/pull/698) Increase plugman install test timeout
* [GH-686](https://github.com/apache/cordova-lib/pull/686) Remove support for old option format
* [GH-685](https://github.com/apache/cordova-lib/pull/685) Remove unused dependency `properties-parser`
* [GH-677](https://github.com/apache/cordova-lib/pull/677) Fix `cordova/platform/addHelper` tests
* [GH-679](https://github.com/apache/cordova-lib/pull/679) `platform.spec` Cleanup
* [GH-684](https://github.com/apache/cordova-lib/pull/684) Code Cleanup and Refactor (Bits and pieces)
* [GH-683](https://github.com/apache/cordova-lib/pull/683) Remove unused npm utility functions
* [GH-682](https://github.com/apache/cordova-lib/pull/682) GH-676 Remove Browserify
* [GH-652](https://github.com/apache/cordova-lib/pull/652) Make `plugin.remove` more easily understandable
* [GH-650](https://github.com/apache/cordova-lib/pull/650) Make `cordova/platform/check` more approachable
* [GH-678](https://github.com/apache/cordova-lib/pull/678) Fix tests that are failing with npm config 'save-exact' set
* [GH-675](https://github.com/apache/cordova-lib/pull/675) One root `describe` per suite
* [GH-674](https://github.com/apache/cordova-lib/pull/674) `plugman/install.spec` Cleanup
* [GH-672](https://github.com/apache/cordova-lib/pull/672) `plugman_uninstall.spec` Cleanup
* [GH-613](https://github.com/apache/cordova-lib/pull/613) Switch to using `fs-extra` in favour of `shelljs`
* [GH-665](https://github.com/apache/cordova-lib/pull/665) Radically focused `restore.spec` finally fast and reliable
* [GH-671](https://github.com/apache/cordova-lib/pull/671) Remove `cordova plugin search` command
* [GH-670](https://github.com/apache/cordova-lib/pull/670) Various `spec` fixes and cleanup
* [GH-666](https://github.com/apache/cordova-lib/pull/666) Remove deprecated and unused content
* [GH-669](https://github.com/apache/cordova-lib/pull/669) Linting Improvements
* [GH-668](https://github.com/apache/cordova-lib/pull/668) Only upload coverage when tests succeed
* [GH-667](https://github.com/apache/cordova-lib/pull/667) Report Code Coverage to `codecov` on Travis CI
* [GH-664](https://github.com/apache/cordova-lib/pull/664) Move some cordova test fixtures into fixtures folder
* [GH-651](https://github.com/apache/cordova-lib/pull/651) Remove all usage of Q-specific methods on Promise instances
* [GH-662](https://github.com/apache/cordova-lib/pull/662) Remove unused content
* [GH-663](https://github.com/apache/cordova-lib/pull/663) Update `read-chunk` to properly close file descriptors on failure
* [GH-658](https://github.com/apache/cordova-lib/pull/658) Remove deprecated platform support files
* [GH-616](https://github.com/apache/cordova-lib/pull/616) Extend and improve `cordova info` output

### 8.0.0 (Dec 14, 2017)
* [CB-13057](https://issues.apache.org/jira/browse/CB-13057): removed `cordova save` command
* [CB-13056](https://issues.apache.org/jira/browse/CB-13056): removed support for **WebOS**, **BlackBerry10**, and **Ubuntu**
* [CB-13674](https://issues.apache.org/jira/browse/CB-13674): updated cordova dependencies
* [CB-13055](https://issues.apache.org/jira/browse/CB-13055): updated integration tests, removed `lazy_load.js`, removed `gitclone.js` and `--nofetch` flag. This removes the need for us to include an npm dependency.
* [CB-13532](https://issues.apache.org/jira/browse/CB-13532): updated to include a check for `package.json` `devDependencies`
* [CB-12361](https://issues.apache.org/jira/browse/CB-12361): added unit tests for `check.js`
* [CB-13501](https://issues.apache.org/jira/browse/CB-13501): added support for node 8 to tests
* [CB-13463](https://issues.apache.org/jira/browse/CB-13463): prevent `package.json` updating plugins with `--nosave`

### 7.1.0 (Oct 04, 2017)
* [CB-13303](https://issues.apache.org/jira/browse/CB-13303) added `--save_exact`, `--production` flags
* [CB-13288](https://issues.apache.org/jira/browse/CB-13288) updated `index.js` and test to fix `cordova plugin search`
* [CB-13206](https://issues.apache.org/jira/browse/CB-13206) fixed incorrect target being passed in to `plugin add` from `restore-util.js`
* [CB-13145](https://issues.apache.org/jira/browse/CB-13145) added `variable-merge.js` to deal with `plugin.xml` variables for uninstall
* [CB-12870](https://issues.apache.org/jira/browse/CB-12870) catch all use cases for `getPlatformApiFunction` and update tests accordingly
* [CB-12944](https://issues.apache.org/jira/browse/CB-12944) Platform's spec is ignored in `config.xml` if `package.json` doesn't contain dependency for platform
* [CB-12361](https://issues.apache.org/jira/browse/CB-12361) added new unit tests for plugin tests
* [CB-13020](https://issues.apache.org/jira/browse/CB-13020) (plugman) install filters out `nohooks`
* [CB-13056](https://issues.apache.org/jira/browse/CB-13056) added deprecation notice for **WebOS**
* [CB-13057](https://issues.apache.org/jira/browse/CB-13057) added deprecation warning for `cordova platform save`
* [CB-12361](https://issues.apache.org/jira/browse/CB-12361) added tests for `save.js` and rebased
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) switched from `jshint` to `eslint`
* [CB-12361](https://issues.apache.org/jira/browse/CB-12361) updated `addHelper` tests
* [CB-11980](https://issues.apache.org/jira/browse/CB-11980) Update `README` to reflect new repos
* [CB-6143](https://issues.apache.org/jira/browse/CB-6143) Change `plugman.emit()` to `events.emit()`
* Reorganized unit test directory. Changes include: - consolidate `spec-cordova/` and `spec-plugman/` into a single `spec/` dir. - put `jasmine config` and helper modules in top-level spec dir. - changed `package.json` npm run scripts to reflect purposes of tasks. remove `npm run ci`. Updated `README` to reflect `package.json` npm run script changes. 
* [CB-12361](https://issues.apache.org/jira/browse/CB-12361) added unit tests for `prepare.spec.js`
* Update cordova-lib api. Deprecate `raw` from api calls. 
* [CB-11980](https://issues.apache.org/jira/browse/CB-11980) moved `fetch`, `common` and `serve` into their own repos
* [CB-12786](https://issues.apache.org/jira/browse/CB-12786) Improve logic for searching plugin id in case of module already exists in `node_modules`
* [CB-12250](https://issues.apache.org/jira/browse/CB-12250) [CB-12409](https://issues.apache.org/jira/browse/CB-12409) **iOS**: Fix bug with escaping properties from plist file
* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) point `package.json` repo items to github mirrors instead of apache repos site
* [CB-12777](https://issues.apache.org/jira/browse/CB-12777) removed **Android**, **iOS**, and **Windows** projects fixtures
* [CB-12787](https://issues.apache.org/jira/browse/CB-12787) Fix plugin installation with `--link` option
* [CB-12738](https://issues.apache.org/jira/browse/CB-12738) Cordova ignores plugin dependency version on **Windows** platform
* [CB-12766](https://issues.apache.org/jira/browse/CB-12766) Consistently write JSON with 2 spaces indentation

### 7.0.1 (May 08, 2017)
* [CB-12773](https://issues.apache.org/jira/browse/CB-12773): fixed incorrect plugin version fetching issue
* [CB-12769](https://issues.apache.org/jira/browse/CB-12769): updated `cordova-create` dependency to 1.1.1
* [CB-12757](https://issues.apache.org/jira/browse/CB-12757): if there's a plugin dependency in `package.json`, use that one for `config.xml`

### 7.0.0 (May 02, 2017)
* [CB-12747](https://issues.apache.org/jira/browse/CB-12747): updated pinned platforms
* [CB-12705](https://issues.apache.org/jira/browse/CB-12705): Modified `(before|after)_plugin_(uninstall|install)` to always expect existence of plugin field
* [CB-12705](https://issues.apache.org/jira/browse/CB-12705): Pass plugin info to project `*_plugin_install` hooks
* [CB-11242](https://issues.apache.org/jira/browse/CB-11242): removed support for platforms that don't have a `package.json`
* [CB-11242](https://issues.apache.org/jira/browse/CB-11242): updated tests and fixtures
* [CB-11242](https://issues.apache.org/jira/browse/CB-11242): refactored out `getPlatformApiFunction`
* [CB-11242](https://issues.apache.org/jira/browse/CB-11242): removed `parser` and `handler` files for deprecated versions of platforms
* [CB-12683](https://issues.apache.org/jira/browse/CB-12683): improved error messaging for when a plugin doesn't have `package.json`
* [CB-12674](https://issues.apache.org/jira/browse/CB-12674): Added deprecation notice for **blackberry10** and **ubuntu**
* [CB-11777](https://issues.apache.org/jira/browse/CB-11777): Restore plugins before preparing
* [CB-12643](https://issues.apache.org/jira/browse/CB-12643): removed references to **wp8**
* [CB-12645](https://issues.apache.org/jira/browse/CB-12645): removed references to **firefoxos**
* [CB-12665](https://issues.apache.org/jira/browse/CB-12665): removed `engineStrict` as it is no longer supported
* [CB-12612](https://issues.apache.org/jira/browse/CB-12612): removing old `amazon-fireos` code
* [CB-12425](https://issues.apache.org/jira/browse/CB-12425): autocreate a `package.json` if it doesn't exist during `cordova prepare` 
* [CB-12517](https://issues.apache.org/jira/browse/CB-12517): `package.json` `name` feild is `config.xml` `id` feild and `package.json` `displayName` feild is `config.xml` `name` feild
* [CB-12592](https://issues.apache.org/jira/browse/CB-12592): added `requireNoCache` function and replaced instances of `delete.require cache`
* [CB-12606](https://issues.apache.org/jira/browse/CB-12606): Fix plugin dependency installation. Now it respects the `spec` specified for dependencies of plugins in `plugin.xml`
* [CB-12016](https://issues.apache.org/jira/browse/CB-12016): removed `pluginMapper` code from uninstall
* [CB-12337](https://issues.apache.org/jira/browse/CB-12337): Resolve symbolic links in project root
* [CB-11346](https://issues.apache.org/jira/browse/CB-11346): Remove known platforms check
* [CB-11977](https://issues.apache.org/jira/browse/CB-11977): removed support for `node 0.x`
* [CB-12021](https://issues.apache.org/jira/browse/CB-12021): Added local path support to `--fetch` and fixed failing tests for adding a relative path
* [CB-11960](https://issues.apache.org/jira/browse/CB-11960): Added support to `package.json` for platform/plugin add/rm
* [CB-12001](https://issues.apache.org/jira/browse/CB-12001): Added support for platform/plugin & `spec` restore to sync `config.xml` and `package.json`

### 6.5.0 (Jan 17, 2017)
* [CB-12018](https://issues.apache.org/jira/browse/CB-12018): updated `jshint` and updated `jasmine` tests to work with `jasmine` instead of `jasmine-node`
* [CB-12314](https://issues.apache.org/jira/browse/CB-12314) updated pinned android to 6.1.1
* [CB-12261](https://issues.apache.org/jira/browse/CB-12261) fix subdirectories deprecated warning always shows and stop fetch caused by [CB-11979](https://issues.apache.org/jira/browse/CB-11979)
* [CB-12284](https://issues.apache.org/jira/browse/CB-12284) Include project root as additional root for static router
* [CB-12088](https://issues.apache.org/jira/browse/CB-12088) Fix misleading warning when adding platform without `Api.js`

### 6.4.0 (Oct 21, 2016)
* [CB-12039](https://issues.apache.org/jira/browse/CB-12039) updated pinned `Android` to 6.0.0 and `iOS` to 4.3.0
* [CB-11979](https://issues.apache.org/jira/browse/CB-11979) added deprecation warning for installing plugins via subdirectories
* [CB-11730](https://issues.apache.org/jira/browse/CB-11730) Modify condition of if clause to avoid similar project name with plugin name
* [CB-11985](https://issues.apache.org/jira/browse/CB-11985) Check if cached platform/plugin exists before `npm cache`
* [CB-11951](https://issues.apache.org/jira/browse/CB-11951) [CB-11967](https://issues.apache.org/jira/browse/CB-11967) Respect preference default values when installling plugins
* [CB-11771](https://issues.apache.org/jira/browse/CB-11771) Deep symlink directories to target project instead of linking the directory itself
* [CB-11908](https://issues.apache.org/jira/browse/CB-11908) Handle `edit-config` in `config.xml` on prepare
* Add github pull request template
* [CB-8320](https://issues.apache.org/jira/browse/CB-8320) We look for a `build.gradle` to make sure it's **Android**, not an `AndroidManifest`, because it moved
* [CB-11811](https://issues.apache.org/jira/browse/CB-11811) Moved **iOS** platform specific tests to `platform.spec.ios.js`, added `test-ios` npm run script.
* [CB-11811](https://issues.apache.org/jira/browse/CB-11811) disable `CocoaPods` e2e test temporarily since it is platform specific and requires cocoapods to be installed.
* updated `save.spec.js` to use latest **android** and newer fb plugin
* [CB-11607](https://issues.apache.org/jira/browse/CB-11607) breakout `cordova-create` from `cordova-lib`
* [CB-9825](https://issues.apache.org/jira/browse/CB-9825) framework tag spec parsing
* [CB-11698](https://issues.apache.org/jira/browse/CB-11698) Fix plugin installation when restoring platform
* [CB-11679](https://issues.apache.org/jira/browse/CB-11679) Speed up save/restore tests
* [CB-11205](https://issues.apache.org/jira/browse/CB-11205) Respect saved variables when installing plugin
* [CB-11589](https://issues.apache.org/jira/browse/CB-11589) Fix missing plugin files after restore

### 6.3.1 (Aug 08, 2016)
* [CB-11652](https://issues.apache.org/jira/browse/CB-11652) Update run and emulate to skip build
* [CB-11194](https://issues.apache.org/jira/browse/CB-11194) Defer creating of libDir folder until something actually requests it
* [CB-11493](https://issues.apache.org/jira/browse/CB-11493) Add cordova emulate option to skip prepare
* [CB-11205](https://issues.apache.org/jira/browse/CB-11205) Respect saved variables when installing plugin
* [CB-11589](https://issues.apache.org/jira/browse/CB-11589) Fix missing plugin files after restore

### 6.3.0 (Jul 12, 2016)
* [CB-11491](https://issues.apache.org/jira/browse/CB-11491) Introduce before_deploy hook
* [CB-11412](https://issues.apache.org/jira/browse/CB-11412) template support for www folders
* Fix config.xml path in PlatformApi.prepare
* [CB-11412](https://issues.apache.org/jira/browse/CB-11412) improve template implementation
* [CB-11164](https://issues.apache.org/jira/browse/CB-11164) Allow forced dependent plugin removal
* [CB-11339](https://issues.apache.org/jira/browse/CB-11339) Add a warning about prerelease platform usage
* [CB-11349](https://issues.apache.org/jira/browse/CB-11349) added --fetch and cordova fetch to create --template
* [CB-11337](https://issues.apache.org/jira/browse/CB-11337) Use latest released platform version in e2e tests
* [CB-11274](https://issues.apache.org/jira/browse/CB-11274) Platform browser: wrong path for config.xml
* [CB-11274](https://issues.apache.org/jira/browse/CB-11274) Make serve dashboard take config.xml -> content.src entry point into account
* [CB-11261](https://issues.apache.org/jira/browse/CB-11261) Cut out '-nightly' prerelease tag when checking plugin engines
* [CB-9858](https://issues.apache.org/jira/browse/CB-9858) added fetch tests to travis
* [CB-9858](https://issues.apache.org/jira/browse/CB-9858) fixed failing travis and appveyor tests

### 6.2.0 (May 12, 2016)
* [CB-11259](https://issues.apache.org/jira/browse/CB-11259) Improving prepare and build logging
* Resolve npm run jshint failure due to npm/npm#10343
* [CB-11200](https://issues.apache.org/jira/browse/CB-11200) Bump `node-xcode` dependency and update tests to pass
* [CB-11240](https://issues.apache.org/jira/browse/CB-11240) added `--fetch` support to `cordova prepare`
* [CB-9858](https://issues.apache.org/jira/browse/CB-9858) merging initial `--fetch` work for plugin and platform fetching
* [CB-11194](https://issues.apache.org/jira/browse/CB-11194) Improve cordova load time
* [CB-11174](https://issues.apache.org/jira/browse/CB-11174) Resolve `symlinked` path before getting `PlatformApi` instance
* [CB-11036](https://issues.apache.org/jira/browse/CB-11036) `args.slice is not a function` when building **Windows** with other platform
* [CB-10761](https://issues.apache.org/jira/browse/CB-10761) Resore plugins saved without spec attribute
* [CB-10981](https://issues.apache.org/jira/browse/CB-10981) Remove `cordova-common` from bundled dependencies
* [CB-11042](https://issues.apache.org/jira/browse/CB-11042) Add cordova run option to skip prepare
* [CB-11022](https://issues.apache.org/jira/browse/CB-11022) Respect result returned by plugin installation and skip prepare if it is truthy
* [CB-10975](https://issues.apache.org/jira/browse/CB-10975) Allow plugin path to be relative to current directory
* [CB-10986](https://issues.apache.org/jira/browse/CB-10986) Adding support for scoped npm package plugins
* [CB-10770](https://issues.apache.org/jira/browse/CB-10770) Remove `cache-min` when adding platforms
* [CB-10921](https://issues.apache.org/jira/browse/CB-10921) Emit warning in case of plugin restoration failure

### 6.1.1 (Mar 29, 2016)
* [CB-10961](https://issues.apache.org/jira/browse/CB-10961) Error no such file or directory adding ios platform when plugins present or required
* [CB-10908](https://issues.apache.org/jira/browse/CB-10908) Reload the config.xml before writing the saved plugin

### 6.1.0 (Mar 17, 2016)
* [CB-10902](https://issues.apache.org/jira/browse/CB-10902) updated pinned platforms
* [CB-10808](https://issues.apache.org/jira/browse/CB-10808) revert npm install for templates
* [CB-10808](https://issues.apache.org/jira/browse/CB-10808) CLI Support templates with subdirectory
* [CB-10880](https://issues.apache.org/jira/browse/CB-10880) Removed plugin pinning
* [CB-10679](https://issues.apache.org/jira/browse/CB-10679) Improving version choosing logic test coverage
* [CB-10673](https://issues.apache.org/jira/browse/CB-10673) add plugin `--force` option.
* [CB-10679](https://issues.apache.org/jira/browse/CB-10679) New version choosing logic for plugin add
* [CB-10328](https://issues.apache.org/jira/browse/CB-10328) set top-level property when adding new platforms
* [CB-10314](https://issues.apache.org/jira/browse/CB-10314) avoid fetching plugins when oldId is already fetched
* [CB-10708](https://issues.apache.org/jira/browse/CB-10708) Install/uninstall plugins correctly into CLI project using plugman
* [CB-10462](https://issues.apache.org/jira/browse/CB-10462) Get rid of npmconf in favor of npm.
* [CB-10662](https://issues.apache.org/jira/browse/CB-10662) Use project's `config.xml` as a fallback for package name
* [CB-10644](https://issues.apache.org/jira/browse/CB-10644) Adds deprecation message about old platforms support removal.
* [CB-10519](https://issues.apache.org/jira/browse/CB-10519) Wrap all sync calls inside of `cordova.raw` methods into promises
* [CB-10641](https://issues.apache.org/jira/browse/CB-10641) Adds tests for order of operations in platform add
* [CB-10641](https://issues.apache.org/jira/browse/CB-10641) Run prepare `_after_` plugins were installed
* [CB-10618](https://issues.apache.org/jira/browse/CB-10618) Do not call `prepBuildFiles` for `cordova-android@>=5.2.0`.
* [CB-10518](https://issues.apache.org/jira/browse/CB-10518) Correct log level and error messages for some cordova errors
* [CB-10550](https://issues.apache.org/jira/browse/CB-10550) Fix plugin id mapper not enforced when a version is specified
* [CB-10611](https://issues.apache.org/jira/browse/CB-10611) fix `before_plugin_install` hook not disabled with `--nohooks`
* [CB-10235](https://issues.apache.org/jira/browse/CB-10235) Added clearer error message for info command.
* [CB-10584](https://issues.apache.org/jira/browse/CB-10584) Splashscreen plugin crashes the app on windows 10 when built with browserify
* [CB-10592](https://issues.apache.org/jira/browse/CB-10592) Don't quote platform specific args values
* [CB-10482](https://issues.apache.org/jira/browse/CB-10482) Remove references to **windows8** from cordova-lib/cli
* [CB-10567](https://issues.apache.org/jira/browse/CB-10567) Bubble up `cordova.raw.run()` error to the caller
* [CB-10553](https://issues.apache.org/jira/browse/CB-10553) Fix framework tag handler for **Android**
* [CB-10461](https://issues.apache.org/jira/browse/CB-10461) `cordova platform ls` should list the versions of platforms pinned
* [CB-10531](https://issues.apache.org/jira/browse/CB-10531) Enable coverage reports for cordova-lib
* [CB-10465](https://issues.apache.org/jira/browse/CB-10465) Pass correct options to prepare from compile
* [CB-10459](https://issues.apache.org/jira/browse/CB-10459) cordova platform list should mark amazon-fireos and wp8 as deprecated
* [CB-10499](https://issues.apache.org/jira/browse/CB-10499) `--template` should pull the latest template from npm when version isn't specified
* [CB-10432](https://issues.apache.org/jira/browse/CB-10432) Adds e2e test to protect against future regressions.
* Added node versions matrix to `.travis.yml`.

### 6.0.0 (Jan 25, 2016)
* [CB-10432](https://issues.apache.org/jira/browse/CB-10432) Fix plugin installation for newly added platform
* [CB-10423](https://issues.apache.org/jira/browse/CB-10423) allow recursive folder copy skipping whatever .. was
* [CB-10394](https://issues.apache.org/jira/browse/CB-10394) updated pinned **Android** version to `~5.1.0`
* [CB-10299](https://issues.apache.org/jira/browse/CB-10299) updated pinned **windows** version to `~4.3.0`
* [CB-10274](https://issues.apache.org/jira/browse/CB-10274) Make www directory the default for plugman
* [CB-10121](https://issues.apache.org/jira/browse/CB-10121) added deprecation notice for **amazon-fireos** and **wp8**
* [CB-7183](https://issues.apache.org/jira/browse/CB-7183) prevent read/write/modify files outside project from plugins
* [CB-8455](https://issues.apache.org/jira/browse/CB-8455) Added `--nohooks` option.
* [CB-10193](https://issues.apache.org/jira/browse/CB-10193) Add deprecation notice about `pre_package` removal
* [CB-10147](https://issues.apache.org/jira/browse/CB-10147) updated pinned **iOS** to `~4.0.0`
* [CB-10125](https://issues.apache.org/jira/browse/CB-10125): Android build fails on read-only files.
* [CB-6698](https://issues.apache.org/jira/browse/CB-6698) Fix directory resolution of framework with parent.
* [CB-9653](https://issues.apache.org/jira/browse/CB-9653) Adds copying of **blackberry10** splashscreens
* **Ubuntu** support for the new plugin naming convention
* [CB-9957](https://issues.apache.org/jira/browse/CB-9957) removed support for fetching from Cordova Plugins Registry. Only fetch plugins from **npm** now.
* [CB-10108](https://issues.apache.org/jira/browse/CB-10108) Fixes **android** frameworks installation/removal
* [CB-9964](https://issues.apache.org/jira/browse/CB-9964) Added `--template` support to `cordova create`
* Removing the `--usegit` flag from `cordova platform`. Recommended method is to use `cordova platform add git_url#branch`
* [CB-10081](https://issues.apache.org/jira/browse/CB-10081) pinned plugin versions. These are default versions fetched when adding a plugin.
* add missing `package_suffix` function on **amazon-fireos** platform for plugman installations.
* [CB-10057](https://issues.apache.org/jira/browse/CB-10057) - removing `<access>` tag does not remove `ATS` entry
* [CB-10048](https://issues.apache.org/jira/browse/CB-10048) clobbering of `<access>` tags to `ATS` directives

### 5.4.1 (Nov 19, 2015)
* [CB-9976](https://issues.apache.org/jira/browse/CB-9976) Reinstall plugins for platform if they were installed with `cordova@<5.4.0`.
* [CB-9981](https://issues.apache.org/jira/browse/CB-9981) `path.parse` only available on `node 0.12+`.
* [CB-9987](https://issues.apache.org/jira/browse/CB-9987) Adds compatibility layer for `cordova.raw.*` methods
* [CB-9975](https://issues.apache.org/jira/browse/CB-9975) Fix issue with using `all" as orientation for **iOS**
* [CB-9984](https://issues.apache.org/jira/browse/CB-9984) Bumps `plist` version and fixes failing `cordova-common` test

### 5.4.0 (Oct 30, 2015)
* [CB-9935](https://issues.apache.org/jira/browse/CB-9935) Cordova CLI silently fails on node.js v5
* [CB-9834](https://issues.apache.org/jira/browse/CB-9834) Introduce compat map for hook requires
* [CB-9902](https://issues.apache.org/jira/browse/CB-9902) Fix broken `cordova run --list`
* [CB-9872](https://issues.apache.org/jira/browse/CB-9872) Fixed save.spec.11 failure
* [CB-9800](https://issues.apache.org/jira/browse/CB-9800) Fixing contribute link.
* [CB-9736](https://issues.apache.org/jira/browse/CB-9736) Extra main activity generated when an android package name is specified
* [CB-9675](https://issues.apache.org/jira/browse/CB-9675) OSX App Icons are not properly copied.
* [CB-9758](https://issues.apache.org/jira/browse/CB-9758) Mobilespec crashes adding plugins on OS X
* [CB-9782](https://issues.apache.org/jira/browse/CB-9782) Update create/update signatures for PlatformApi polyfill
* [CB-9815](https://issues.apache.org/jira/browse/CB-9815) Engine name="cordova" should check tools version, not platforms.
* [CB-9824](https://issues.apache.org/jira/browse/CB-9824) removed plugin download counter code from lib
* [CB-9821](https://issues.apache.org/jira/browse/CB-9821) Fix EventEmitter incorrect trace level usages
* [CB-9813](https://issues.apache.org/jira/browse/CB-9813) Keep module-to-plugin mapping at hand.
* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Fixes broken `require` for FFOS plugin handler
* Update 'serve' to use 'express' implementation of cordova-serve.
* [CB-9712](https://issues.apache.org/jira/browse/CB-9712) CLI 5.3 breaks with node 3.3.3
* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Fixies broken require calls that aren't covered by tests
* [CB-9589](https://issues.apache.org/jira/browse/CB-9589) added more warnings and added conversion step to fetch.js
* [CB-9589](https://issues.apache.org/jira/browse/CB-9589) auto convert old plugin ids to new npm ids using [registry-mapper](https://github.com/stevengill/cordova-registry-mapper)
* Pick ConfigParser changes from apache@0c3614e
* [CB-9743](https://issues.apache.org/jira/browse/CB-9743) Removes system frameworks handling from ConfigChanges
* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Cleans out code which has been moved to `cordova-common`
* [CB-9598](https://issues.apache.org/jira/browse/CB-9598) Switches LIB to use `cordova-common`
* [CB-9569](https://issues.apache.org/jira/browse/CB-9569) Support <access> and <allow-navigation> tag translation to Application Transport Security (ATS) Info.plist directives.
* [CB-9737](https://issues.apache.org/jira/browse/CB-9737) (save flag) unit test failures for spec.14
* [CB-8914](https://issues.apache.org/jira/browse/CB-8914) when project is renamed, remove userdata otherwise project is un-usable in xcode
* [CB-9665](https://issues.apache.org/jira/browse/CB-9665) Support .xcassets for icons and splashscreens in the CLI
* [CB-9407](https://issues.apache.org/jira/browse/CB-9407) Fixes incorrect applying of plugin-provided config changes.
* [CB-8198](https://issues.apache.org/jira/browse/CB-8198) Unified console output logic for core platforms
* [CB-9408](https://issues.apache.org/jira/browse/CB-9408) Added support for `windows-packageVersion` on `<widget>`
* [CB-9588](https://issues.apache.org/jira/browse/CB-9588) Plugman. Add support for <resource-file> on Windows
* [CB-8615](https://issues.apache.org/jira/browse/CB-8615) Improves plugman tests for Windows
* [CB-8615](https://issues.apache.org/jira/browse/CB-8615) **Windows** .winmd files with the same names are not added properly when using framework tag with target attribute
* [CB-9297](https://issues.apache.org/jira/browse/CB-9297) Parse xcode project syncronously to avoid issues with node v4
* [CB-9617](https://issues.apache.org/jira/browse/CB-9617) Do not restore plugins after plugin removal.
* [CB-9631](https://issues.apache.org/jira/browse/CB-9631) Save plugin to config.xml only if installation succeeds
* [CB-9601](https://issues.apache.org/jira/browse/CB-9601) Fix <framework>.versions support on Windows after semver update
* [CB-9617](https://issues.apache.org/jira/browse/CB-9617) Fixes incorrect project state after adding/removing plugins
* [CB-9560](https://issues.apache.org/jira/browse/CB-9560) Issue using plugin restore for plugins with common dependencies
* [CB-8993](https://issues.apache.org/jira/browse/CB-8993) Plugin restore ignores search path
* [CB-9587](https://issues.apache.org/jira/browse/CB-9587) Check if browser platform added properly before creating parser.
* [CB-9604](https://issues.apache.org/jira/browse/CB-9604) Fix error adding browser platform with PlatformApi polyfill.
* [CB-9597](https://issues.apache.org/jira/browse/CB-9597) Initial Implementation of PlatformApiPoly
* [CB-9354](https://issues.apache.org/jira/browse/CB-9354) Fix array merging with complex items
* [CB-9556](https://issues.apache.org/jira/browse/CB-9556) Don't uninstall dependent plugin if it was installed as a top-level after

### 5.3.2 (Sep 17, 2015)
* [CB-9297](https://issues.apache.org/jira/browse/CB-9297) Parse xcode project syncronously to avoid issues with node v4

### 5.3.1 (Aug 28, 2015)
* pinned blackberry@3.8.0 in prepartion for its release
* pinned browser@4.0.0 and windows@4.1.0
* [CB-9559](https://issues.apache.org/jira/browse/CB-9559) Adding a plugin with caret in version results in an error
* Update cordova-serve required version to 0.1.3.
* [CB-6506](https://issues.apache.org/jira/browse/CB-6506) RTC: Add support for OSX (closes #278)
* [CB-9517](https://issues.apache.org/jira/browse/CB-9517) Adding a plugin on iOS/OSX that uses a private framework does not work (closes #281)
* [CB-9549](https://issues.apache.org/jira/browse/CB-9549) Removes excess JS files from browserified app
* [CB-9505](https://issues.apache.org/jira/browse/CB-9505) Correct plugin modules loading within browserify flow
* [CB-8532](https://issues.apache.org/jira/browse/CB-8532) Adding Windows Plugin Failed with "Cannot read property 'text' of null" Updated elementtree API according 0.1.6 release. This closes #277

### 5.2.0 (Aug 06, 2015)
* [CB-9436](https://issues.apache.org/jira/browse/CB-9436) Removes `require-tr` bundle transformation
* updated pinned ios version to ~3.9.0
* [CB-9278](https://issues.apache.org/jira/browse/CB-9278): Restoring multiple platforms fails. This closes #266
* updated pinned android to ~4.1.0
* [CB-9421](https://issues.apache.org/jira/browse/CB-9421) Added a test for plugin fetch with searchpath parameter
* [CB-9421](https://issues.apache.org/jira/browse/CB-9421) Fixed searchpath parameter being ignored. This closes #269
* Update xcode dependency to latest stable version. This closes #272
* [CB-9420](https://issues.apache.org/jira/browse/CB-9420) Fixes malformed require calls in browserify bundle. This closes #270
* [CB-9405](https://issues.apache.org/jira/browse/CB-9405) limit author/description to 256 char per WMAppManifest schema
* [CB-9414](https://issues.apache.org/jira/browse/CB-9414) plugin fetching now defaults to npm, CPR fallback
* [CB-9384](https://issues.apache.org/jira/browse/CB-9384) Added tests that test plugin fetch from github branch|tag|sha
* added comment outlining the types of things git_ref can be : commit SHA | branch | tag
* actually checkout git_ref because it may be a branch OR a commit SHA
* [CB-9332](https://issues.apache.org/jira/browse/CB-9332) Upgrade npm and semver to actual versions
* [CB-9330](https://issues.apache.org/jira/browse/CB-9330) updated wording for warning messages for removal of publish/unpublish commands
* Adds stubs for `publish`/`unpublish` commands. This closes #254
* [CB-9330](https://issues.apache.org/jira/browse/CB-9330) Removes 'plugman publish' related functionality
* [CB-9335](https://issues.apache.org/jira/browse/CB-9335): Windows quality-of-life improvements.  To align with the change in Cordova-Windows which removes the Windows 8 project from the solution file used by Windows 8.1 and Windows 10, the same is done in the spec.
* Fix prepare to wait the promise from plugman prepare.
* [CB-9362](https://issues.apache.org/jira/browse/CB-9362) Don't fail if superspawn can't chmod a file
* [CB-9122](https://issues.apache.org/jira/browse/CB-9122) Added tests for platform/plugin add/rm/update with --save flag. This closes #246
* Fixed ios node-xcode related tests failing on Windows according to version update
* Added webOS parsers for project creation/manipulation
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) Prevent cli from copying cordova.js and cordova-js-src/ multiple times
* [CB-9114](https://issues.apache.org/jira/browse/CB-9114): Log deprecation message when --usegit flag is used. This closes #234
* [CB-9126](https://issues.apache.org/jira/browse/CB-9126) Fix ios pbxproj' resources paths when adding ios platform on non-OSX environment. This closes #237
* [CB-9221](https://issues.apache.org/jira/browse/CB-9221) Updates `cordova serve` command to use cordova-serve module.
* [CB-9225](https://issues.apache.org/jira/browse/CB-9225) Add windows platform support to `plugman platform add`
* [CB-9163](https://issues.apache.org/jira/browse/CB-9163) when engine check isn't satisfied, skip that plugin install
* [CB-9162](https://issues.apache.org/jira/browse/CB-9162) Adds support for default values for plugin variables.
* [CB-9188](https://issues.apache.org/jira/browse/CB-9188) Confusing error after delete plugin folder then prepare.
* [CB-9145](https://issues.apache.org/jira/browse/CB-9145) prepare can lose data during config munge
* [CB-9177](https://issues.apache.org/jira/browse/CB-9177) Use tilde instead of caret when save to config.xml.
* [CB-9147](https://issues.apache.org/jira/browse/CB-9147) Adding a platform via caret version adds latest rather than the latest matching.
* [CB-5578](https://issues.apache.org/jira/browse/CB-5578) Adds `clean` module to cordova. This closes #241
* [CB-9124](https://issues.apache.org/jira/browse/CB-9124) Makes network-related errors' messages more descriptive.
* [CB-9067](https://issues.apache.org/jira/browse/CB-9067) fixed plugman config set registry and adduser
* [CB-8993](https://issues.apache.org/jira/browse/CB-8993) Plugin restore ignores search path. This closes #224
* [CB-9087](https://issues.apache.org/jira/browse/CB-9087) updated pinned windows platform to 4.0.0
* [CB-9108](https://issues.apache.org/jira/browse/CB-9108) Handle version ranges when add platform with --usegit.
* [CB-8898](https://issues.apache.org/jira/browse/CB-8898) Makes error message descriptive when `requirements` is called outside of cordova project.
* [CB-8007](https://issues.apache.org/jira/browse/CB-8007) Two cordova plugins modifying “*-Info.plist” CFBundleURLTypes
* [CB-9065](https://issues.apache.org/jira/browse/CB-9065) Allow removing plugins by short name.
* [CB-9001](https://issues.apache.org/jira/browse/CB-9001) Set WMAppManifest.xml Author, Description and Publisher attributes based on config.xml
* [CB-9073](https://issues.apache.org/jira/browse/CB-9073) Allow to add platform if project path contains `&` symbol

### 5.1.1 (June 4, 2015)
* [CB-9087](https://issues.apache.org/jira/browse/CB-9087) Updated pinned version of cordova-windows to 4.0.0
* [CB-9108](https://issues.apache.org/jira/browse/CB-9108) Handle version ranges when add platform with --usegit.
* [CB-8898](https://issues.apache.org/jira/browse/CB-8898) Makes error message descriptive when `requirements` is called outside of cordova project.
* Fix four failing tests on Windows.
* [CB-8007](https://issues.apache.org/jira/browse/CB-8007) Two cordova plugins modifying “*-Info.plist” CFBundleURLTypes
* [CB-9065](https://issues.apache.org/jira/browse/CB-9065) Allow removing plugins by short name.
* [CB-9001](https://issues.apache.org/jira/browse/CB-9001) Set WMAppManifest.xml Author, Description and Publisher attributes based on config.xml
* [CB-9073](https://issues.apache.org/jira/browse/CB-9073) Allow to add platform if project path contains `&` symbol
* [CB-8783](https://issues.apache.org/jira/browse/CB-8783) - Revert 'all' as a global preference value for Orientation (specific to iOS for now)
* [CB-8783](https://issues.apache.org/jira/browse/CB-8783) - 'default' value for Orientation does not support both landscape and portrait orientations. (new 'all' value)
* [CB-9075](https://issues.apache.org/jira/browse/CB-9075) pinned platforms will include patch updates without new tools release
* [CB-9051](https://issues.apache.org/jira/browse/CB-9051) Plugins don't get re-added if platforms folder deleted.
* [CB-9025](https://issues.apache.org/jira/browse/CB-9025) Call windows `prepare` logic on as part of cordova-lib `prepare`. This closes #217
* [CB-9048](https://issues.apache.org/jira/browse/CB-9048) Clean up git cloned directories (close #222)
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) readded browserify transform
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) copy platform specific js into platform_www when adding new platforms for browserify workflow
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) passing platform as argument when getting symbolList
* [CB-8965](https://issues.apache.org/jira/browse/CB-8965) copy platform specific js into platform_www when adding new platforms for browserify workflow
* Add support to specify a build config file. If none is specified `build.json` in the project root is used as a default This closes #215
* [CB-9030](https://issues.apache.org/jira/browse/CB-9030): Modifies superspawn to support a "chmod" option. When truthy, attempts to set the target file mode to 755 before executing.  Specifies this argument as truthy for common CLI operations (compile, run, and steps in plugman).  Didn't add it for hooks runner since that particular mode is in legacy support.
* [CB-8989](https://issues.apache.org/jira/browse/CB-8989) - cordova-lib jasmine tests are failing on older hardware
* [CB-6462](https://issues.apache.org/jira/browse/CB-6462) [CB-6026](https://issues.apache.org/jira/browse/CB-6026) - Orientation preference now updates `UISupportedInterfaceOrientations~ipad` too.
* [CB-8898](https://issues.apache.org/jira/browse/CB-8898) Introduces `requirements` cordova module
* Update elementtree dependency to 0.1.6. Note it has a breaking API change. https://github.com/racker/node-elementtree/issues/24 (closes #209)
* [CB-8757](https://issues.apache.org/jira/browse/CB-8757) Resolve symlinks in order to avoid relative path issues (close #212)
* [CB-8956](https://issues.apache.org/jira/browse/CB-8956) Remove hardcoded reference to registry.npmjs.org
* [CB-8934](https://issues.apache.org/jira/browse/CB-8934) fixed regression with projects config.json not being used in cordova create
* [CB-8908](https://issues.apache.org/jira/browse/CB-8908) Make fetching via git faster via --depth=1
* [CB-8897](https://issues.apache.org/jira/browse/CB-8897) Make default icon/splash on Android map to mdpi

### 5.0.0 (Apr 16, 2015)
* [CB-8865](https://issues.apache.org/jira/browse/CB-8865) fixed plugman.help()
* Pinned Cordova-Android version 4.0.0
* [CB-8775](https://issues.apache.org/jira/browse/CB-8775) updated warning message to be more descriptive
* Fix getPlatformVersion fails for paths with spaces
* [CB-8799](https://issues.apache.org/jira/browse/CB-8799) Save plugin/platform src and version to 'spec' attribute.
* [CB-8807](https://issues.apache.org/jira/browse/CB-8807) Platform Add fails to add plugins with variables.
* [CB-8832](https://issues.apache.org/jira/browse/CB-8832) Fix iOS icon copying logic to not use default for every size
* Updated pinned versions of windows and wp8
* [CB-8775](https://issues.apache.org/jira/browse/CB-8775) adding a plugin will still copy it to plugins folder, except if the plugin's new or old id is already installed.
* [CB-8775](https://issues.apache.org/jira/browse/CB-8775) removed failing test
* Fix setGlobalPreference() in ConfigParser
* removed mostly unused relativePath checking and added missing cases for isAbsolutePath
* use string method for clarity
* [CB-8775](https://issues.apache.org/jira/browse/CB-8775) new style plugins won't install if same RDS plugin is installed and vice versa
* [CB-8791](https://issues.apache.org/jira/browse/CB-8791) Recognize UAP as a valid TargetPlatformIdentifier
* [CB-8784](https://issues.apache.org/jira/browse/CB-8784) Prepare with no platforms should restore all platforms.
* Fix plugman install failure on iOS containing &
* [CB-8703](https://issues.apache.org/jira/browse/CB-8703): Test failure after merge to head.
* [CB-8703](https://issues.apache.org/jira/browse/CB-8703): Add support for semver and device-specific targeting of config-file to Windows
* [CB-8596](https://issues.apache.org/jira/browse/CB-8596) Expose APIs to retrieve platforms and plugins saved in config.xml.
* [CB-8741](https://issues.apache.org/jira/browse/CB-8741) Make plugin --save work more like npm install
* [CB-8755](https://issues.apache.org/jira/browse/CB-8755) Plugin --save: Multiple config.xml entries don't get removed
* [CB-8754](https://issues.apache.org/jira/browse/CB-8754) Auto-restoring a plugin fails when adding a platform.
* [CB-8651](https://issues.apache.org/jira/browse/CB-8651) Restoring platforms causes plugin install to be triggered twice  (close #196)
* [CB-8731](https://issues.apache.org/jira/browse/CB-8731) updated app hello world dependency to 3.9.0
* [CB-8757](https://issues.apache.org/jira/browse/CB-8757) ios: Make paths with --link relative to the real project path (close #192)
* [CB-8286](https://issues.apache.org/jira/browse/CB-8286) Fix regression from e70432f2: Never want to link to app-hello-world
* [CB-8737](https://issues.apache.org/jira/browse/CB-8737) Available platforms list includes extraneous values
* Bugfix to json.parse before using cfg
* Add merges/ by default, now all tests pass
* Move cordova-app-hello-world dependency to cordova-lib
* Support the old 4-argument version of create again
* [CB-8286](https://issues.apache.org/jira/browse/CB-8286) Update create.js to always require passing in a www
* Show npm failure message when plugin fetch fails
* [CB-8725](https://issues.apache.org/jira/browse/CB-8725) Fix plugin add from npm when authenticated to CPR
* [CB-8499](https://issues.apache.org/jira/browse/CB-8499) Remove project_dir from (un)installers signature
* Add addElement() to ConfigParser
* [CB-8696](https://issues.apache.org/jira/browse/CB-8696) Fix fetching of dependencies with semver constraints rather than exact versions
* [CB-7747](https://issues.apache.org/jira/browse/CB-7747) Add `<allow-intent>` for App Store on iOS
* Export PlatformProjectAdapter from platforms.js
* Allow subdirs for icons on BB10
* [CB-8670](https://issues.apache.org/jira/browse/CB-8670) Error when set engine name to "cordova-windows" in plugin.xml
* Allow hyphen in platform name
* [CB-8521](https://issues.apache.org/jira/browse/CB-8521) Cleans up plugin metadata save method
* [CB-8521](https://issues.apache.org/jira/browse/CB-8521) Adds `cordova plugin save` which saves all installed plugins to config.xml
* [CB-7698](https://issues.apache.org/jira/browse/CB-7698) BugFix: For plugins which require variables, 'cordova plugin add FOO' should fail when no variables specified.
* Add setGlobalPreference() to ConfigParser
* [CB-8499](https://issues.apache.org/jira/browse/CB-8499) Merge platforms.js from cordova and plugman
* rename references to feature to plugin
* Deprecate the old feature syntax from config.xml
* [CB-8634](https://issues.apache.org/jira/browse/CB-8634) Fixes missed merge/rebase issue
* [CB-8634](https://issues.apache.org/jira/browse/CB-8634) Adds support for custom branches for `cordova platform add`
* [CB-8633](https://issues.apache.org/jira/browse/CB-8633) BugFix: Support for urls to tarballs was broken
* [CB-8499](https://issues.apache.org/jira/browse/CB-8499) `cordova platform save`: save installed platforms and their sources (versions/git_urls/folders) into config.xml
* [CB-8499](https://issues.apache.org/jira/browse/CB-8499) When deleting a platform, remove it from platforms.json
* [CB-8499](https://issues.apache.org/jira/browse/CB-8499) When adding a platform, capture version/folder/url being added to allow us to be able to save all installed platforms and their versions later on by doing 'cordova platform save'
* [CB-8602](https://issues.apache.org/jira/browse/CB-8602) plugman: publish fail early if unsupported npm is active
* [CB-7747](https://issues.apache.org/jira/browse/CB-7747) Add `<allow-intent>`s to default template
* [CB-8616](https://issues.apache.org/jira/browse/CB-8616) Support 9-patch images for default android splashscreen
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) fixed regex in isValidCprName
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) updated version of registry mapper and cordova plugin rm code
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) merged fetchNPM and fetchPlugReg into fetchPlugin
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) updated regex in isValidCprName to exclude matching @version
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) split up changePluginId into two functions
* [CB-8457](https://issues.apache.org/jira/browse/CB-8457) Ignore version specifier when running hooks (close #165)
* [CB-8578](https://issues.apache.org/jira/browse/CB-8578) `cordova plugin add <plugin>` should be able to restore urls and folders in addition to versions. (close #173)
* [CB-7827](https://issues.apache.org/jira/browse/CB-7827) Add support for `android-activityName` within `config.xml` (close #171)
* Add org.apache.cordova.test-framework to plugman publish whitelist
* [CB-8577](https://issues.apache.org/jira/browse/CB-8577) - Read plugin variables from correct tag
* [CB-8555](https://issues.apache.org/jira/browse/CB-8555) Incremented package version to -dev
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) added plugin-name support for removing plugins.
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) Skip CPR if pluginID isn't reverse domain name style
* [CB-8551](https://issues.apache.org/jira/browse/CB-8551) added npm fetching as fallback

### 4.3.0 (Feb 27, 2015)
* updated pinned versions of ios to 3.8.0 and android to 3.7.1
* [CB-8524](https://issues.apache.org/jira/browse/CB-8524) Switched to the latest Windows release
* changed createpackage.json keyword to ecosystem:cordova
* [CB-8448](https://issues.apache.org/jira/browse/CB-8448) add support for activities
* [CB-8482](https://issues.apache.org/jira/browse/CB-8482) rename: platformId -> platformName
* [CB-8482](https://issues.apache.org/jira/browse/CB-8482): Update engine syntax within config.xml
* Organize save logic some more
* --save flag for plugins
* fix for test after prepare changes
* restore plugins and platforms on prepare
* [CB-8472](https://issues.apache.org/jira/browse/CB-8472) Can't find config.xml error installing browser platform after plugin.  (close #167)
* [CB-8469](https://issues.apache.org/jira/browse/CB-8469) android: Call into platform's build.js after `plugin add` so that Android Studio will work without needing an explicit command-line build first
* [CB-8123](https://issues.apache.org/jira/browse/CB-8123) Fix JSHINT issue.
* [CB-8123](https://issues.apache.org/jira/browse/CB-8123) Fix path handling so tests work on any platform.
* [CB-8123](https://issues.apache.org/jira/browse/CB-8123) Rename further windows platform related files.
* [CB-8123](https://issues.apache.org/jira/browse/CB-8123) Rename windows platform related files.
* [CB-8123](https://issues.apache.org/jira/browse/CB-8123) Plugin references can target specific windows platforms.
* [CB-8420](https://issues.apache.org/jira/browse/CB-8420) Make `cordova plugin add FOO` use version from config.xml (close #162)
* [CB-8239](https://issues.apache.org/jira/browse/CB-8239) Fix `cordova platform add PATH` when PATH is relative and CWD != project root
* [CB-8227](https://issues.apache.org/jira/browse/CB-8227) CB8237 [CB-8238](https://issues.apache.org/jira/browse/CB-8238) Add --save flag and autosave to 'cordova platform add', 'cordova platform remove' and 'cordova platform update'
* [CB-8409](https://issues.apache.org/jira/browse/CB-8409) compile: bubble failures
* [CB-8239](https://issues.apache.org/jira/browse/CB-8239) Fix "platform update" should ignore `<cdv:engine>` (close #159)
* [CB-8390](https://issues.apache.org/jira/browse/CB-8390) android: Make `<framework custom=false>` work with Gradle
* [CB-8416](https://issues.apache.org/jira/browse/CB-8416) updated plugman publish to temporarily rename existing package.json files
* [CB-8416](https://issues.apache.org/jira/browse/CB-8416): added `plugman createpackagejson .` command to create a package.json from plugin.xml
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) add spec-plugman to npm run jshint
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) fix spec-plugman jshint failures
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) have base rules in jshintrc for spec-plugman
* [CB-8377](https://issues.apache.org/jira/browse/CB-8377) Fixed <runs> tag parsing (close #156)
* [CB-5696](https://issues.apache.org/jira/browse/CB-5696) find ios project directory using the xcode project file (close #151)
* [CB-8373](https://issues.apache.org/jira/browse/CB-8373) android: Add gradle references to project.properties rather than build.gradle
* [CB-8370](https://issues.apache.org/jira/browse/CB-8370) Make "plugman publish" without args default to CWD
* Fix publish type-error introduced in recent commit 15adc1b9fcc069438f5
* [CB-8366](https://issues.apache.org/jira/browse/CB-8366) android: Remove empty `<framework>` directory upon uninstall
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) Enable JSHint for spec-cordova
* [CB-8239](https://issues.apache.org/jira/browse/CB-8239) Add support for git urls to 'cordova platform add' (close #148)
* [CB-8358](https://issues.apache.org/jira/browse/CB-8358) Add `--link` for `platform add` and `platform update`
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) remove base rules from individual files in src
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973) have base rules in .jshintrc file
* Add shims to undo breaking change in a20b3ae3 (didn't realize PluginInfo was exported)
* [CB-8354](https://issues.apache.org/jira/browse/CB-8354) Add --link support for iOS source and header files
* Make all ad-hoc plugin.xml parsing use PluginInfo instead
* Make all usages of PluginInfo use PluginInfoProvider instead
* Add PluginInfoProvider for better caching of PluginInfo
* [CB-8284](https://issues.apache.org/jira/browse/CB-8284) revert npm dependency due to issues with registry
* [CB-8223](https://issues.apache.org/jira/browse/CB-8223) Expose config.xml in the Browser platform (close #149)
* [CB-8168](https://issues.apache.org/jira/browse/CB-8168) --list support for cordova-lib (close #145)
* [Amazon] Improve error message when `<source-file>` is missing `target-dir`
* refactor: Make addUninstalledPluginToPrepareQueue take pluginId rather than dirName
* Chnage plugman test plugins to have IDs as directory names
* Make all test plugin IDs unique
* Empty out contents of plugin test files (and delete some unused ones)
* [CB-4789](https://issues.apache.org/jira/browse/CB-4789) refactor: Remove config_changes.get/set_platform_json in favour of PlatformJson
* [CB-8319](https://issues.apache.org/jira/browse/CB-8319) Remove config_changes module from plugman's public API
* [CB-8314](https://issues.apache.org/jira/browse/CB-8314) Speed up Travis CI (close #150)
* refactor: Extract PlatformJson and munge-util into separate modules
* refactor: Move ConfigFile and ConfigKeeper into their own files
* [CB-8285](https://issues.apache.org/jira/browse/CB-8285) Fix regression caused by c49eaa86c92b (PluginInfo's are cached, don't change them)
* [CB-8208](https://issues.apache.org/jira/browse/CB-8208) Made CI systems to get cordova-js dependency from gihub (close #146)
* [CB-8285](https://issues.apache.org/jira/browse/CB-8285) Don't create .fetch.json files within plugin directories
* [CB-8286](https://issues.apache.org/jira/browse/CB-8286) Never persist value of create --link-to within .cordova/config.json
* [CB-8288](https://issues.apache.org/jira/browse/CB-8288) Don't set config.setAutoPersist() in cordova.create
* Fix create spec sometimes failing because it's deleted its own tmp directory
* [CB-8153](https://issues.apache.org/jira/browse/CB-8153) generate cordova_plugins.json for browserify based projects
* [CB-8043](https://issues.apache.org/jira/browse/CB-8043) [CB-6462](https://issues.apache.org/jira/browse/CB-6462) [CB-6105](https://issues.apache.org/jira/browse/CB-6105) Refactor orientation preference support (close #128)
* FirefoxOS parser: allow passing in a ConfigParser object
* Parsers: extend base parser with helper functions
* [CB-8244](https://issues.apache.org/jira/browse/CB-8244) android: Have `plugin add --link` create symlinks for `<source-file>`, `<framework>`, etc
* [CB-8244](https://issues.apache.org/jira/browse/CB-8244) Pass options object to platform handlers in plugman (commit attempt #2)
* [CB-8226](https://issues.apache.org/jira/browse/CB-8226) 'cordova platform add' : Look up version in config.xml if no version specified
* Delete root .npmignore, since there's no node module there

### 4.2.0 (Jan 06, 2015)
* `ConfigParser`: refactor `getPreference()`
* Parsers: add base parser (parser.js) and make platform parsers inherit from it
* Parsers: assign methods without overriding the prototype
* [CB-8225](https://issues.apache.org/jira/browse/CB-8225) Add Unit Tests for `platform.js/add` function (closes #138)
* [CB-8230](https://issues.apache.org/jira/browse/CB-8230) Make `project.properties` optional for Android sub-libraries
* [CB-8215](https://issues.apache.org/jira/browse/CB-8215) Improve error message when `<source-file>` is missing `target-dir` on android
* [CB-8217](https://issues.apache.org/jira/browse/CB-8217) Fix plugin add --link when plugin given as relative path
* [CB-8216](https://issues.apache.org/jira/browse/CB-8216) Resolve plugin paths relative to original CWD
* [CB-7311](https://issues.apache.org/jira/browse/CB-7311) Fix tests on windows for iOS parser
* [CB-7803](https://issues.apache.org/jira/browse/CB-7803) Allow adding any platform on any host OS (close #126)
* [CB-8155](https://issues.apache.org/jira/browse/CB-8155) Do not fail plugin installation from git url with --link (close #129)
* Updates README with description of npm commands for this package
* [CB-8129](https://issues.apache.org/jira/browse/CB-8129) Adds 'npm run cover' command to generate tests coverage report (close #131)
* [CB-8114](https://issues.apache.org/jira/browse/CB-8114) Specify a cache-min-time for plugins (closes #133)
* [CB-8190](https://issues.apache.org/jira/browse/CB-8190) Make plugman config/cache directory to be customizable via PLUGMAN_HOME (close #134)
* [CB-7863](https://issues.apache.org/jira/browse/CB-7863) Fixed broken test run on Windows 8.1 caused by incorrect use of promises (close #132, close #112)
* [CB-7610](https://issues.apache.org/jira/browse/CB-7610) Fix `cordova plugin add d:\path` (or any other non-c: path) (close #135)
* [CB-8179](https://issues.apache.org/jira/browse/CB-8179) Corrected latest wp8 version
* [CB-8158](https://issues.apache.org/jira/browse/CB-8158) added hasModule check to browserify code
* [CB-8173](https://issues.apache.org/jira/browse/CB-8173) Point to the latest ubuntu version
* [CB-8179](https://issues.apache.org/jira/browse/CB-8179) Point to the latest wp8 version
* [CB-8158](https://issues.apache.org/jira/browse/CB-8158) adding symbolList to cordova.js
* [CB-8154](https://issues.apache.org/jira/browse/CB-8154) Fix errors adding platforms or plugins
* browserify: updated require to use symbollist
* Amazon related changes. Added a type named "gradleReference" in framework according to https://git-wip-us.apache.org/repos/asf?p=cordova-lib.git;a=commit;h=02a96d757acc604610eb403cf11f79513ead4ac5
* [CB-7736](https://issues.apache.org/jira/browse/CB-7736) Update npm dep to promote qs module to 1.0
* Added a missing "else" keyword.
* [CB-8086](https://issues.apache.org/jira/browse/CB-8086) Fixed framework tests.
* [CB-8086](https://issues.apache.org/jira/browse/CB-8086) Added an explanatory comment.
* [CB-8086](https://issues.apache.org/jira/browse/CB-8086) Prefixed subprojects with package name.
* [CB-8067](https://issues.apache.org/jira/browse/CB-8067) externalized valid-identifier it is it's own module
* Added identifier checking for app id, searches for java+C# reserved words
* [CB-6472](https://issues.apache.org/jira/browse/CB-6472) Adding content to -Info.plist - Unexpected behaviour
* [CB-8053](https://issues.apache.org/jira/browse/CB-8053): Including a project reference in a plugin fails on Windows platform.
* Pass the searchpath when installing plugins
* Add a type named "gradleReference" in framework

### 4.1.2 (Nov 13, 2014)
* [CB-7079](https://issues.apache.org/jira/browse/CB-7079) Allow special characters and digits in id when publishing to plugins registry
* [CB-7988](https://issues.apache.org/jira/browse/CB-7988): Update platform versions for iOS, wp8 & Windows to 3.7.0
* [CB-7846](https://issues.apache.org/jira/browse/CB-7846) Fix plugin deletion when dependency plugin does not exist
* [CB-6992](https://issues.apache.org/jira/browse/CB-6992) Fix build issue on iOS when app name contains accented characters
* [CB-7890](https://issues.apache.org/jira/browse/CB-7890) validate file copy operations in plugman
* [CB-7884](https://issues.apache.org/jira/browse/CB-7884) moved platform metadata to platformsConfig.json
* Amazon Specific changes: Added support for SdkVersion
* Expose PluginInfo from cordova-lib
* [CB-7839](https://issues.apache.org/jira/browse/CB-7839) android: Fix versionCode logic when version is less than 3 digits
* [CB-7033](https://issues.apache.org/jira/browse/CB-7033) Improve cordova platform check
* [CB-7311](https://issues.apache.org/jira/browse/CB-7311) Fix xcode project manipulation on Windows host
* [CB-7820](https://issues.apache.org/jira/browse/CB-7820) Make cordova platform restore not stop if a platforms fails to restore
* [CB-7649](https://issues.apache.org/jira/browse/CB-7649) Support iPhone 6 Plus Icon in CLI config.xml
* [CB-7647](https://issues.apache.org/jira/browse/CB-7647) Support new iPhone 6 and 6 Plus Images in the CLI config.xml
* [CB-7909](https://issues.apache.org/jira/browse/CB-7909) "plugman platform add" fixes
* Enable platform-specific id for android and ios
* Check for a CORDOVA_HOME environment variable to create a global config path

### 4.0.0 (Oct 10, 2014)
* Bumped version to 4.0.0 to be semVer complient and to match cli version
* Pinned dependencies in package.json
* updated platforms.js for 3.6.4
* [CB-5390](https://issues.apache.org/jira/browse/CB-5390) Uninstall - recursively remove dependencies of dependencies
* fixes HooksRunner test - should run before_plugin_uninstall
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) getPluginsHookScripts to work if plugin platform not defined
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Context opts should copy not reference
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Fixed tests - removed output
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Fixed HooksRunner and tests Avoided issue with parallel tests running Added checks for handling mocked config.xml and package.json in HooksRunner and scriptsFinder Addressed jshint issues Renamed ScriptsFinder to scriptsFinder
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Addressed community review notes: Removed commonModules from Context Renamed Hooker and subclasses to HooksRunner and scriptsFinder Moved scriptsRunner code into HooksRunner
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Replaced CordovaError throwings with Error per @kamrik review Extracted prepareOptions Hooker method
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Docs: deprecated .cordova/hooks + other minor updates
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Updated hooks documentation
* [CB-6481](https://issues.apache.org/jira/browse/CB-6481) Added unified hooks support for cordova app and plugins
* [CB-7572](https://issues.apache.org/jira/browse/CB-7572) Serve - respond with 304 when resource not modified
* computeCommitId for browserify workflow fixed to handle cli and non cli workflows:q
* [CB-7219](https://issues.apache.org/jira/browse/CB-7219) prepare-browserify now supports commitId and platformVersion for cordovajs
* [CB-7219](https://issues.apache.org/jira/browse/CB-7219): initial work for cordova.js platformVersion
* [CB-7219](https://issues.apache.org/jira/browse/CB-7219) prepare-browserify now supports commitId and platformVersion for cordovajs
* [CB-7219](https://issues.apache.org/jira/browse/CB-7219): initial work for cordova.js platformVersion
* [CB-7383](https://issues.apache.org/jira/browse/CB-7383) Updated version and RELEASENOTES.md for release 0.21.13
* Fix [CB-7615](https://issues.apache.org/jira/browse/CB-7615) Read config.xml after pre-prepare hooks fire
* [CB-7578](https://issues.apache.org/jira/browse/CB-7578) Windows. Fix platform name reported by pre_package hook
* [CB-7576](https://issues.apache.org/jira/browse/CB-7576) Support 'windows' merges folder for Windows platform
* Revert "Merge branch 'browserPlatform' of https://github.com/surajpindoria/cordova-lib"
* Added tests for browser platform

### 0.21.13
* remove shrinkwrap

### 0.21.12
* [CB-7383](https://issues.apache.org/jira/browse/CB-7383): depend on a newer version of cordova-js, bump self version

### 0.21.11
* bump version numbers of platforms to 3.6.3

### 0.21.10 (Sep 05, 2014)
* [CB-7457](https://issues.apache.org/jira/browse/CB-7457) - cordova plugin add --searchpath does not recurse through subfolders when a plugin.xml is malformed in one of them
* [CB-7457](https://issues.apache.org/jira/browse/CB-7457) - Add malformed plugin for tests
* [Windows8] Fix failing test to match updated functionality
* [CB-7420](https://issues.apache.org/jira/browse/CB-7420) Windows. Plugin <resource-file>s are removed from platform during prepare
* Windows helper. Removes unnecessary $(MSBuildThisFileDirectory)
* updated Releasenotes.md
* updated version to 0.21.10-dev
* [CB-7457](https://issues.apache.org/jira/browse/CB-7457) - cordova plugin add --searchpath does not recurse through subfolders when a plugin.xml is malformed in one of them
* [CB-7457](https://issues.apache.org/jira/browse/CB-7457) - Add malformed plugin for tests
* [Windows8] Fix failing test to match updated functionality
* updated Releasenotes.md
* updated version to 0.21.10-dev
* updated version, updated ffos to use 3.6.1, updated cordova-js dependency to be strcit
* [CB-7383](https://issues.apache.org/jira/browse/CB-7383) Incremented package version to -dev
* updated platforms.js to use 3.6.0
*  Updated version and RELEASENOTES.md for release 0.21.8
* [CB-5535](https://issues.apache.org/jira/browse/CB-5535): Remove "--arc" from ios platform creation args
* Windows helper. Removes unnecessary $(MSBuildThisFileDirectory)
* [CB-7420](https://issues.apache.org/jira/browse/CB-7420) Windows. Plugin <resource-file>s are removed from platform during prepare
* [CB-7416](https://issues.apache.org/jira/browse/CB-7416) Fixes file path reference when adding new source file
* [CB-7416](https://issues.apache.org/jira/browse/CB-7416) handleInstall tests for null platformTag. removed uncalled 'hasPlatformSection' from PluginInfo.js
* Remove use of path.join for manifest.launch_path
* [CB-7347](https://issues.apache.org/jira/browse/CB-7347) Improve cordova platform add /path/to handling
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) (fix jshint warnings)
* [CB-7114](https://issues.apache.org/jira/browse/CB-7114) Android: add support of min/max/target SDK to config.xml
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) Use updated version of node-xcode
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) iOS: add target-device and MinimumOSVersion support to config.xml
* ubuntu: support incremental builds
* ubuntu: support target-dir for resource-file
* ubuntu: use common.copyFile
* ubuntu: check icon existence
* ffos: Make author url optional
* [CB-7142](https://issues.apache.org/jira/browse/CB-7142) Add <variable> to <feature> for "plugin restore" command
* Set git clone depth to 10 for Travis to make it faster
* windows: update as per changed manifest file names
* Don't spy and expect it to call the other spy ...
* Well that looks like an error
* Fixing failing tests: update_proj should be update_project
* Fix failing tests. update_jsproj and update_csproj are now just update_proj
* Fix jshint errors in amazon_fireos_parser : mixed single/double quotes
* [CB-6699](https://issues.apache.org/jira/browse/CB-6699) Include files from www folder via single element (use ** glob pattern)
* Taking care of dashes in amazon-fireos platform name.
* Upleveled amazon-fireos changes.
* Fix link/copy parent check for windows
* Style fixes - comments
* Fix error in comments for munge functions
* Add link to BuildBot at ci.cordova.io in README
* [CB-7255](https://issues.apache.org/jira/browse/CB-7255) Fixed writing plist unescaped
* Allow plugin modules to be .json files
* Style fixes - white space only
* Add JSCS config file
* [CB-7260](https://issues.apache.org/jira/browse/CB-7260) Get cordova-android 3.5.1 instead of 3.5.0
* [CB-7228](https://issues.apache.org/jira/browse/CB-7228): Fixed issue with "cordova prepare --browserify"
* [CB-7234](https://issues.apache.org/jira/browse/CB-7234) added better outputs for plugin registry workflows
* [CB-7100](https://issues.apache.org/jira/browse/CB-7100): Use npm based lazy-load by default
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Remove check_requirements() funcs from platform parsers
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Remove check_requirements() funcs from platform parsers
* [CB-7140](https://issues.apache.org/jira/browse/CB-7140) Check plugin versions in local search path
* [CB-7001](https://issues.apache.org/jira/browse/CB-7001): Create a --browserify option for run action
* [CB-7228](https://issues.apache.org/jira/browse/CB-7228): Cordova prepare --browserify runs on all installed plugins
* [CB-7190](https://issues.apache.org/jira/browse/CB-7190): Add browserify support in cordova-lib/cordova-cli
* Remove references to "firefoxos"
* Browser platform is now being created from cli
* Created new files for browser

### 0.21.8 (Aug 29, 2014)
* [CB-5535](https://issues.apache.org/jira/browse/CB-5535): Remove "--arc" from ios platform creation args
* [CB-7416](https://issues.apache.org/jira/browse/CB-7416) Fixes file path reference when adding new source file
* [CB-7416](https://issues.apache.org/jira/browse/CB-7416) handleInstall tests for null platformTag. removed uncalled 'hasPlatformSection' from PluginInfo.js
* Remove use of path.join for manifest.launch_path
* [CB-7347](https://issues.apache.org/jira/browse/CB-7347) Improve cordova platform add /path/to handling
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) (fix jshint warnings)
* [CB-7114](https://issues.apache.org/jira/browse/CB-7114) Android: add support of min/max/target SDK to config.xml
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) Use updated version of node-xcode
* [CB-7118](https://issues.apache.org/jira/browse/CB-7118) iOS: add target-device and MinimumOSVersion support to config.xml
* ubuntu: support incremental builds
* ubuntu: support target-dir for resource-file
* ubuntu: use common.copyFile
* ubuntu: check icon existence
* ffos: Make author url optional
* [CB-7142](https://issues.apache.org/jira/browse/CB-7142) Add <variable> to <feature> for "plugin restore" command
* Set git clone depth to 10 for Travis to make it faster
* windows: update as per changed manifest file names
* Don't spy and expect it to call the other spy ...
* Well that looks like an error
* Fixing failing tests: update_proj should be update_project
* Fix failing tests. update_jsproj and update_csproj are now just update_proj
* Fix jshint errors in amazon_fireos_parser : mixed single/double quotes
* [CB-6699](https://issues.apache.org/jira/browse/CB-6699) Include files from www folder via single element (use ** glob pattern)
* Allow plugin modules to be .json files
* Taking care of dashes in amazon-fireos platform name.
* Upleveled amazon-fireos changes.
* Fix link/copy parent check for windows
* Style fixes - comments
* Fix error in comments for munge functions
* Add link to BuildBot at ci.cordova.io in README
* [CB-7255](https://issues.apache.org/jira/browse/CB-7255) Fixed writing plist unescaped
* Style fixes - white space only
* Add JSCS config file
* [CB-7228](https://issues.apache.org/jira/browse/CB-7228): Fixed issue with "cordova prepare --browserify"
* [CB-7001](https://issues.apache.org/jira/browse/CB-7001): Create a --browserify option for run action
* [CB-7228](https://issues.apache.org/jira/browse/CB-7228): Cordova prepare --browserify runs on all installed plugins
* [CB-7190](https://issues.apache.org/jira/browse/CB-7190): Add browserify support in cordova-lib/cordova-cli
* [CB-7260](https://issues.apache.org/jira/browse/CB-7260) Get cordova-android 3.5.1 instead of 3.5.0
* [CB-7001](https://issues.apache.org/jira/browse/CB-7001): Create a --browserify option for run action
* [CB-7228](https://issues.apache.org/jira/browse/CB-7228): Cordova prepare --browserify runs on all installed plugins
* [CB-7190](https://issues.apache.org/jira/browse/CB-7190): Add browserify support in cordova-lib/cordova-cli
* [CB-7234](https://issues.apache.org/jira/browse/CB-7234) added better outputs for plugin registry workflows
* [CB-7100](https://issues.apache.org/jira/browse/CB-7100): Use npm based lazy-load by default
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Remove check_requirements() funcs from platform parsers
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Remove check_requirements() funcs from platform parsers
* [CB-7140](https://issues.apache.org/jira/browse/CB-7140) Check plugin versions in local search path
* small refactor for missing code block after conditional statement
* [CB-7203](https://issues.apache.org/jira/browse/CB-7203) isRelativePath needs to pass path through
* [CB-7199](https://issues.apache.org/jira/browse/CB-7199) control git/npm using platform.js
* [CB-7199](https://issues.apache.org/jira/browse/CB-7199) control git/npm using platform.js
* Fix style errors - make jshint happy
* [CB-6756](https://issues.apache.org/jira/browse/CB-6756) Adds save and restore command for platforms.
* Add VERSION files to fix failing tests (forgot to git add in b7781cb)
* [CB-7132](https://issues.apache.org/jira/browse/CB-7132) Fix regression regarding default resources
* [CB-7187](https://issues.apache.org/jira/browse/CB-7187) Make CoreLocation a required library only for cordova-ios < 3.6.0
* Add AppVeyor badge to README
* Add Travis and npm badges to README.md
* fix(tests): cordova/lazy_load spec on Windows
* Fix plugman/install spec
* build configuration for AppVeyor
* build configurations for Travis
* [CB-7124](https://issues.apache.org/jira/browse/CB-7124) Wrap the cordova platform string in Platform object
* [CB-7140](https://issues.apache.org/jira/browse/CB-7140): Switch to using PluginInfo in plugman/fetch.js
* Minor style fixes in fetch.js
* [CB-7078](https://issues.apache.org/jira/browse/CB-7078): Disable serve.spec.js
* [CB-6512](https://issues.apache.org/jira/browse/CB-6512): platform add <path> was using wrong www/cordova.js
* [CB-7083](https://issues.apache.org/jira/browse/CB-7083) Missing SDKReference support on Windows Phone
* [CB-6874](https://issues.apache.org/jira/browse/CB-6874) Consolidate <Content> tag additions into 1 ItemGroup
* [CB-7100](https://issues.apache.org/jira/browse/CB-7100): Use npm based lazy-load by default
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Remove check_requirements() funcs from platform parsers
* [CB-7091](https://issues.apache.org/jira/browse/CB-7091): Don't call check_requirements during platform add
* Fix typo in comment.
* [CB-7087](https://issues.apache.org/jira/browse/CB-7087) Retire blackberry10/ directory
* [CB-6776](https://issues.apache.org/jira/browse/CB-6776): Fix uri/url renaming bug
* Remove npm-shrinkwrap.json


### 0.21.4 (Jun 23, 2014)
* [CB-3571](https://issues.apache.org/jira/browse/CB-3571), [CB-2606](https://issues.apache.org/jira/browse/CB-2606): support for splashscreens
* [CB-6976](https://issues.apache.org/jira/browse/CB-6976) Add support for Windows Universal apps (Windows 8.1 and WP 8.1)
* Use Plugininfo module to determine plugin id and version
* Fix plugin check error, when plugin dependency with specific version is given
* [CB-6709](https://issues.apache.org/jira/browse/CB-6709) Do not create merges/ folder when adding a platform
* [CB-6140](https://issues.apache.org/jira/browse/CB-6140) Don't allow deletion of platform dependencies
* [CB-6698](https://issues.apache.org/jira/browse/CB-6698): Fix 'android update lib-project' to work with paths containing spaces
* [CB-6973](https://issues.apache.org/jira/browse/CB-6973): Run JSHint on all code in src/ via npm test
* [CB-6542](https://issues.apache.org/jira/browse/CB-6542): Delay creating project until there's some chance that it will succeed
* folder_contents() now ignores .svn folders
* [CB-6970](https://issues.apache.org/jira/browse/CB-6970) Share win project files manipulation code between cordova and plugman
* [CB-6954](https://issues.apache.org/jira/browse/CB-6954): Share events.js between cordova and plugman
* [CB-6698](https://issues.apache.org/jira/browse/CB-6698) Automatically copy sub-libraries to project's directory
* Revert "CB-6698 Resolve android <framework> relative to plugin_dir when custom=true"
* [CB-6942](https://issues.apache.org/jira/browse/CB-6942) Describe running hooks only in verbose mode.
* [CB-6512](https://issues.apache.org/jira/browse/CB-6512): Allow "cordova platform add /path/to/platform/files"
* Update hooks-README.md - shebang line in hooks on Windows.
* [CB-6895](https://issues.apache.org/jira/browse/CB-6895) Add more config properties into manifest
* Allow "cordova platform add platform@version"
* Add util func for chaining promises
* removing doWrap from prepare
* adding configurable attribute
* cleaning up plugman.js for uninstall
* adding param to uninstall
* adding support for prepare flag
* adding prepare-browserify
* adding options to prepare
* adding and freezing cordova-js
* [CB-6879](https://issues.apache.org/jira/browse/CB-6879) config parser breakout into a cordova level module
* [CB-6698](https://issues.apache.org/jira/browse/CB-6698) Resolve android <framework> relative to plugin_dir when custom=true
* Fix tests on node 0.11.x
* Fix android <framework> unit tests to not expect end of line.
* [CB-6024](https://issues.apache.org/jira/browse/CB-6024): Accept cli vars as part of opts param
* Refer properties-parser package from NPM.
* [CB-6859](https://issues.apache.org/jira/browse/CB-6859) Removed all wp7 references, tests still passing
* Extract AndroidProject class into a separate .js file
* [CB-6698](https://issues.apache.org/jira/browse/CB-6698): Support library references for Android via the framework tag
* [CB-6854](https://issues.apache.org/jira/browse/CB-6854) Strip BOM when adding cordova.define() to js-modules
* Add npm cache based downloading to lazy_load
* Use PluginInfo in plugman/install.js
* Extend PluginInfo to parse more of plugin.xml
* [CB-6772](https://issues.apache.org/jira/browse/CB-6772) Provide a default for AndroidLaunchMode
* [CB-6711](https://issues.apache.org/jira/browse/CB-6711): Use parseProjectFile when working with XCode projects.
* Start using PluginInfo object in plugman/install.js
* [CB-6709](https://issues.apache.org/jira/browse/CB-6709) Remove merges/ folder for default apps
* support for shrinkwrap flag
* Initial implementation for restore and save plugin
* [CB-6668](https://issues.apache.org/jira/browse/CB-6668): Use <description> for "plugin ls" when <name> is missing.
* Add --noregstry flag for disabling plugin lookup in the registry
* Remove --force from default npm settings for plugin registry
* Use "npm info" for fetching plugin metadata
* Use "npm cache add" for downloading plugins
* [CB-6691](https://issues.apache.org/jira/browse/CB-6691): Change some instances of Error() to CordovaError()


### 0.21.1
Initial release v0.21.1 (picks up from the same version number as plugman was).


================================================
FILE: cordova-lib.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const common = require('cordova-common');

module.exports = {
    set binname (name) {
        this.cordova.binname = name;
    },
    get binname () {
        return this.cordova.binname;
    },
    events: common.events,
    configparser: common.ConfigParser,
    PluginInfo: common.PluginInfo,
    CordovaError: common.CordovaError,
    plugman: require('./src/plugman/plugman'),
    cordova: require('./src/cordova/cordova'),
    cordova_platforms: require('./src/platforms/platforms')
};


================================================
FILE: eslint.config.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const { defineConfig, globalIgnores } = require('eslint/config');
const nodeConfig = require('@cordova/eslint-config/node');
const nodeTestConfig = require('@cordova/eslint-config/node-tests');

module.exports = defineConfig([
    globalIgnores([
        '**/coverage/',
        'spec/cordova/fixtures/*',
        'spec/plugman/projects/*',
        'spec/plugman/plugins/*',
        'spec/cordova/temp/*'

    ]),
    ...nodeConfig,
    ...nodeTestConfig.map(config => ({
        files: ['spec/**/*.js', 'integration-tests/**/*.js'],
        ...config
    }))
]);


================================================
FILE: integration-tests/HooksRunner.spec.js
================================================
/**
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 **/

const fs = require('node:fs');
const path = require('node:path');
const timers = require('node:timers/promises');
const et = require('elementtree');

const HooksRunner = require('../src/hooks/HooksRunner');
const cordova = require('../src/cordova/cordova');
const { tmpDir } = require('../spec/helpers');
const { PluginInfo, ConfigParser } = require('cordova-common');

const ext = process.platform === 'win32' ? 'bat' : 'sh';
const fixtures = path.join(__dirname, '../spec/cordova/fixtures');

describe('HooksRunner', function () {
    let tmp, project, hooksRunner;

    // This prepares a project that we will copy and use for all tests
    beforeEach(() => {
        tmp = tmpDir('hooks_test');
        project = path.join(tmp, 'project');

        // Copy base project fixture
        fs.cpSync(path.join(fixtures, 'basePkgJson'), project, { recursive: true });

        // Copy project hooks
        const hooksDir = path.join(fixtures, 'projectHooks');
        fs.cpSync(hooksDir, path.join(project, 'scripts'), { recursive: true });

        // Change into our project directory
        process.chdir(project);
        process.env.PWD = project; // this is used by cordovaUtil.isCordova

        hooksRunner = new HooksRunner(project);
    });

    afterEach(() => {
        process.chdir(path.join(__dirname, '..')); // Non e2e tests assume CWD is repo root.
        fs.rmSync(tmp, { recursive: true, force: true });
    });

    it('Test 001 : should throw if provided directory is not a cordova project', function () {
        expect(_ => new HooksRunner(tmp)).toThrow();
    });

    it('Test 002 : should not throw if provided directory is a cordova project', function () {
        expect(_ => new HooksRunner(project)).not.toThrow();
    });

    describe('fire method', function () {
        const test_event = 'before_build';
        let hooksOrderFile;

        beforeEach(function () {
            hooksOrderFile = path.join(project, 'hooks_order.txt');
            fs.rmSync(hooksOrderFile, { recursive: true, force: true });
        });

        // helper methods
        function getActualHooksOrder () {
            const fileContents = fs.readFileSync(hooksOrderFile, 'ascii');
            return fileContents.match(/\d+/g).map(Number);
        }

        function checkHooksOrderFile () {
            expect(hooksOrderFile).toExist();

            const hooksOrder = getActualHooksOrder();
            const sortedHooksOrder = hooksOrder.slice(0).sort((a, b) => a - b);
            expect(hooksOrder).toEqual(sortedHooksOrder);
        }

        function addHooks (hooksXml, doc) {
            const hooks = et.parse(hooksXml);
            for (const el of hooks.getroot().findall('./*')) {
                doc.getroot().append(el);
            }
        }

        describe('application hooks', function () {
            const BASE_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <hook type="before_build" src="scripts/appBeforeBuild1.${ext}" />
                    <hook type="before_build" src="scripts/appBeforeBuild02.js" />
                </widget>
            `;
            const WINDOWS_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <platform name="windows">
                        <hook type="before_build" src="scripts/windows/appWindowsBeforeBuild.${ext}" />
                        <hook type="before_build" src="scripts/windows/appWindowsBeforeBuild.js" />
                    </platform>
                </widget>
            `;
            const ANDROID_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <platform name="android">
                        <hook type="before_build" src="scripts/android/appAndroidBeforeBuild.${ext}" />
                        <hook type="before_build" src="scripts/android/appAndroidBeforeBuild.js" />
                    </platform>
                </widget>
            `;

            function addHooksToConfig (hooksXml) {
                const config = new ConfigParser(path.join(project, 'config.xml'));
                addHooks(hooksXml, config.doc);
                config.write();
            }

            it('Test 006 : should execute hook scripts serially from config.xml', function () {
                addHooksToConfig(BASE_HOOKS);

                return hooksRunner.fire(test_event)
                    .then(checkHooksOrderFile);
            });

            it('Test 007 : should execute hook scripts serially from config.xml including platform scripts', function () {
                addHooksToConfig(BASE_HOOKS);
                addHooksToConfig(WINDOWS_HOOKS);

                return hooksRunner.fire(test_event)
                    .then(checkHooksOrderFile);
            });

            it('Test 008 : should filter hook scripts from config.xml by platform', function () {
                addHooksToConfig(BASE_HOOKS);
                addHooksToConfig(WINDOWS_HOOKS);
                addHooksToConfig(ANDROID_HOOKS);
                const hookOptions = { cordova: { platforms: ['android'] } };

                return hooksRunner.fire(test_event, hookOptions).then(function () {
                    checkHooksOrderFile();

                    const baseScriptResults = [8, 9];
                    const androidPlatformScriptsResults = [14, 15];
                    const expectedResults = baseScriptResults.concat(androidPlatformScriptsResults);
                    expect(getActualHooksOrder()).toEqual(expectedResults);
                });
            });

            it('Test 023 : should error if any hook fails', function () {
                const FAIL_HOOK = `
                    <widget xmlns="http://www.w3.org/ns/widgets">
                        <hook type="fail" src="scripts/fail.js" />
                    </widget>
                `;
                addHooksToConfig(FAIL_HOOK);

                return expectAsync(
                    hooksRunner.fire('fail')
                ).toBeRejectedWithError();
            });

            it('Test 024 : should not error if the hook is unrecognized', function () {
                return hooksRunner.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!');
            });
        });

        describe('plugin hooks', function () {
            const PLUGIN_BASE_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <hook type="before_build" src="scripts/beforeBuild.js" />
                    <hook type="before_build" src="scripts/beforeBuild.${ext}" />
                </widget>
            `;
            const PLUGIN_WINDOWS_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <platform name="windows">
                        <hook type="before_build" src="scripts/windows/windowsBeforeBuild.js" />
                    </platform>
                </widget>
            `;
            const PLUGIN_ANDROID_HOOKS = `
                <widget xmlns="http://www.w3.org/ns/widgets">
                    <platform name="android">
                        <hook type="before_build" src="scripts/android/androidBeforeBuild.js" />
                    </platform>
                </widget>
            `;
            const testPlugin = 'com.plugin.withhooks';
            const testPluginFixture = path.join(fixtures, 'plugins', testPlugin);
            let testPluginInstalledPath;

            beforeEach(() => {
                // Add the test plugin to our project
                testPluginInstalledPath = path.join(project, 'plugins', testPlugin);
                fs.cpSync(testPluginFixture, testPluginInstalledPath, { recursive: true });
            });

            function addHooksToPlugin (hooksXml) {
                const config = new PluginInfo(testPluginInstalledPath);
                addHooks(hooksXml, config._et);

                const configPath = path.join(testPluginInstalledPath, 'plugin.xml');
                fs.writeFileSync(configPath, config._et.write({ indent: 4 }));
            }

            it('Test 009 : should execute hook scripts serially from plugin.xml', function () {
                addHooksToPlugin(PLUGIN_BASE_HOOKS);

                return hooksRunner.fire(test_event)
                    .then(checkHooksOrderFile);
            });

            it('Test 010 : should execute hook scripts serially from plugin.xml including platform scripts', function () {
                addHooksToPlugin(PLUGIN_BASE_HOOKS);
                addHooksToPlugin(PLUGIN_WINDOWS_HOOKS);

                return hooksRunner.fire(test_event)
                    .then(checkHooksOrderFile);
            });

            it('Test 011 : should filter hook scripts from plugin.xml by platform', function () {
                addHooksToPlugin(PLUGIN_BASE_HOOKS);
                addHooksToPlugin(PLUGIN_WINDOWS_HOOKS);
                addHooksToPlugin(PLUGIN_ANDROID_HOOKS);
                const hookOptions = { cordova: { platforms: ['android'] } };

                return hooksRunner.fire(test_event, hookOptions).then(function () {
                    checkHooksOrderFile();

                    const baseScriptResults = [21, 22];
                    const androidPlatformScriptsResults = [26];
                    const expectedResults = baseScriptResults.concat(androidPlatformScriptsResults);
                    expect(getActualHooksOrder()).toEqual(expectedResults);
                });
            });
        });

        describe('nohooks option', () => {
            it('Test 013 : should not execute the designated hook when --nohooks option specifies the exact hook name', async () => {
                const hookOptions = { nohooks: [test_event] };

                expect(await hooksRunner.fire(test_event, hookOptions))
                    .toBe('hook before_build is disabled.');
            });

            it('Test 014 : should not execute matched hooks when --nohooks option specifies a hook pattern', async () => {
                const hookOptions = { nohooks: ['ba'] };

                for (const e of ['foo', 'bar', 'baz']) {
                    expect(await hooksRunner.fire(e, hookOptions))
                        .toBe(e === 'foo' ? undefined : `hook ${e} is disabled.`);
                }
            });

            it('Test 015 : should not execute any hooks when --nohooks option specifies .', async () => {
                const hookOptions = { nohooks: ['.'] };

                for (const e of ['foo', 'bar', 'baz']) {
                    expect(await hooksRunner.fire(e, hookOptions))
                        .toBe(`hook ${e} is disabled.`);
                }
            });
        });

        describe('module-level hooks (event handlers)', function () {
            let handler;

            beforeEach(() => {
                handler = jasmine.createSpy('testHandler').and.resolveTo();
                cordova.on(test_event, handler);
            });

            afterEach(function () {
                cordova.removeAllListeners(test_event);
            });

            it('Test 016 : should fire handlers that were attached using cordova.on', function () {
                return hooksRunner.fire(test_event).then(function () {
                    expect(handler).toHaveBeenCalled();
                });
            });

            it('Test 017 : should pass the project root folder as parameter into the module-level handlers', function () {
                return hooksRunner.fire(test_event).then(function () {
                    expect(handler).toHaveBeenCalledWith(jasmine.objectContaining({
                        projectRoot: project
                    }));
                });
            });

            it('Test 018 : should be able to stop listening to events using cordova.off', function () {
                cordova.off(test_event, handler);
                return hooksRunner.fire(test_event).then(function () {
                    expect(handler).not.toHaveBeenCalled();
                });
            });

            it('Test 019 : should execute async event listeners serially', function () {
                const order = [];
                // Delay 100 ms here to check that h2 is not executed until after
                // the promise returned by h1 is resolved.
                const h1 = _ => timers.setTimeout(100).then(_ => order.push(1));
                const h2 = _ => Promise.resolve().then(_ => order.push(2));

                cordova.on(test_event, h1);
                cordova.on(test_event, h2);

                return hooksRunner.fire(test_event)
                    .then(_ => expect(order).toEqual([1, 2]));
            });

            it('Test 021 : should pass options passed to fire into handlers', async () => {
                const hookOptions = { test: 'funky' };
                await hooksRunner.fire(test_event, hookOptions);
                expect(handler).toHaveBeenCalledWith(hookOptions);
            });
        });
    });
});


================================================
FILE: integration-tests/fetch.spec.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const path = require('node:path');
const fs = require('node:fs');
const helpers = require('../spec/helpers');
const cordova = require('../src/cordova/cordova');

const TIMEOUT = 60 * 1000;
const plugins_dir = path.join(__dirname, '..', 'spec', 'plugman', 'plugins');

const plugins = {
    Test1: path.join(plugins_dir, 'dependencies', 'Test1'),
    Test2: path.join(plugins_dir, 'dependencies', 'Test2'),
    Test3: path.join(plugins_dir, 'dependencies', 'Test3'),
    Test4: path.join(plugins_dir, 'dependencies', 'Test4')
};

describe('end-to-end plugin dependency tests', function () {
    helpers.setDefaultTimeout(TIMEOUT);

    // This prepares a project that we will copy and use for all tests
    let preparedProject;
    beforeAll(function () {
        preparedProject = helpers.tmpDir('plugin_dependency_test_project');
        return helpers.getFixture('projectWithPlatform').copyTo(preparedProject);
    });

    afterAll(function () {
        process.chdir(__dirname); // Needed to rm the dir on Windows.
        fs.rmSync(preparedProject, { recursive: true, force: true });
    });

    let tmpDir, project, pluginsDir;
    beforeEach(function () {
        tmpDir = helpers.tmpDir('plugin_dependency_test');
        project = path.join(tmpDir, 'project');
        pluginsDir = path.join(project, 'plugins');

        fs.cpSync(preparedProject, project, { recursive: true });
        process.chdir(project);
        delete process.env.PWD;
    });

    afterEach(function () {
        process.chdir(__dirname); // Needed to rm the dir on Windows.
        fs.rmSync(tmpDir, { recursive: true, force: true });
    });

    it('Test 029 : should fail if dependency already installed is wrong version', function () {
        return Promise.resolve()
            .then(function () {
                return cordova.plugin('add', 'cordova-plugin-file');
            }).then(function () {
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                return cordova.plugin('add', plugins.Test1);
            }).catch(function (err) {
                expect(err.message).toContain('does not satisfy dependency plugin requirement');
            });
    });

    it('Test 030 : should pass if dependency already installed is wrong version with --force', function () {
        return Promise.resolve()
            .then(function () {
                return cordova.plugin('add', 'cordova-plugin-file');
            })
            .then(function () {
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                return cordova.plugin('add', plugins.Test1, { force: true });
            })
            .then(function () {
                expect(path.join(pluginsDir, 'Test1')).toExist();
            });
    });

    it('Test 031 : should pass if dependency already installed is same major version (if specific version is specified)', function () {
        // Test1 requires cordova-plugin-file version 2.0.0 (which should automatically turn into ^2.0.0); we'll install version 2.1.0
        return Promise.resolve()
            .then(function () {
                return cordova.plugin('add', 'cordova-plugin-file@2.1.0');
            })
            .then(function () {
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                return cordova.plugin('add', plugins.Test1);
            })
            .then(function () {
                expect(path.join(pluginsDir, 'Test1')).toExist();
            });
    });

    it('Test 032 : should handle two plugins with same dependent plugin', function () {
        // Test1 and Test2 have compatible dependencies on cordova-plugin-file
        // Test1 and Test3 have incompatible dependencies on cordova-plugin-file
        return Promise.resolve()
            .then(function () {
                return cordova.plugin('add', plugins.Test1);
            })
            .then(function () {
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                expect(path.join(pluginsDir, 'Test1')).toExist();
                return cordova.plugin('add', plugins.Test2);
            })
            .then(function () {
                return cordova.plugin('add', plugins.Test3);
            })
            .catch(function (err) {
                expect(path.join(pluginsDir, 'Test2')).toExist();
                expect(path.join(pluginsDir, 'Test3')).not.toExist();
                expect(err.message).toContain('does not satisfy dependency plugin requirement');
            });
    });

    it('Test 033 : should use a dev version of a dependent plugin if it is already installed', function () {
        // Test4 has this dependency in its plugin.xml:
        // <dependency id="cordova-plugin-file" url="https://github.com/apache/cordova-plugin-file" />
        return Promise.resolve()
            .then(function () {
                return cordova.plugin('add', 'https://github.com/apache/cordova-plugin-file');
            })
            .then(function () {
                return cordova.plugin('add', plugins.Test4);
            })
            .then(function () {
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                expect(path.join(pluginsDir, 'Test4')).toExist();
            });
    });
});


================================================
FILE: integration-tests/pkgJson.spec.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const path = require('node:path');
const fs = require('node:fs');
const semver = require('semver');
const { listPlatforms, requireNoCache } = require('../src/cordova/util');
const { tmpDir: getTmpDir, testPlatform, getFixture, setDefaultTimeout } = require('../spec/helpers');
const projectTestHelpers = require('../spec/project-test-helpers');
const cordova = require('../src/cordova/cordova');

describe('pkgJson', function () {
    const TIMEOUT = 150 * 1000;
    setDefaultTimeout(TIMEOUT);

    const fixturesPath = path.join(__dirname, '../spec/cordova/fixtures');
    let tmpDir, project, pkgJsonPath;
    const {
        getPkgJsonPath, setupBaseProject, getCfg, getPkgJson, setPkgJson
    } = projectTestHelpers(() => project);

    beforeEach(() => {
        tmpDir = getTmpDir('pkgJson');
        project = path.join(tmpDir, 'project');
        pkgJsonPath = getPkgJsonPath();
        delete process.env.PWD;
    });

    afterEach(() => {
        process.chdir(__dirname); // Needed to rm the dir on Windows.
        fs.rmSync(tmpDir, { recursive: true, force: true });
    });

    // Copies a fixture to temp dir to avoid modifiying it as they get installed as symlinks
    function copyFixture (fixtureRelativePath) {
        const fixturePath = path.join(fixturesPath, fixtureRelativePath);
        const tmpPath = path.join(tmpDir, path.basename(fixtureRelativePath));
        fs.cpSync(fixturePath, tmpPath, { recursive: true });
        return tmpPath;
    }

    function installedPlatforms () {
        // Sort platform list to allow for easy pseudo set equality
        return listPlatforms(project).sort();
    }

    function platformVersion (platformName) {
        const p = path.join(project, 'platforms', platformName, 'cordova/Api.js');
        expect(p).toExist();
        return requireNoCache(p).version();
    }

    function pluginVersion (pluginName) {
        const p = path.join(project, 'plugins', pluginName, 'package.json');
        expect(p).toExist();
        return JSON.parse(fs.readFileSync(p)).version;
    }

    function specSatisfiedBy (version) {
        return {
            asymmetricMatch: spec => semver.satisfies(version, spec),
            jasmineToString: _ => `<specSatisfiedBy(${version})>`
        };
    }

    function specWithMinSatisfyingVersion (version) {
        return {
            asymmetricMatch: spec =>
                !semver.intersects(spec, `<${version}`) &&
                semver.intersects(spec, `>=${version}`),
            jasmineToString: _ => `<specWithMinSatisfyingVersion(${version})>`
        };
    }

    const customMatchers = {
        toSatisfy: () => ({
            compare (version, spec) {
                const pass = semver.satisfies(version, spec);
                const expectation = (pass ? 'not ' : '') + 'to satisfy';
                return {
                    pass, message: `expected ${version} ${expectation} ${spec}`
                };
            }
        }),
        tohaveMinSatisfyingVersion: () => ({
            compare (spec, version) {
                const pass = specWithMinSatisfyingVersion(version).asymmetricMatch(spec);
                const expectation = (pass ? 'not ' : '') + 'to have minimal satisfying version';
                return {
                    pass, message: `expected ${spec} ${expectation} ${version}`
                };
            }
        })
    };

    // Add our custom matchers
    beforeEach(() => jasmine.addMatchers(customMatchers));

    // This group of tests checks if plugins are added and removed as expected from package.json.
    describe('plugin end-to-end', function () {
        const pluginId = 'cordova-plugin-device';

        // Prepare a project with platform that can be reused by below tests
        let projectFixture;
        beforeAll(() => {
            projectFixture = getTmpDir('pkgJson-project-fixture');
            return getFixture('projectWithPlatform').copyTo(projectFixture);
        });

        afterAll(() => {
            process.chdir(__dirname); // Needed to rm the dir on Windows.
            fs.rmSync(projectFixture, { recursive: true, force: true });
        });

        beforeEach(function () {
            fs.cpSync(projectFixture, project, { recursive: true });
            process.chdir(project);
        });

        it('Test#001 : should successfully add and remove a plugin with save and correct spec', function () {
            // No plugins in config or pkg.json yet.
            expect(getCfg().getPluginIdList()).toEqual([]);
            expect(getPkgJson('cordova.plugins')).toBeUndefined();

            // Add the plugin with --save.
            return cordova.plugin('add', `${pluginId}@1.1.2`, { save: true })
                .then(function () {
                    // Check that the plugin and spec add was successful to pkg.json.
                    expect(getPkgJson('cordova.plugins')[pluginId]).toBeDefined();
                    expect(getPkgJson('devDependencies')[pluginId]).tohaveMinSatisfyingVersion('1.1.2');

                    expect(getCfg().getPluginIdList()).toEqual([]);
                }).then(function () {
                    // And now remove it with --save.
                    return cordova.plugin('rm', pluginId, { save: true });
                }).then(function () {
                    // Expect plugin to be removed from pkg.json.
                    expect(getPkgJson('cordova.plugins')[pluginId]).toBeUndefined();
                    expect(getPkgJson('devDependencies')[pluginId]).toBeUndefined();
                });
        });

        it('Test#002 : should NOT add a plugin to package.json if --save is not used', function () {
            const SAVED_PLUGIN = 'cordova-plugin-geolocation';
            expect(pkgJsonPath).toExist();

            // Add the geolocation plugin with --save.
            return cordova.plugin('add', SAVED_PLUGIN, { save: true })
                .then(function () {
                    // Add a second plugin without save.
                    return cordova.plugin('add', pluginId);
                }).then(function () {
                    // Expect that only the plugin that had --save was added.
                    expect(getPkgJson('cordova.plugins')).toEqual({
                        [SAVED_PLUGIN]: jasmine.anything()
                    });
                });
        });

        it('Test#003 : should NOT remove plugin from package.json if there is no --save', function () {
            expect(pkgJsonPath).toExist();

            // Add the plugin with --save.
            return cordova.plugin('add', pluginId, { save: true })
                .then(function () {
                    expect(getPkgJson('cordova.plugins')).toEqual({
                        [pluginId]: {}
                    });
                }).then(function () {
                    // And now remove it, but without --save.
                    return cordova.plugin('rm', pluginId);
                }).then(function () {
                    // The plugin should still be in package.json.
                    expect(getPkgJson('cordova.plugins')).toEqual({
                        [pluginId]: {}
                    });
                });
        });

        it('Test#004 : should successfully add and remove a plugin with variables and save to package.json', function () {
            expect(pkgJsonPath).toExist();

            // Add the plugin with --save.
            return cordova.plugin('add', pluginId, { save: true, cli_variables: { someKey: 'someValue' } })
                .then(function () {
                    // Check the plugin add was successful and that variables have been added too.
                    expect(getPkgJson('cordova.plugins')).toEqual({
                        [pluginId]: { someKey: 'someValue' }
                    });
                }).then(function () {
                    // And now remove it with --save.
                    return cordova.plugin('rm', pluginId, { save: true });
                }).then(function () {
                    // Checking that the plugin and variables were removed successfully.
                    expect(getPkgJson('cordova.plugins')).toEqual({});
                });
        });

        it('Test#005 : should successfully add and remove multiple plugins with save & fetch', function () {
            const OTHER_PLUGIN = 'cordova-plugin-device-motion';
            expect(pkgJsonPath).toExist();

            // Add the plugin with --save.
            return cordova.plugin('add', [pluginId, OTHER_PLUGIN], { save: true })
                .then(function () {
                    // Check that the plugin add was successful.
                    expect(getPkgJson('cordova.plugins')).toEqual({
                        [pluginId]: {}, [OTHER_PLUGIN]: {}
                    });
                    expect(getPkgJson('devDependencies')).toEqual({
                        'cordova-android': jasmine.any(String),
                        [pluginId]: jasmine.any(String),
                        [OTHER_PLUGIN]: jasmine.any(String)
                    });
                }).then(function () {
                    // And now remove it with --save.
                    return cordova.plugin('rm', [pluginId, OTHER_PLUGIN], { save: true });
                }).then(function () {
                    // Checking that the plugin removed is in not in the platforms.
                    expect(getPkgJson('cordova.plugins')).toEqual({});
                    expect(getPkgJson('devDependencies')).toEqual({
                        'cordova-android': jasmine.any(String)
                    });
                });
        });

        // Test #023 : if pkg.json and config.xml have no platforms/plugins/spec.
        // and --save is called, use the pinned version or plugin pkg.json version.
        it('Test#023 : use pinned/lastest version if there is no platform/plugin version passed in and no platform/plugin versions in pkg.json or config.xml', function () {
            const PLATFORM = 'ios';
            const PLUGIN = 'cordova-plugin-geolocation';

            // Pkg.json has no platform or plugin or specs.
            expect(getPkgJson('cordova.platforms')).not.toContain(PLATFORM);
            expect(getPkgJson(`devDependencies.${PLUGIN}`)).toBeUndefined();

            // Config.xml has no platform or plugin or specs.
            expect(getCfg().getEngines()).not.toContain(PLATFORM);
            expect(getCfg().getPluginIdList()).toEqual([]);

            return cordova.platform('add', PLATFORM, { save: true })
                .then(function () {
                    expect(getPkgJson('cordova.platforms')).toContain(PLATFORM);
                }).then(function () {
                    return cordova.plugin('add', PLUGIN, { save: true });
                }).then(function () {
                    const iosJson = JSON.parse(fs.readFileSync(path.join(project, 'platforms/ios/ios.json')));
                    expect(iosJson.installed_plugins[PLUGIN]).toBeDefined();

                    // Check that installed version satisfies the dependency spec
                    const version = pluginVersion(PLUGIN);
                    expect(version).toSatisfy(getPkgJson(`devDependencies.${PLUGIN}`));
                });
        });

        // Test#025: has a pkg.json. Checks if local path is added to pkg.json for platform and plugin add.
        it('Test#025 : if you add a plugin with local path, pkg.json gets updated', () => {
            const PLUGIN = 'cordova-lib-test-plugin';
            const pluginPath = copyFixture(path.join('plugins', PLUGIN));

            // Run cordova plugin add local path --save
            return cordova.plugin('add', pluginPath, { save: true })
                .then(() => {
                    // Pkg.json has test plugin.
                    expect(getPkgJson(`cordova.plugins.${PLUGIN}`)).toBeDefined();
                    expect(getPkgJson(`devDependencies.${PLUGIN}`)).toBeDefined();
                });
        });

        it('Test#026 : should successfully add a plugin with git/semver combo', async () => {
            const TAG = '#semver:2.0.x';
            const URL = `https://github.com/apache/cordova-plugin-device.git${TAG}`;

            expect(getPkgJson('cordova.plugins')).toBeUndefined();
            expect(getPkgJson(`devDependencies.${pluginId}`)).toBeUndefined();

            await cordova.plugin('add', URL, { save: true });
            expect(getPkgJson('cordova.plugins')[pluginId]).toBeDefined();
            expect(getPkgJson('devDependencies')[pluginId]).toContain(TAG);
        });
    });

    // This group of tests checks if platforms are added and removed as expected from package.json.
    describe('platform end-to-end with --save', function () {
        beforeEach(() => setupBaseProject());

        it('Test#006 : platform is added and removed correctly with --save', function () {
            expect(pkgJsonPath).toExist();
            expect(installedPlatforms()).toEqual([]);

            // Add the testing platform with --save.
            return cordova.platform('add', testPlatform, { save: true }).then(function () {
                // Check the platform add was successful.
                expect(installedPlatforms()).toEqual([testPlatform]);
                expect(getPkgJson('cordova.platforms')).toEqual([testPlatform]);
            }).then(function () {
                // And now remove it with --save.
                return cordova.platform('rm', testPlatform, { save: true });
            }).then(function () {
                // Checking that the platform removed is in not in the platforms key.
                expect(getPkgJson('cordova.platforms')).toEqual([]);
            });
        });

        it('Test#007 : should not remove platforms from package.json when removing without --save', function () {
            expect(pkgJsonPath).toExist();
            expect(installedPlatforms()).toEqual([]);

            // Add the testing platform with --save.
            return cordova.platform('add', testPlatform, { save: true }).then(function () {
                // Check the platform add was successful.
                expect(installedPlatforms()).toEqual([testPlatform]);
                expect(getPkgJson('cordova.platforms')).toEqual([testPlatform]);
            }).then(function () {
                // And now remove it without --save.
                return cordova.platform('rm', testPlatform);
            }).then(function () {
                // Check that the removed platform is still in cordova.platforms...
                expect(getPkgJson('cordova.platforms')).toEqual([testPlatform]);
                // ... but is not actually installed any longer
                expect(installedPlatforms()).toEqual([]);
            });
        });

        it('Test#008 : should not add platform to package.json when adding without --save', function () {
            expect(getPkgJson('cordova')).toBeUndefined();

            // Add platform without --save.
            return cordova.platform('add', testPlatform)
                .then(function () {
                    // Test platform should have been installed but not added to pkg.json
                    expect(installedPlatforms()).toEqual([testPlatform]);
                    expect(getPkgJson('cordova')).toBeUndefined();
                });
        });

        it('Test#009 : should only add the platform to package.json with --save', function () {
            const platformNotToAdd = 'ios';
            expect(pkgJsonPath).toExist();

            // Add a platform without --save.
            return cordova.platform('add', platformNotToAdd)
                .then(function () {
                    // And now add another platform with --save.
                    return cordova.platform('add', testPlatform, { save: true });
                }).then(function () {
                    // Check that only the platform added with --save was added to package.json.
                    expect(getPkgJson('cordova.platforms')).toEqual([testPlatform]);
                });
        });

        it('Test#010 : two platforms are added and removed correctly with --save', function () {
            // No platforms installed nor saved in config or pkg.json yet.
            expect(getPkgJson('cordova')).toBeUndefined();
            expect(getCfg().getEngines()).toEqual([]);
            expect(installedPlatforms()).toEqual([]);

            // Add the testing platform with --save and add specific version to android platform.
            return cordova.platform('add', ['android@9.0.0', 'ios@6.1.0'], { save: true }).then(function () {
                expect(installedPlatforms()).toEqual(['android', 'ios']);

                // Check the platform add was successful in platforms list and
                // dependencies should have specific version from add.
                expect(getPkgJson('cordova.platforms')).toEqual(['android', 'ios']);
                expect(getPkgJson('devDependencies')).toEqual({
                    'cordova-android': specWithMinSatisfyingVersion('9.0.0'),
                    'cordova-ios': specWithMinSatisfyingVersion('6.1.0')
                });

                expect(getCfg().getEngines()).toEqual([]);
            }).then(function () {
                // And now remove it with --save.
                return cordova.platform('rm', ['android', 'ios'], { save: true });
            }).then(function () {
                // Expect platforms to be uninstalled & removed from config files
                expect(getPkgJson('cordova.platforms')).toEqual([]);
                expect(getPkgJson('devDependencies') || {}).toEqual({});
                expect(getCfg().getEngines()).toEqual([]);
                expect(installedPlatforms()).toEqual([]);
            });
        });

        xit('Test#012 : platform with local path is added correctly with --save', () => {
            const PLATFORM = 'android';
            const platformPath = path.join(tmpDir, PLATFORM);

            expect(getPkgJson('cordova')).toBeUndefined();
            expect(installedPlatforms()).toEqual([]);

            return getFixture('androidPlatform').copyTo(platformPath)
                .then(() => {
                    return cordova.platform('add', platformPath, { save: true });
                })
                .then(() => {
                    expect(installedPlatforms()).toEqual([PLATFORM]);
                    expect(getPkgJson('cordova.platforms')).toEqual([PLATFORM]);
                    expect(getPkgJson(`devDependencies.cordova-${PLATFORM}`)).toBeDefined();
                });
        });
    });

    // Test #020 : pkg.json contains platform/spec and plugin/spec and config.xml does not
    describe('with differing config files', function () {
        beforeEach(() => setupBaseProject());

        /** Test#020 will check that pkg.json, config.xml, platforms.json, and cordova platform ls
        *   are updated with the correct (platform and plugin) specs from pkg.json.
        */
        // @todo add a test to also support checking dependencies
        it('Test#020 : During add, if pkg.json has a spec, use that one.', function () {
            const PLATFORM = 'ios';
            const PLUGIN = 'cordova-plugin-splashscreen';

            setPkgJson('cordova.platforms', [PLATFORM]);
            setPkgJson('devDependencies', {
                [PLUGIN]: '^3.2.2',
                [`cordova-${PLATFORM}`]: '^6.1.0'
            });

            // config.xml has no platforms or plugins yet.
            expect(getCfg().getEngines()).toEqual([]);
            expect(getCfg().getPluginIdList()).toEqual([]);

            expect(installedPlatforms()).toEqual([]);

            return cordova.platform('add', PLATFORM, { save: true }).then(function () {
                // No change to pkg.json platforms or spec for ios.
                expect(getPkgJson('cordova.platforms')).toEqual([PLATFORM]);
                // Config.xml and ios/cordova/version check.
                const version = platformVersion(PLATFORM);
                // Check that pkg.json and ios/cordova/version versions "satisfy" each other.
                const pkgSpec = getPkgJson(`devDependencies.cordova-${PLATFORM}`);
                expect(version).toSatisfy(pkgSpec);
            }).then(function () {
                return cordova.plugin('add', PLUGIN, { save: true });
            }).then(function () {
                // Check that installed version satisfies the dependency spec
                expect(pluginVersion(PLUGIN)).toSatisfy(getPkgJson(`devDependencies.${PLUGIN}`));
            });
        }, TIMEOUT * 2);

        /** Test#021 during add, this test will check that pkg.json, config.xml, platforms.json,
        *   and cordova platform ls are updated with the correct platform/plugin spec from config.xml.
        */
        it('Test#021 : If config.xml has a spec (and none was specified and pkg.json does not have one), use config.', function () {
            const PLATFORM = 'ios';
            const PLUGIN = 'cordova-plugin-splashscreen';

            getCfg()
                .addEngine(PLATFORM, '~4.2.1')
                .addPlugin({ name: PLUGIN, spec: '~3.2.2' })
                .write();

            expect(installedPlatforms()).toEqual([]);

            // Remove for testing purposes so platform is not pre-installed.
            return cordova.platform('rm', PLATFORM, { save: true }).then(function () {
                return cordova.platform('add', PLATFORM, { save: true });
            }).then(function () {
                // pkg.json has new platform.
                expect(getPkgJson('cordova.platforms')).toEqual([PLATFORM]);
            }).then(function () {
                return cordova.plugin('add', PLUGIN, { save: true });
            }).then(function () {
                expect(getCfg().getPlugins()).toEqual([{
                    name: PLUGIN,
                    spec: specSatisfiedBy(pluginVersion(PLUGIN)),
                    variables: {}
                }]);
            });
        });

        /** Test#022 : when adding with a specific platform version, always use that one
        *   regardless of what is in package.json or config.xml.
        */
        it('Test#022 : when adding with a specific platform version, always use that one.', function () {
            const PLATFORM = 'ios';
            const PLUGIN = 'cordova-plugin-splashscreen';

            setPkgJson('cordova.platforms', [PLATFORM]);
            setPkgJson('devDependencies', {
                [`cordova-${PLATFORM}`]: '^6.1.0',
                [PLUGIN]: '^3.2.2'
            });
            getCfg()
                .addEngine(PLATFORM, '~6.1.0')
                .addPlugin({ name: PLUGIN, spec: '~3.2.1' })
                .write();

            expect(installedPlatforms()).toEqual([]);

            return cordova.platform('add', `${PLATFORM}@6.1.0`, { save: true }).then(function () {
                // Pkg.json has ios.
                expect(getPkgJson('cordova.platforms')).toEqual([PLATFORM]);
            }).then(function () {
                return cordova.plugin('add', `${PLUGIN}@4.0.0`, { save: true });
            }).then(function () {
                // Check that installed version satisfies the dependency spec
                const version = pluginVersion(PLUGIN);
                expect(version).toSatisfy(getCfg().getPlugin(PLUGIN).spec);
                expect(version).toSatisfy(getPkgJson(`devDependencies.${PLUGIN}`));
            });
        });
    });
});


================================================
FILE: integration-tests/platform.spec.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const path = require('node:path');
const fs = require('node:fs');
const rewire = require('rewire');

const { tmpDir: getTmpDir, testPlatform, setDefaultTimeout } = require('../spec/helpers');
const { listPlatforms } = require('../src/cordova/util');
const cordova = require('../src/cordova/cordova');
const plugman = require('../src/plugman/plugman');

const fixturesDir = path.join(__dirname, '..', 'spec', 'cordova', 'fixtures');
const pluginFixturesDir = path.join(fixturesDir, 'plugins');

describe('cordova/platform end-to-end', () => {
    const TIMEOUT = 240 * 1000;
    setDefaultTimeout(TIMEOUT);

    let tmpDir, project, pluginsDir, platformsDir, nodeModulesDir, testPlatformDir;

    beforeEach(() => {
        tmpDir = getTmpDir('cordova-platform-e2e-test');
        project = path.join(tmpDir, 'project');
        pluginsDir = path.join(project, 'plugins');
        platformsDir = path.join(project, 'platforms');
        nodeModulesDir = path.join(project, 'node_modules');
        testPlatformDir = path.join(platformsDir, testPlatform);

        fs.cpSync(path.join(fixturesDir, 'basePkgJson'), project, { recursive: true });
        process.chdir(project);
    });

    afterEach(() => {
        process.chdir(__dirname); // Needed to rm the dir on Windows.
        fs.rmSync(tmpDir, { recursive: true, force: true });
    });

    function installedPlatforms () {
        return listPlatforms(project);
    }

    it('Test 001 : should successfully run', () => {
        // Check there are no platforms yet.
        expect(installedPlatforms()).toEqual([]);

        return Promise.resolve()
            .then(() => {
                // Add the testing platform.
                return cordova.platform('add', [testPlatform]);
            })
            .then(() => {
                // Check the platform add was successful.
                expect(testPlatformDir).toExist();
                expect(path.join(testPlatformDir, 'cordova')).toExist();
                expect(installedPlatforms()).toEqual([testPlatform]);
            })
            .then(() => {
                // Spy on Api.updatePlatform since it always rejects otherwise
                const Api = require(path.join(nodeModulesDir, 'cordova-android'));
                spyOn(Api, 'updatePlatform').and.returnValue(Promise.resolve());
                spyOn(require('../src/cordova/util'), 'getPlatformApiFunction').and.returnValue(Api);

                return cordova.platform('update', [testPlatform]).then(_ => Api);
            })
            .then(Api => {
                expect(Api.updatePlatform).toHaveBeenCalled();
                // Platform should still be in platform ls.
                expect(installedPlatforms()).toEqual([testPlatform]);
            })
            .then(() => {
                // And now remove it.
                return cordova.platform('rm', [testPlatform]);
            })
            .then(() => {
                // It should be gone.
                expect(testPlatformDir).not.toExist();
                expect(installedPlatforms()).toEqual([]);
            });
    });

    it('Test 002 : should install plugins correctly while adding platform', () => {
        spyOn(plugman, 'install').and.callThrough();
        const prepare = require('../src/cordova/prepare');
        const prepareSpy = jasmine.createSpy('prepare', prepare).and.callThrough();
        Object.assign(prepareSpy, prepare);

        // This is all just to get the prepareSpy to be used by `platform.add`
        const platform = rewire('../src/cordova/platform');
        const addHelper = rewire('../src/cordova/platform/addHelper');
        const requireFake = jasmine.createSpy('require', addHelper.__get__('require')).and.callThrough();
        requireFake.withArgs('../prepare').and.returnValue(prepareSpy);
        addHelper.__set__({ require: requireFake });
        platform.__set__({ addHelper });

        return Promise.resolve()
            .then(() => {
                return cordova.plugin('add', path.join(pluginFixturesDir, 'test'));
            })
            .then(() => {
                return platform('add', [testPlatform]);
            })
            .then(() => {
                // Check the platform add was successful.
                expect(testPlatformDir).toExist();
                // Check that plugin files exists in www dir
                expect(path.join(testPlatformDir, 'platform_www/test.js')).toExist();
                // should call prepare after plugins were installed into platform
                expect(plugman.install).toHaveBeenCalledBefore(prepareSpy);
            });
    });

    it('Test 007 : should add and remove platform from node_modules directory', () => {
        return Promise.resolve()
            .then(() => {
                return cordova.platform('add', 'ios', { save: true });
            })
            .then(() => {
                expect(path.join(nodeModulesDir, 'cordova-ios')).toExist();
                expect(path.join(platformsDir, 'ios')).toExist();
                return cordova.platform('add', 'android@9.0.0');
            })
            .then(() => {
                expect(path.join(nodeModulesDir, 'cordova-android')).toExist();
                expect(path.join(platformsDir, 'android')).toExist();
                return cordova.platform('rm', 'ios', { save: true });
            })
            .then(() => {
                expect(path.join(nodeModulesDir, 'cordova-ios')).not.toExist();
                expect(path.join(platformsDir, 'ios')).not.toExist();
                return cordova.platform('rm', 'android', { save: true });
            })
            .then(() => {
                expect(path.join(nodeModulesDir, 'cordova-android')).not.toExist();
                expect(path.join(platformsDir, 'android')).not.toExist();
            });
    });

    it('Test 008 : should remove dependency when removing parent plugin', () => {
        return Promise.resolve()
            .then(() => {
                return cordova.platform('add', testPlatform);
            })
            .then(() => {
                return cordova.plugin('add', 'cordova-plugin-media', { save: true });
            })
            .then(() => {
                expect(path.join(pluginsDir, 'cordova-plugin-media')).toExist();
                expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
                expect(path.join(nodeModulesDir, 'cordova-plugin-media')).toExist();
                expect(path.join(nodeModulesDir, 'cordova-plugin-file')).toExist();
                return cordova.plugin('rm', 'cordova-plugin-media', { save: true });
            })
            .then(() => {
                expect(path.join(pluginsDir, 'cordova-plugin-media')).not.toExist();
                expect(path.join(pluginsDir, 'cordova-plugin-file')).not.toExist();
                expect(path.join(nodeModulesDir, 'cordova-plugin-media')).not.toExist();
                expect(path.join(nodeModulesDir, 'cordova-plugin-file')).not.toExist();
            });
    });

    it('Test 009 : should add and remove 3rd party platforms', () => {
        return Promise.resolve()
            .then(() => {
                // add cordova-android instead of android
                return cordova.platform('add', 'cordova-android@9.0.0');
            })
            .then(() => {
                // 3rd party platform from npm
                return cordova.platform('add', 'cordova-platform-test');
            })
            .then(() => {
                expect(path.join(platformsDir, 'android')).toExist();
                expect(path.join(platformsDir, 'cordova-platform-test')).toExist();
                expect(installedPlatforms()).toEqual(jasmine.arrayWithExactContents([
                    'android', 'cordova-platform-test'
                ]));
            });
    });
});


================================================
FILE: integration-tests/plugin.spec.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

const fs = require('node:fs');
const path = require('node:path');
const helpers = require('../spec/helpers');
const events = require('cordova-common').events;
const cordova = require('../src/cordova/cordova');
const platforms = require('../src/platforms/platforms');
const plugman = require('../src/plugman/plugman');
const install = require('../src/plugman/install');
const plugin_util = require('../src/cordova/plugin/util');
const HooksRunner = require('../src/hooks/HooksRunner');

const util = require('../src/cordova/util');

const tmpDir = helpers.tmpDir('plugin_test');
const preparedProject = path.join(tmpDir, 'prepared-project');
const fixturesDir = path.join(__dirname, '..', 'spec', 'cordova', 'fixtures');
const pluginsDir = path.join(fixturesDir, 'plugins');

const pluginId = 'org.apache.cordova.fakeplugin1';
const org_test_defaultvariables = 'org.test.defaultvariables';

// This plugin is published to npm and defines cordovaDependencies
// in its package.json. Based on the dependencies and the version of
// cordova-android installed in our test project, the CLI should
// select version 1.1.2 of the plugin. We don't actually fetch from
// npm, but we do check the npm info.
const npmInfoTestPlugin = 'cordova-lib-test-plugin';
const npmInfoTestPluginVersion = '1.1.2';

const scopedTestPlugin = '@cordova/plugin-test-dummy';

const testGitPluginRepository = 'https://github.com/apache/cordova-plugin-device.git';
const testGitPluginId = 'cordova-plugin-device';

let results;

// Runs: list, add, list
function addPlugin (project, target, id, options) {
    // Check there are no plugins yet.
    return cordova.plugin('list').then(function () {
        expect(results).toMatch(/No plugins added/gi);
    }).then(function () {
        // Add a fake plugin from fixtures.
        return cordova.plugin('add', target, options);
    }).then(function () {
        expect(path.join(project, 'plugins', id, 'plugin.xml')).toExist();
    }).then(function () {
        return cordova.plugin('ls');
    }).then(function () {
        expect(results).toContain(id);
    });
}

// Runs: remove, list
function removePlugin (project, id) {
    return cordova.plugin('rm', id)
        .then(function () {
            // The whole dir should be gone.
            expect(path.join(project, 'plugins', id)).not.toExist();
        }).then(function () {
            return cordova.plugin('ls');
        }).then(function () {
            expect(results).toMatch(/No plugins added/gi);
        });
}

// We can't call add with a searchpath or else we will conflict with other tests
// that use a searchpath. See loadLocalPlugins() in plugman/fetch.js for details.
// The searchpath behavior gets tested in the plugman spec
function mockPluginFetch (project, id, dir) {
    spyOn(plugman, 'fetch').and.callFake(function (target, pluginPath, fetchOptions) {
        const dest = path.join(project, 'plugins', id);

        fs.cpSync(path.join(dir, 'plugin.xml'), path.join(dest, 'plugin.xml'));
        return Promise.resolve(dest);
    });
}

describe('plugin end-to-end', function () {
    let project;

    events.on('results', function (res) { results = res; });

    beforeAll(() => {
        return helpers.getFixture('projectWithPlatform').copyTo(preparedProject);
    }, 20000);

    beforeEach(function () {
        project = path.join(tmpDir, `project-${Date.now()}`);
        // Reset our test project and change into it
        fs.cpSync(preparedProject, project, { recursive: true });
        process.chdir(project);

        // Reset origCwd before each spec to respect chdirs
        util._resetOrigCwd();
        delete process.env.PWD;

        spyOn(platforms, 'getPlatformApi').and.callThrough();
        spyOn(install, 'runInstall').and.callThrough();
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        fs.rmSync(project, { recursive: true, force: true });
    });

    it('Test 001 : should successfully add and remove a plugin with no options', function () {
        return addPlugin(project, path.join(pluginsDir, 'fake1'), pluginId)
            .then(function () {
                expect(install.runInstall).toHaveBeenCalled();
                expect(platforms.getPlatformApi.calls.count()).toEqual(1);
                return removePlugin(project, pluginId);
            }).then(function () {
                expect(platforms.getPlatformApi.calls.count()).toEqual(2);
            });
    }, 30000);

    it('Test 004 : should successfully add a plugin using relative path when running from subdir inside of project', function () {
        // Copy plugin to subdir inside of the project. This is required since path.relative
        // returns an absolute path when source and dest are on different drives
        const plugindir = path.join(project, 'custom-plugins/some-plugin-inside-subfolder');
        fs.cpSync(path.join(pluginsDir, 'fake1'), plugindir, { recursive: true });

        // Create a subdir, where we're going to run cordova from
        const subdir = path.join(project, 'bin');
        fs.mkdirSync(subdir, { recursive: true });
        process.chdir(subdir);

        // Add plugin using relative path
        return addPlugin(project, path.relative(subdir, plugindir), pluginId)
            .then(function () {
                return removePlugin(project, pluginId);
            });
    }, 30000);

    it('Test 005 : should respect preference default values', function () {
        const plugin_util = require('../src/cordova/plugin/util');
        spyOn(plugin_util, 'mergeVariables').and.returnValue({ REQUIRED: 'NO', REQUIRED_ANDROID: 'NO' });
        return addPlugin(project, path.join(pluginsDir, org_test_defaultvariables), org_test_defaultvariables, { cli_variables: { REQUIRED: 'NO', REQUIRED_ANDROID: 'NO' } })
            .then(function () {
                const platformJsonPath = path.join(project, 'plugins', helpers.testPlatform + '.json');
                const installed_plugins = require(platformJsonPath).installed_plugins;
                const defaultPluginPreferences = installed_plugins[org_test_defaultvariables];
                expect(defaultPluginPreferences).toBeDefined();
                expect(defaultPluginPreferences.DEFAULT).toBe('yes');
                expect(defaultPluginPreferences.DEFAULT_ANDROID).toBe('yes');
                expect(defaultPluginPreferences.REQUIRED_ANDROID).toBe('NO');
                expect(defaultPluginPreferences.REQUIRED).toBe('NO');
                return removePlugin(project, org_test_defaultvariables);
            });
    }, 30000);

    it('Test 006 : should successfully add a plugin when specifying CLI variables', function () {
        return addPlugin(project, path.join(pluginsDir, org_test_defaultvariables), org_test_defaultvariables, { cli_variables: { REQUIRED: 'yes', REQUIRED_ANDROID: 'yes' } });
    }, 30000);

    it('Test 007 : should not check npm info when using the searchpath flag', function () {
        mockPluginFetch(project, npmInfoTestPlugin, path.join(pluginsDir, npmInfoTestPlugin));
        spyOn(plugin_util, 'info');
        return addPlugin(project, npmInfoTestPlugin, npmInfoTestPlugin, { searchpath: pluginsDir })
            .then(function () {
                expect(plugin_util.info).not.toHaveBeenCalled();
                const fetchOptions = plugman.fetch.calls.mostRecent().args[2];
                expect(fetchOptions.searchpath[0]).toExist();
            });
    }, 30000);

    it('Test 008 : should not check npm info when using the noregistry flag', function () {
        mockPluginFetch(project, npmInfoTestPlugin, path.join(pluginsDir, npmInfoTestPlugin));

        spyOn(plugin_util, 'info');
        return addPlugin(project, npmInfoTestPlugin, npmInfoTestPlugin, { noregistry: true })
            .then(function () {
                expect(plugin_util.info).not.toHaveBeenCalled();

                const fetchOptions = plugman.fetch.calls.mostRecent().args[2];
                expect(fetchOptions.noregistry).toBeTruthy();
            });
    }, 30000);

    it('Test 009 : should not check npm info when fetching from a Git repository', function () {
        spyOn(plugin_util, 'info');
        return addPlugin(project, testGitPluginRepository, testGitPluginId)
            .then(function () {
                expect(plugin_util.info).not.toHaveBeenCalled();
            });
    }, 30000);

    it('Test 010 : should select the plugin version based on npm info when fetching from npm', function () {
        mockPluginFetch(project, npmInfoTestPlugin, path.join(pluginsDir, npmInfoTestPlugin));

        spyOn(plugin_util, 'info').and.callThrough();

        // Pretend to have cordova-android 5.2.2 installed to force the
        // expected version outcome for the plugin below
        const targetVersion = '5.2.2';
        const apiFile = path.join(project, 'node_modules/cordova-android/lib/Api.js');
        const apiString = fs.readFileSync(apiFile, 'utf8')
            .replace('const VERSION = require(\'../package\').version;', `const VERSION = '${targetVersion}';`);
        fs.writeFileSync(apiFile, apiString, 'utf8');

        return addPlugin(project, npmInfoTestPlugin, npmInfoTestPlugin)
            .then(function () {
                expect(plugin_util.info).toHaveBeenCalled();

                const fetchTarget = plugman.fetch.calls.mostRecent().args[0];
                expect(fetchTarget).toEqual(npmInfoTestPlugin + '@' + npmInfoTestPluginVersion);
            });
    }, 30000);

    it('Test 011 : should handle scoped npm packages', function () {
        mockPluginFetch(project, scopedTestPlugin, path.join(pluginsDir, scopedTestPlugin));

        spyOn(plugin_util, 'info').and.returnValue(Promise.resolve({}));
        return addPlugin(project, scopedTestPlugin, scopedTestPlugin, {})
            .then(function () {
                // Check to make sure that we are at least trying to get the correct package.
                // This package is not published to npm, so we can't truly do end-to-end tests

                expect(plugin_util.info).toHaveBeenCalledWith([scopedTestPlugin]);

                const fetchTarget = plugman.fetch.calls.mostRecent().args[0];
                expect(fetchTarget).toEqual(scopedTestPlugin);
            });
    }, 30000);

    it('Test 012 : should handle scoped npm packages with given version tags', function () {
        const scopedPackage = scopedTestPlugin + '@latest';
        mockPluginFetch(project, scopedTestPlugin, path.join(pluginsDir, scopedTestPlugin));

        spyOn(plugin_util, 'info');
        return addPlugin(project, scopedPackage, scopedTestPlugin, {})
            .then(function () {
                expect(plugin_util.info).not.toHaveBeenCalled();

                const fetchTarget = plugman.fetch.calls.mostRecent().args[0];
                expect(fetchTarget).toEqual(scopedPackage);
            });
    }, 30000);

    it('Test 013 : should be able to add and remove scoped npm packages without screwing up everything', () => {
        mockPluginFetch(project, scopedTestPlugin, path.join(pluginsDir, scopedTestPlugin));
        spyOn(plugin_util, 'info').and.returnValue(Promise.resolve({}));

        return addPlugin(project, scopedTestPlugin, scopedTestPlugin, {})
            .then(() => {
                expect(plugin_util.info).toHaveBeenCalledWith([scopedTestPlugin]);

                const fetchTarget = plugman.fetch.calls.mostRecent().args[0];
                expect(fetchTarget).toEqual(scopedTestPlugin);

                return removePlugin(project, scopedTestPlugin);
            });
    }, 30000);

    it('Test 014 : should run plugin (un)install hooks with correct opts', async () => {
        const testPluginInstalledPath = path.join(project, 'plugins', npmInfoTestPlugin);
        const expectedOpts = jasmine.objectContaining({
            cordova: {
                platforms: [helpers.testPlatform],
                plugins: [npmInfoTestPlugin],
                version: require('../package').version
            },
            plugin: {
                id: npmInfoTestPlugin,
                platform: helpers.testPlatform,
                dir: testPluginInstalledPath,
                pluginInfo: jasmine.objectContaining({
                    id: npmInfoTestPlugin,
                    dir: testPluginInstalledPath
                })
            },
            projectRoot: project
        });

        mockPluginFetch(project, npmInfoTestPlugin, path.join(pluginsDir, npmInfoTestPlugin));
        spyOn(HooksRunner.prototype, 'fire').and.callThrough();

        await cordova.plugin('add', npmInfoTestPlugin);
        await cordova.plugin('rm', npmInfoTestPlugin);

        HooksRunner.prototype.fire.calls.allArgs()
            .filter(([hook]) => /_plugin_(un)?install$/.test(hook))
            .forEach(([hook, opts]) => {
                expect(opts)
                    .withContext(`${hook} hook options`)
                    .toEqual(expectedOpts);
            });
    }, 20 * 1000);
});


================================================
FILE: integration-tests/plugman_fetch.spec.js
================================================
/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache Licen
Download .txt
gitextract_tgy_emxc/

├── .asf.yaml
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG_REPORT.md
│   │   ├── FEATURE_REQUEST.md
│   │   └── SUPPORT_QUESTION.md
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── ci.yml
│       └── release-audit.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .ratignore
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASENOTES.md
├── cordova-lib.js
├── eslint.config.js
├── integration-tests/
│   ├── HooksRunner.spec.js
│   ├── fetch.spec.js
│   ├── pkgJson.spec.js
│   ├── platform.spec.js
│   ├── plugin.spec.js
│   ├── plugman_fetch.spec.js
│   └── plugman_uninstall.spec.js
├── licence_checker.yml
├── package.json
├── spec/
│   ├── common.js
│   ├── cordova/
│   │   ├── build.spec.js
│   │   ├── compile.spec.js
│   │   ├── cordova-lib.spec.js
│   │   ├── emulate.spec.js
│   │   ├── fixtures/
│   │   │   ├── basePkgJson/
│   │   │   │   ├── config.xml
│   │   │   │   ├── package.json
│   │   │   │   ├── plugins/
│   │   │   │   │   └── .svn
│   │   │   │   └── www/
│   │   │   │       ├── css/
│   │   │   │       │   └── index.css
│   │   │   │       ├── index.html
│   │   │   │       ├── js/
│   │   │   │       │   └── index.js
│   │   │   │       └── spec.html
│   │   │   ├── plugins/
│   │   │   │   ├── @cordova/
│   │   │   │   │   └── plugin-test-dummy/
│   │   │   │   │       ├── package.json
│   │   │   │   │       └── plugin.xml
│   │   │   │   ├── com.plugin.withhooks/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   └── scripts/
│   │   │   │   │       ├── android/
│   │   │   │   │       │   └── androidBeforeBuild.js
│   │   │   │   │       ├── beforeBuild.bat
│   │   │   │   │       ├── beforeBuild.js
│   │   │   │   │       ├── beforeBuild.sh
│   │   │   │   │       └── windows/
│   │   │   │   │           └── windowsBeforeBuild.js
│   │   │   │   ├── cordova-lib-test-plugin/
│   │   │   │   │   ├── LICENSE
│   │   │   │   │   ├── NOTICE
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   ├── fake1/
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   ├── org.test.defaultvariables/
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── plugin.xml
│   │   │   │   └── test/
│   │   │   │       ├── package.json
│   │   │   │       ├── plugin.xml
│   │   │   │       └── www/
│   │   │   │           └── test.js
│   │   │   ├── projectHooks/
│   │   │   │   ├── android/
│   │   │   │   │   ├── appAndroidBeforeBuild.bat
│   │   │   │   │   ├── appAndroidBeforeBuild.js
│   │   │   │   │   └── appAndroidBeforeBuild.sh
│   │   │   │   ├── appBeforeBuild02.js
│   │   │   │   ├── appBeforeBuild1.bat
│   │   │   │   ├── appBeforeBuild1.sh
│   │   │   │   ├── fail.js
│   │   │   │   ├── orderLogger.js
│   │   │   │   └── windows/
│   │   │   │       ├── appWindowsBeforeBuild.bat
│   │   │   │       ├── appWindowsBeforeBuild.js
│   │   │   │       └── appWindowsBeforeBuild.sh
│   │   │   └── projects/
│   │   │       ├── ProjectMetadata/
│   │   │       │   └── config.xml
│   │   │       └── platformApi/
│   │   │           └── platforms/
│   │   │               └── windows/
│   │   │                   └── cordova/
│   │   │                       └── Api.js
│   │   ├── platform/
│   │   │   ├── addHelper.spec.js
│   │   │   ├── getPlatformDetailsFromDir.spec.js
│   │   │   ├── index.spec.js
│   │   │   ├── list.spec.js
│   │   │   ├── listDeprecated.spec.js
│   │   │   └── remove.spec.js
│   │   ├── platforms/
│   │   │   └── platforms.spec.js
│   │   ├── plugin/
│   │   │   ├── add.getFetchVersion.spec.js
│   │   │   ├── add.spec.js
│   │   │   ├── index.spec.js
│   │   │   ├── list.spec.js
│   │   │   ├── plugin_spec_parser.spec.js
│   │   │   ├── remove.spec.js
│   │   │   └── util.spec.js
│   │   ├── prepare/
│   │   │   └── platforms.spec.js
│   │   ├── prepare.spec.js
│   │   ├── project-metadata-apis.spec.js
│   │   ├── requirements.spec.js
│   │   ├── restore-util.spec.js
│   │   ├── run.spec.js
│   │   └── util.spec.js
│   ├── fixture-helper.js
│   ├── helper.js
│   ├── helpers.js
│   ├── hooks/
│   │   └── Context.spec.js
│   ├── plugman/
│   │   ├── install.spec.js
│   │   ├── plugins/
│   │   │   ├── com.adobe.vars/
│   │   │   │   └── plugin.xml
│   │   │   ├── com.cordova.engine/
│   │   │   │   ├── megaBoringVersion
│   │   │   │   ├── megaFunVersion
│   │   │   │   └── plugin.xml
│   │   │   ├── com.cordova.engine-android/
│   │   │   │   └── plugin.xml
│   │   │   ├── dependencies/
│   │   │   │   ├── A/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── A.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── APluginCommand.h
│   │   │   │   │   │       └── APluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-a.js
│   │   │   │   ├── B/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── B.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── BPluginCommand.h
│   │   │   │   │   │       └── BPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-b.js
│   │   │   │   ├── C/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── C.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── CPluginCommand.h
│   │   │   │   │   │       └── CPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-c.js
│   │   │   │   ├── C@1.0.0/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── C.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── CPluginCommand.h
│   │   │   │   │   │       └── CPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-c.js
│   │   │   │   ├── D/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── D.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── DPluginCommand.h
│   │   │   │   │   │       └── DPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-d.js
│   │   │   │   ├── E/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── E.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── EPluginCommand.h
│   │   │   │   │   │       └── EPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-d.js
│   │   │   │   ├── F/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── F.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── FPluginCommand.h
│   │   │   │   │   │       └── FPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-f.js
│   │   │   │   ├── G/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── G.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── EPluginCommand.m
│   │   │   │   │   │       └── GPluginCommand.h
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-g.js
│   │   │   │   ├── H/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── H.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── HPluginCommand.h
│   │   │   │   │   │       └── HPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-h.js
│   │   │   │   ├── I/
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   └── I.java
│   │   │   │   │   │   └── ios/
│   │   │   │   │   │       ├── IPluginCommand.h
│   │   │   │   │   │       └── IPluginCommand.m
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-i.js
│   │   │   │   ├── README.md
│   │   │   │   ├── Test1/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test1.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test2/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test2.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test3/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test3.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── Test4/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── plugin.xml
│   │   │   │   │   ├── src/
│   │   │   │   │   │   └── android/
│   │   │   │   │   │       └── Test4.java
│   │   │   │   │   └── www/
│   │   │   │   │       └── plugin-test.js
│   │   │   │   ├── meta/
│   │   │   │   │   ├── D/
│   │   │   │   │   │   ├── plugin.xml
│   │   │   │   │   │   ├── src/
│   │   │   │   │   │   │   ├── android/
│   │   │   │   │   │   │   │   └── D.java
│   │   │   │   │   │   │   └── ios/
│   │   │   │   │   │   │       ├── DPluginCommand.h
│   │   │   │   │   │   │       └── DPluginCommand.m
│   │   │   │   │   │   └── www/
│   │   │   │   │   │       └── plugin-d.js
│   │   │   │   │   └── subdir/
│   │   │   │   │       └── E/
│   │   │   │   │           ├── plugin.xml
│   │   │   │   │           ├── src/
│   │   │   │   │           │   ├── android/
│   │   │   │   │           │   │   └── E.java
│   │   │   │   │           │   └── ios/
│   │   │   │   │           │       ├── EPluginCommand.h
│   │   │   │   │           │       └── EPluginCommand.m
│   │   │   │   │           └── www/
│   │   │   │   │               └── plugin-e.js
│   │   │   │   └── subdir/
│   │   │   │       └── E/
│   │   │   │           ├── plugin.xml
│   │   │   │           ├── src/
│   │   │   │           │   ├── android/
│   │   │   │           │   │   └── E.java
│   │   │   │           │   └── ios/
│   │   │   │           │       ├── EPluginCommand.h
│   │   │   │           │       └── EPluginCommand.m
│   │   │   │           └── www/
│   │   │   │               └── plugin-e.js
│   │   │   ├── org.test.androidonly/
│   │   │   │   ├── plugin.xml
│   │   │   │   └── www/
│   │   │   │       └── android.js
│   │   │   ├── org.test.defaultvariables/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.no.platform/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.no.scriptSrc/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.invalid.engine.script/
│   │   │   │   └── plugin.xml
│   │   │   ├── org.test.plugins.childbrowser/
│   │   │   │   ├── package.json
│   │   │   │   ├── plugin.xml
│   │   │   │   ├── src/
│   │   │   │   │   ├── android/
│   │   │   │   │   │   └── ChildBrowser.java
│   │   │   │   │   └── ios/
│   │   │   │   │       ├── ChildBrowserCommand.h
│   │   │   │   │       ├── ChildBrowserCommand.m
│   │   │   │   │       ├── ChildBrowserViewController.h
│   │   │   │   │       ├── ChildBrowserViewController.m
│   │   │   │   │       ├── ChildBrowserViewController.xib
│   │   │   │   │       ├── TargetDirTest.h
│   │   │   │   │       ├── TargetDirTest.m
│   │   │   │   │       └── preserveDirs/
│   │   │   │   │           ├── PreserveDirsTest.h
│   │   │   │   │           └── PreserveDirsTest.m
│   │   │   │   └── www/
│   │   │   │       ├── childbrowser.js
│   │   │   │       └── childbrowser_file.html
│   │   │   ├── org.test.plugins.dummyplugin/
│   │   │   │   ├── android-resource.xml
│   │   │   │   ├── extra.gradle
│   │   │   │   ├── plugin-lib/
│   │   │   │   │   ├── AndroidManifest.xml
│   │   │   │   │   ├── libFile
│   │   │   │   │   └── project.properties
│   │   │   │   ├── plugin-lib2/
│   │   │   │   │   ├── AndroidManifest.xml
│   │   │   │   │   ├── libFile
│   │   │   │   │   └── project.properties
│   │   │   │   ├── plugin.xml
│   │   │   │   ├── src/
│   │   │   │   │   ├── android/
│   │   │   │   │   │   └── DummyPlugin.java
│   │   │   │   │   └── ios/
│   │   │   │   │       ├── Custom.framework/
│   │   │   │   │       │   ├── someFheader.h
│   │   │   │   │       │   └── somebinlib
│   │   │   │   │       ├── DummyPlugin.bundle
│   │   │   │   │       ├── DummyPluginCommand.h
│   │   │   │   │       ├── DummyPluginCommand.m
│   │   │   │   │       ├── SourceWithFramework.m
│   │   │   │   │       ├── TargetDirTest.h
│   │   │   │   │       └── TargetDirTest.m
│   │   │   │   └── www/
│   │   │   │       └── dummyplugin.js
│   │   │   ├── pkgjson-test-plugin/
│   │   │   │   ├── package.json
│   │   │   │   └── plugin.xml
│   │   │   └── recursivePlug/
│   │   │       ├── asset.txt
│   │   │       ├── demo/
│   │   │       │   └── config.xml
│   │   │       ├── package.json
│   │   │       └── plugin.xml
│   │   ├── util/
│   │   │   ├── dependencies.spec.js
│   │   │   └── metadata.spec.js
│   │   └── variable-merge.spec.js
│   ├── project-test-helpers.js
│   └── support/
│       └── jasmine.json
└── src/
    ├── cordova/
    │   ├── build.js
    │   ├── clean.js
    │   ├── compile.js
    │   ├── cordova.js
    │   ├── emulate.js
    │   ├── platform/
    │   │   ├── addHelper.js
    │   │   ├── getPlatformDetailsFromDir.js
    │   │   ├── index.js
    │   │   ├── list.js
    │   │   └── remove.js
    │   ├── plugin/
    │   │   ├── add.js
    │   │   ├── index.js
    │   │   ├── list.js
    │   │   ├── plugin_spec_parser.js
    │   │   ├── remove.js
    │   │   └── util.js
    │   ├── prepare/
    │   │   └── platforms.js
    │   ├── prepare.js
    │   ├── project_metadata.js
    │   ├── requirements.js
    │   ├── restore-util.js
    │   ├── run.js
    │   ├── targets.js
    │   └── util.js
    ├── hooks/
    │   ├── Context.js
    │   ├── HooksRunner.js
    │   └── scriptsFinder.js
    ├── platforms/
    │   ├── index.js
    │   ├── platforms.js
    │   └── platformsConfig.json
    ├── plugman/
    │   ├── fetch.js
    │   ├── install.js
    │   ├── plugman.js
    │   ├── uninstall.js
    │   ├── util/
    │   │   ├── default-engines.js
    │   │   ├── dep-graph.js
    │   │   ├── dependencies.js
    │   │   └── metadata.js
    │   └── variable-merge.js
    └── util/
        └── promise-util.js
Download .txt
SYMBOL INDEX (179 symbols across 52 files)

FILE: cordova-lib.js
  method binname (line 23) | set binname (name) {
  method binname (line 26) | get binname () {

FILE: integration-tests/HooksRunner.spec.js
  function getActualHooksOrder (line 78) | function getActualHooksOrder () {
  function checkHooksOrderFile (line 83) | function checkHooksOrderFile () {
  function addHooks (line 91) | function addHooks (hooksXml, doc) {
  function addHooksToConfig (line 122) | function addHooksToConfig (hooksXml) {
  function addHooksToPlugin (line 208) | function addHooksToPlugin (hooksXml) {

FILE: integration-tests/fetch.spec.js
  constant TIMEOUT (line 25) | const TIMEOUT = 60 * 1000;

FILE: integration-tests/pkgJson.spec.js
  function copyFixture (line 51) | function copyFixture (fixtureRelativePath) {
  function installedPlatforms (line 58) | function installedPlatforms () {
  function platformVersion (line 63) | function platformVersion (platformName) {
  function pluginVersion (line 69) | function pluginVersion (pluginName) {
  function specSatisfiedBy (line 75) | function specSatisfiedBy (version) {
  function specWithMinSatisfyingVersion (line 82) | function specWithMinSatisfyingVersion (version) {
  method compare (line 93) | compare (version, spec) {
  method compare (line 102) | compare (spec, version) {

FILE: integration-tests/platform.spec.js
  function installedPlatforms (line 53) | function installedPlatforms () {

FILE: integration-tests/plugin.spec.js
  function addPlugin (line 57) | function addPlugin (project, target, id, options) {
  function removePlugin (line 74) | function removePlugin (project, id) {
  function mockPluginFetch (line 89) | function mockPluginFetch (project, id, dir) {

FILE: integration-tests/plugman_uninstall.spec.js
  function setupProject (line 42) | function setupProject (name) {
  function validateReturnedResultFor (line 125) | function validateReturnedResultFor (values, expectedResult) {

FILE: spec/common.js
  method getReceivedMessages (line 37) | getReceivedMessages (emitSpy) {

FILE: spec/cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js
  constant PLATFORM (line 22) | const PLATFORM = 'windows';
  function Api (line 24) | function Api (platform, rootDir) {

FILE: spec/cordova/platform/addHelper.spec.js
  function installPluginsForNewPlatformWithTestArgs (line 298) | function installPluginsForNewPlatformWithTestArgs () {

FILE: spec/cordova/platforms/platforms.spec.js
  constant CORDOVA_ROOT (line 29) | const CORDOVA_ROOT = path.join(__dirname, '../fixtures/projects/platform...
  constant PLATFORM_WITH_API (line 30) | const PLATFORM_WITH_API = path.join(CORDOVA_ROOT, 'platforms/windows');
  constant PLATFORM_SYMLINK (line 31) | const PLATFORM_SYMLINK = path.join(os.tmpdir(), 'cordova_windows_symlink');

FILE: spec/cordova/plugin/add.getFetchVersion.spec.js
  constant UNMET_REQ_REGEX (line 29) | const UNMET_REQ_REGEX = /\s+([^\s]+)[^\d]+(\d+\.\d+\.\d+) in project, (....
  function unmetRequirementsCollector (line 31) | function unmetRequirementsCollector (warning) {
  function expectUnmetRequirements (line 45) | function expectUnmetRequirements (expected) {
  function getPlatformRequirement (line 52) | function getPlatformRequirement (requirement) {
  function getCordovaRequirement (line 60) | function getCordovaRequirement (requirement) {
  function getPluginRequirement (line 68) | function getPluginRequirement (requirement) {
  function getFetchVersion (line 118) | function getFetchVersion (plugin) {

FILE: spec/cordova/plugin/plugin_spec_parser.spec.js
  function checkPluginSpecParsing (line 23) | function checkPluginSpecParsing (testString, id, version) {

FILE: spec/cordova/prepare/platforms.spec.js
  method add_config_changes (line 34) | add_config_changes () {}

FILE: spec/cordova/project-metadata-apis.spec.js
  function findPlatform (line 101) | function findPlatform (platforms, platformName) {
  function findPlugin (line 110) | function findPlugin (plugins, pluginId) {

FILE: spec/cordova/restore-util.spec.js
  function getCfgEngineNames (line 59) | function getCfgEngineNames (cfg = getCfg()) {
  function platformPkgName (line 63) | function platformPkgName (platformName) {
  function expectPluginsInPkgJson (line 67) | function expectPluginsInPkgJson (plugins) {
  function expectPlatformAdded (line 92) | function expectPlatformAdded (platform) {
  function expectPluginAdded (line 106) | function expectPluginAdded (plugin) {
  function expectPluginsAddedAndSavedToPkgJson (line 121) | function expectPluginsAddedAndSavedToPkgJson (plugins) {

FILE: spec/cordova/util.spec.js
  function expectFindPluginsToReturn (line 130) | function expectFindPluginsToReturn (expectedPlugins) {

FILE: spec/fixture-helper.js
  method androidApp (line 44) | androidApp () {
  method projectWithPlatform (line 61) | async projectWithPlatform () {
  method androidPlatform (line 77) | androidPlatform () {
  method copyTo (line 93) | async copyTo (targetPath) {
  function linkToGlobalModulesFrom (line 102) | function linkToGlobalModulesFrom (dir) {

FILE: spec/helpers.js
  function getConfigPath (line 29) | function getConfigPath (dir) {
  method pathNormalizingTo (line 169) | pathNormalizingTo (expectedPath) {
  method compare (line 179) | compare (file) {

FILE: spec/plugman/install.spec.js
  function pluginDir (line 35) | function pluginDir (pluginId) {
  constant TIMEOUT (line 43) | const TIMEOUT = 9000;
  method noPlugins (line 50) | noPlugins (path) {
  method dependencies (line 60) | dependencies (id, dir) {
  class PlatformApiMock (line 229) | class PlatformApiMock {
    method addPlugin (line 230) | static addPlugin () { return Promise.resolve(); }

FILE: spec/plugman/util/metadata.spec.js
  method writeFileSync (line 30) | writeFileSync (_, data) { fetchJson = data; }
  method unlinkSync (line 31) | unlinkSync () { fetchJson = null; }

FILE: spec/project-test-helpers.js
  class TestConfigParser (line 28) | class TestConfigParser extends ConfigParser {
    method addPlugin (line 29) | addPlugin (plugin) {
    method addEngine (line 33) | addEngine (...args) {
  function setupBaseProject (line 42) | function setupBaseProject () {
  function getCfg (line 54) | function getCfg () {
  function getPkgJson (line 60) | function getPkgJson (propPath) {
  function setPkgJson (line 71) | function setPkgJson (propPath, value) {

FILE: src/cordova/cordova.js
  method binname (line 32) | get binname () { return cordova_util.binname; }
  method binname (line 33) | set binname (name) { cordova_util.binname = name; }

FILE: src/cordova/platform/addHelper.js
  function addHelper (line 40) | function addHelper (cmd, hooksRunner, projectRoot, targets, opts) {
  function readPackageJsonIfExists (line 240) | function readPackageJsonIfExists (packageDir) {
  function getVersionFromPackageJson (line 247) | function getVersionFromPackageJson (platform, { dependencies, devDepende...
  function getVersionFromConfigFile (line 252) | function getVersionFromConfigFile (platform, cfg) {
  function downloadPlatform (line 263) | function downloadPlatform (projectRoot, platform, version, opts) {
  function installPluginsForNewPlatform (line 288) | function installPluginsForNewPlatform (platform, projectRoot, opts) {

FILE: src/cordova/platform/getPlatformDetailsFromDir.js
  function getPlatformDetailsFromDir (line 28) | function getPlatformDetailsFromDir (dir, platformIfKnown) {
  function platformFromName (line 62) | function platformFromName (name) {

FILE: src/cordova/platform/index.js
  function platform (line 48) | function platform (command, targets, opts) {

FILE: src/cordova/platform/list.js
  function list (line 25) | function list (hooksRunner, projectRoot, opts) {
  function addDeprecatedInformationToPlatforms (line 49) | function addDeprecatedInformationToPlatforms (platformsList) {

FILE: src/cordova/platform/remove.js
  function remove (line 33) | function remove (hooksRunner, projectRoot, targets, opts) {

FILE: src/cordova/plugin/add.js
  function add (line 49) | function add (projectRoot, hooksRunner, opts) {
  function determinePluginTarget (line 198) | function determinePluginTarget (projectRoot, cfg, target, fetchOptions) {
  function parseSource (line 290) | function parseSource (target, opts) {
  function getVersionFromConfigFile (line 304) | function getVersionFromConfigFile (plugin, cfg) {
  function getFetchVersion (line 332) | function getFetchVersion (projectRoot, pluginInfo, cordovaVersion) {
  constant UPPER_BOUND_REGEX (line 357) | const UPPER_BOUND_REGEX = /^<\d+\.\d+\.\d+$/;
  function determinePluginVersionToFetch (line 374) | function determinePluginVersionToFetch (pluginInfo, pluginMap, platformM...
  function getFailedRequirements (line 500) | function getFailedRequirements (reqs, pluginMap, platformMap, cordovaVer...
  function findVersion (line 543) | function findVersion (versions, version) {
  function listUnmetRequirements (line 554) | function listUnmetRequirements (name, failedRequirements) {

FILE: src/cordova/plugin/index.js
  function plugin (line 29) | function plugin (command, targets, opts) {

FILE: src/cordova/plugin/list.js
  function list (line 27) | function list (projectRoot, hooksRunner, opts) {

FILE: src/cordova/plugin/plugin_spec_parser.js
  constant NPM_SPEC_REGEX (line 21) | const NPM_SPEC_REGEX = /^(@[^/]+\/)?([^@/]+)(?:@(.+))?$/;
  function PluginSpec (line 32) | function PluginSpec (raw, id, version) {
  function parse (line 50) | function parse (raw) {

FILE: src/cordova/plugin/remove.js
  function remove (line 39) | function remove (projectRoot, targets, hooksRunner, opts) {
  function validatePluginId (line 156) | function validatePluginId (pluginId, installedPlugins) {

FILE: src/cordova/plugin/util.js
  function getInstalledPlugins (line 32) | function getInstalledPlugins (projectRoot) {
  function mergeVariables (line 49) | function mergeVariables (pluginInfo, cfg, opts) {
  function info (line 75) | function info (plugin) {

FILE: src/cordova/prepare.js
  function prepare (line 29) | function prepare (options) {

FILE: src/cordova/prepare/platforms.js
  function preparePlatforms (line 37) | function preparePlatforms (platformList, projectRoot, options) {

FILE: src/cordova/project_metadata.js
  function getPlatforms (line 28) | function getPlatforms (projectRoot) {
  function getPlugins (line 54) | function getPlugins (projectRoot) {

FILE: src/cordova/requirements.js
  function getPlatformRequirementsOrError (line 47) | function getPlatformRequirementsOrError (platform) {

FILE: src/cordova/restore-util.js
  function installPlatformsFromConfigXML (line 35) | function installPlatformsFromConfigXML (platforms, opts) {
  function installPluginsFromConfigXML (line 158) | function installPluginsFromConfigXML (args) {

FILE: src/cordova/targets.js
  function handleError (line 25) | function handleError (error) {
  function displayDevices (line 34) | function displayDevices (projectRoot, platform, options) {
  function displayVirtualDevices (line 41) | function displayVirtualDevices (projectRoot, platform, options) {

FILE: src/cordova/util.js
  function removePlatformPluginsJson (line 51) | function removePlatformPluginsJson (projectRoot, target) {
  function requireNoCache (line 56) | function requireNoCache (pkgJsonPath) {
  function isUrl (line 63) | function isUrl (value) {
  function isRootDir (line 72) | function isRootDir (dir) {
  function isCordova (line 93) | function isCordova (dir) {
  function getProjectRoot (line 128) | function getProjectRoot () {
  function cdProjectRoot (line 139) | function cdProjectRoot () {
  function getOrigWorkingDirectory (line 149) | function getOrigWorkingDirectory () {
  function _resetOrigCwd (line 153) | function _resetOrigCwd () {
  function fixRelativePath (line 158) | function fixRelativePath (value, /* optional */ cwd) {
  function convertToRealPathSafe (line 171) | function convertToRealPathSafe (path) {
  function listPlatforms (line 179) | function listPlatforms (project_dir) {
  function getInstalledPlatformsWithVersions (line 192) | function getInstalledPlatformsWithVersions (project_dir) {
  function getPlatformVersion (line 204) | function getPlatformVersion (platformPath) {
  function getPlatformVersionOrNull (line 219) | function getPlatformVersionOrNull (platformPath) {
  function findPlugins (line 228) | function findPlugins (pluginDir) {
  function projectWww (line 237) | function projectWww (projectDir) {
  function projectConfig (line 241) | function projectConfig (projectDir) {
  function preProcessOptions (line 252) | function preProcessOptions (inputOptions) {
  function isDirectory (line 296) | function isDirectory (dir) {
  function getPlatformApiFunction (line 306) | function getPlatformApiFunction (dir, platform) {

FILE: src/hooks/Context.js
  function Context (line 29) | function Context (hook, opts) {

FILE: src/hooks/HooksRunner.js
  function HooksRunner (line 33) | function HooksRunner (projectRoot) {
  function globalFire (line 88) | function globalFire (hook, opts) {
  function getEventHandlerJobs (line 97) | function getEventHandlerJobs (hook, opts) {
  function getHookJobs (line 102) | function getHookJobs (hook, opts) {
  function runJobsSerially (line 113) | function runJobsSerially (jobs) {
  function runScript (line 120) | function runScript (script, context) {
  function runScriptViaModuleLoader (line 144) | function runScriptViaModuleLoader (script, context) {
  function runScriptViaChildProcessSpawn (line 168) | function runScriptViaChildProcessSpawn (script, context) {
  function isHookDisabled (line 197) | function isHookDisabled (opts, hook) {

FILE: src/hooks/scriptsFinder.js
  function getApplicationHookScripts (line 47) | function getApplicationHookScripts (hook, opts) {
  function getPluginsHookScripts (line 66) | function getPluginsHookScripts (hook, opts) {
  function getPluginScriptFiles (line 86) | function getPluginScriptFiles (plugin, hook, platforms) {
  function getAllPluginsHookScriptFiles (line 101) | function getAllPluginsHookScriptFiles (hook, opts) {

FILE: src/platforms/index.js
  function getPlatformApi (line 31) | function getPlatformApi (platform, platformRootDir) {
  function hostSupports (line 64) | function hostSupports (platform) {

FILE: src/plugman/fetch.js
  function fetchPlugin (line 39) | function fetchPlugin (plugin_src, plugins_dir, options) {
  function checkID (line 177) | function checkID (expectedIdAndVersion, pinfo) {
  function loadLocalPlugins (line 194) | function loadLocalPlugins (searchpath, pluginInfoProvider) {
  function findLocalPlugin (line 228) | function findLocalPlugin (plugin_src, searchpath, pluginInfoProvider) {
  function copyPlugin (line 257) | function copyPlugin (pinfo, plugins_dir, link) {

FILE: src/plugman/install.js
  function possiblyFetch (line 83) | function possiblyFetch (id, plugins_dir, options) {
  function checkEngines (line 100) | function checkEngines (engines) {
  function cleanVersionOutput (line 116) | function cleanVersionOutput (version, name) {
  function callEngineScripts (line 152) | function callEngineScripts (engines, project_dir) {
  function getEngines (line 187) | function getEngines (pluginInfo, platform, project_dir, plugin_dir) {
  function runInstall (line 240) | function runInstall (actions, platform, project_dir, plugin_dir, plugins...
  function installDependencies (line 357) | function installDependencies (install, dependencies, options) {
  function tryFetchDependency (line 392) | function tryFetchDependency (dep, install, options) {
  function installDependency (line 476) | function installDependency (dep, install, options) {
  function handleInstall (line 546) | function handleInstall (actions, pluginInfo, platform, project_dir, plug...
  function interp_vars (line 573) | function interp_vars (vars, text) {
  function isAbsolutePath (line 581) | function isAbsolutePath (_path) {
  function copyPlugin (line 587) | function copyPlugin (plugin_src_dir, plugins_dir, link, pluginInfoProvid...

FILE: src/plugman/uninstall.js
  function uninstall (line 39) | function uninstall (platform, project_dir, id, plugins_dir, options) {
  function findDependencies (line 140) | function findDependencies (pluginId) {
  function runUninstallPlatform (line 231) | function runUninstallPlatform (actions, platform, project_dir, plugin_di...
  function handleUninstall (line 311) | function handleUninstall (actions, platform, pluginInfo, project_dir, ww...

FILE: src/plugman/util/dep-graph.js
  method constructor (line 21) | constructor () {
  method add (line 25) | add (id, dep) {
  method getChain (line 36) | getChain (id) {

FILE: src/plugman/util/metadata.js
  function getJson (line 25) | function getJson (pluginsDir) {

FILE: src/plugman/variable-merge.js
  function mergeVariables (line 34) | function mergeVariables (plugin_dir, platform, options) {

FILE: src/util/promise-util.js
  function Q_chainmap (line 24) | function Q_chainmap (args, func) {
Condensed preview — 278 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (805K chars).
[
  {
    "path": ".asf.yaml",
    "chars": 1328,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".gitattributes",
    "chars": 805,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/BUG_REPORT.md",
    "chars": 995,
    "preview": "---\nname: 🐛 Bug Report\nabout: If something isn't working as expected.\n\n---\n\n# Bug Report\n\n## Problem\n\n### What is expect"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md",
    "chars": 598,
    "preview": "---\nname: 🚀 Feature Request\nabout: A suggestion for a new functionality\n\n---\n\n# Feature Request\n\n## Motivation Behind Fe"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md",
    "chars": 959,
    "preview": "---\nname: 💬 Support Question\nabout: If you have a question, please check out our Slack or StackOverflow!\n\n---\n\n<!-------"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 1191,
    "preview": "<!--\nPlease have a look at the issue templates you get when you click \"New issue\" in the GitHub UI.\nWe very much prefer "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1118,
    "preview": "<!--\nPlease make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2200,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".github/workflows/release-audit.yml",
    "chars": 1627,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".gitignore",
    "chars": 1402,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".npmignore",
    "chars": 893,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".npmrc",
    "chars": 822,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": ".ratignore",
    "chars": 861,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1375,
    "preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the N"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "NOTICE",
    "chars": 163,
    "preview": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Sof"
  },
  {
    "path": "README.md",
    "chars": 2518,
    "preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the N"
  },
  {
    "path": "RELEASENOTES.md",
    "chars": 96566,
    "preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the N"
  },
  {
    "path": "cordova-lib.js",
    "chars": 1314,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "eslint.config.js",
    "chars": 1385,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/HooksRunner.spec.js",
    "chars": 13802,
    "preview": "/**\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE"
  },
  {
    "path": "integration-tests/fetch.spec.js",
    "chars": 6138,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/pkgJson.spec.js",
    "chars": 24374,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/platform.spec.js",
    "chars": 8666,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/plugin.spec.js",
    "chars": 13895,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/plugman_fetch.spec.js",
    "chars": 6666,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "integration-tests/plugman_uninstall.spec.js",
    "chars": 11943,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "licence_checker.yml",
    "chars": 830,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": "package.json",
    "chars": 1398,
    "preview": "{\n  \"author\": \"Apache Software Foundation\",\n  \"name\": \"cordova-lib\",\n  \"license\": \"Apache-2.0\",\n  \"description\": \"Apache"
  },
  {
    "path": "spec/common.js",
    "chars": 1428,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/build.spec.js",
    "chars": 4865,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/compile.spec.js",
    "chars": 4882,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/cordova-lib.spec.js",
    "chars": 1029,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/emulate.spec.js",
    "chars": 10451,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/config.xml",
    "chars": 593,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<widget id=\"org.testing\" version=\"0.0.1\" xmlns=\"http://www.w3.org/ns/widgets\" xml"
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/package.json",
    "chars": 204,
    "preview": "{\n  \"name\": \"testbase\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"ech"
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/plugins/.svn",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/www/css/index.css",
    "chars": 3719,
    "preview": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOT"
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/www/index.html",
    "chars": 1932,
    "preview": "<!DOCTYPE html>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agre"
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/www/js/index.js",
    "chars": 1914,
    "preview": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOT"
  },
  {
    "path": "spec/cordova/fixtures/basePkgJson/www/spec.html",
    "chars": 2532,
    "preview": "<!DOCTYPE html>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agre"
  },
  {
    "path": "spec/cordova/fixtures/plugins/@cordova/plugin-test-dummy/package.json",
    "chars": 134,
    "preview": "{\n  \"name\": \"@cordova/plugin-test-dummy\",\n  \"version\": \"0.0.1\",\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \""
  },
  {
    "path": "spec/cordova/fixtures/plugins/@cordova/plugin-test-dummy/plugin.xml",
    "chars": 159,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<plugin\n    xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    id=\"@cordova/plu"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/package.json",
    "chars": 205,
    "preview": "{\n  \"name\": \"withhooks\",\n  \"version\": \"3.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"ec"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/plugin.xml",
    "chars": 266,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n        xmlns:android=\"h"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/scripts/android/androidBeforeBuild.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/scripts/beforeBuild.bat",
    "chars": 36,
    "preview": "@echo off\necho 22 >> hooks_order.txt"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/scripts/beforeBuild.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/scripts/beforeBuild.sh",
    "chars": 37,
    "preview": "#!/bin/sh\necho 22 >> hooks_order.txt\n"
  },
  {
    "path": "spec/cordova/fixtures/plugins/com.plugin.withhooks/scripts/windows/windowsBeforeBuild.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/plugins/cordova-lib-test-plugin/LICENSE",
    "chars": 11357,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "spec/cordova/fixtures/plugins/cordova-lib-test-plugin/NOTICE",
    "chars": 163,
    "preview": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Sof"
  },
  {
    "path": "spec/cordova/fixtures/plugins/cordova-lib-test-plugin/package.json",
    "chars": 638,
    "preview": "{\n  \"name\": \"cordova-lib-test-plugin\",\n  \"version\": \"1.3.1\",\n  \"description\": \"Empty plugin used as part of the tests in"
  },
  {
    "path": "spec/cordova/fixtures/plugins/cordova-lib-test-plugin/plugin.xml",
    "chars": 252,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<plugin id=\"cordova-lib-test-plugin\" version=\"0.0.0\" xmlns=\"http://apache.org/cor"
  },
  {
    "path": "spec/cordova/fixtures/plugins/fake1/package.json",
    "chars": 602,
    "preview": "{\n  \"name\": \"fake1\",\n  \"version\": \"1.3.1\",\n  \"description\": \"Empty plugin used as part of the tests in cordova-lib\",\n  \""
  },
  {
    "path": "spec/cordova/fixtures/plugins/fake1/plugin.xml",
    "chars": 341,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n           id=\"org.apac"
  },
  {
    "path": "spec/cordova/fixtures/plugins/org.test.defaultvariables/package.json",
    "chars": 640,
    "preview": "{\n  \"name\": \"org.test.defaultvariables\",\n  \"version\": \"1.3.1\",\n  \"description\": \"Empty plugin used as part of the tests "
  },
  {
    "path": "spec/cordova/fixtures/plugins/org.test.defaultvariables/plugin.xml",
    "chars": 526,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<plugin xmlns=\"http://cordova.apache.org/ns/plugins/1.0\"\n    xmlns:android=\"http"
  },
  {
    "path": "spec/cordova/fixtures/plugins/test/package.json",
    "chars": 197,
    "preview": "{\n  \"name\": \"0\",\n  \"version\": \"3.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Err"
  },
  {
    "path": "spec/cordova/fixtures/plugins/test/plugin.xml",
    "chars": 411,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<plugin xmlns=\"http://www.phonegap.com/ns/plugins/1.0\"\n    xmlns:android=\"http://"
  },
  {
    "path": "spec/cordova/fixtures/plugins/test/www/test.js",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/android/appAndroidBeforeBuild.bat",
    "chars": 36,
    "preview": "@echo off\necho 14 >> hooks_order.txt"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/android/appAndroidBeforeBuild.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/android/appAndroidBeforeBuild.sh",
    "chars": 37,
    "preview": "#!/bin/sh\necho 14 >> hooks_order.txt\n"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/appBeforeBuild02.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/appBeforeBuild1.bat",
    "chars": 36,
    "preview": "@echo off\necho 08 >> hooks_order.txt"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/appBeforeBuild1.sh",
    "chars": 37,
    "preview": "#!/bin/sh\necho 08 >> hooks_order.txt\n"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/fail.js",
    "chars": 51,
    "preview": "module.exports = () => {\n    throw new Error();\n};\n"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/orderLogger.js",
    "chars": 386,
    "preview": "module.exports.logOrder = function logOrder(index, context) {\n    var indexWithEOL = index + require('node:os').EOL;\n   "
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/windows/appWindowsBeforeBuild.bat",
    "chars": 36,
    "preview": "@echo off\necho 11 >> hooks_order.txt"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/windows/appWindowsBeforeBuild.js",
    "chars": 191,
    "preview": "module.exports = function(context) {\n    var orderLogger = require(require('node:path').join(context.opts.projectRoot, '"
  },
  {
    "path": "spec/cordova/fixtures/projectHooks/windows/appWindowsBeforeBuild.sh",
    "chars": 26,
    "preview": "echo 11 >> hooks_order.txt"
  },
  {
    "path": "spec/cordova/fixtures/projects/ProjectMetadata/config.xml",
    "chars": 1664,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<widget id=\"io.cordova.projectmetadata\" version=\"0.0.1\" xmlns=\"http://www.w3.org/"
  },
  {
    "path": "spec/cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js",
    "chars": 1098,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/addHelper.spec.js",
    "chars": 22059,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/getPlatformDetailsFromDir.spec.js",
    "chars": 3092,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/index.spec.js",
    "chars": 6090,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/list.spec.js",
    "chars": 2536,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/listDeprecated.spec.js",
    "chars": 2656,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platform/remove.spec.js",
    "chars": 5652,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/platforms/platforms.spec.js",
    "chars": 5065,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/add.getFetchVersion.spec.js",
    "chars": 15615,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/add.spec.js",
    "chars": 28679,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/index.spec.js",
    "chars": 4417,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/list.spec.js",
    "chars": 4165,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/plugin_spec_parser.spec.js",
    "chars": 2794,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/remove.spec.js",
    "chars": 10312,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/plugin/util.spec.js",
    "chars": 4908,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/prepare/platforms.spec.js",
    "chars": 2787,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/prepare.spec.js",
    "chars": 6874,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/project-metadata-apis.spec.js",
    "chars": 5057,
    "preview": "/**\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE"
  },
  {
    "path": "spec/cordova/requirements.spec.js",
    "chars": 1505,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/restore-util.spec.js",
    "chars": 14583,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/run.spec.js",
    "chars": 10368,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/cordova/util.spec.js",
    "chars": 10739,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/fixture-helper.js",
    "chars": 4400,
    "preview": "/*!\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/helper.js",
    "chars": 1476,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/helpers.js",
    "chars": 5858,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/hooks/Context.spec.js",
    "chars": 4078,
    "preview": "/*!\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/plugman/install.spec.js",
    "chars": 18683,
    "preview": "/**\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the "
  },
  {
    "path": "spec/plugman/plugins/com.adobe.vars/plugin.xml",
    "chars": 1768,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/com.cordova.engine/megaBoringVersion",
    "chars": 39,
    "preview": "./com.cordova.engine/megaBoringVersion\n"
  },
  {
    "path": "spec/plugman/plugins/com.cordova.engine/megaFunVersion",
    "chars": 36,
    "preview": "./com.cordova.engine/megaFunVersion\n"
  },
  {
    "path": "spec/plugman/plugins/com.cordova.engine/plugin.xml",
    "chars": 1091,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may n"
  },
  {
    "path": "spec/plugman/plugins/com.cordova.engine-android/plugin.xml",
    "chars": 933,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/A/plugin.xml",
    "chars": 1972,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/A/src/android/A.java",
    "chars": 36,
    "preview": "./dependencies/A/src/android/A.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/A/src/ios/APluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/A/src/ios/APluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/A/src/ios/APluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/A/src/ios/APluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/A/www/plugin-a.js",
    "chars": 33,
    "preview": "//dependencies/A/www/plugin-a.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/B/plugin.xml",
    "chars": 1991,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/B/src/android/B.java",
    "chars": 36,
    "preview": "./dependencies/B/src/android/B.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/B/src/ios/BPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/B/src/ios/BPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/B/src/ios/BPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/B/src/ios/BPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/B/www/plugin-b.js",
    "chars": 33,
    "preview": "//dependencies/B/www/plugin-b.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C/plugin.xml",
    "chars": 1903,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C/src/android/C.java",
    "chars": 36,
    "preview": "./dependencies/C/src/android/C.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C/src/ios/CPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/C/src/ios/CPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C/src/ios/CPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/C/src/ios/CPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C/www/plugin-c.js",
    "chars": 33,
    "preview": "//dependencies/C/www/plugin-c.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/package.json",
    "chars": 197,
    "preview": "{\n  \"name\": \"c\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Err"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/plugin.xml",
    "chars": 1657,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/src/android/C.java",
    "chars": 42,
    "preview": "./dependencies/C@1.0.0/src/android/C.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/src/ios/CPluginCommand.h",
    "chars": 48,
    "preview": "./dependencies/C@1.0.0/src/ios/CPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/src/ios/CPluginCommand.m",
    "chars": 48,
    "preview": "./dependencies/C@1.0.0/src/ios/CPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/C@1.0.0/www/plugin-c.js",
    "chars": 35,
    "preview": "//dependencies/Cv1/www/plugin-c.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/D/plugin.xml",
    "chars": 1903,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/D/src/android/D.java",
    "chars": 36,
    "preview": "./dependencies/D/src/android/D.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/D/src/ios/DPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/D/src/ios/DPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/D/src/ios/DPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/D/src/ios/DPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/D/www/plugin-d.js",
    "chars": 33,
    "preview": "//dependencies/D/www/plugin-d.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/E/plugin.xml",
    "chars": 1930,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/E/src/android/E.java",
    "chars": 36,
    "preview": "./dependencies/E/src/android/E.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/E/src/ios/EPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/E/src/ios/EPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/E/src/ios/EPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/E/src/ios/EPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/E/www/plugin-d.js",
    "chars": 33,
    "preview": "//dependencies/E/www/plugin-d.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/F/plugin.xml",
    "chars": 1948,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/F/src/android/F.java",
    "chars": 36,
    "preview": "./dependencies/F/src/android/F.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/F/src/ios/FPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/F/src/ios/FPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/F/src/ios/FPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/F/src/ios/FPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/F/www/plugin-f.js",
    "chars": 33,
    "preview": "//dependencies/F/www/plugin-f.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/G/plugin.xml",
    "chars": 1922,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/G/src/android/G.java",
    "chars": 36,
    "preview": "./dependencies/G/src/android/G.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/G/src/ios/EPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/G/src/ios/EPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/G/src/ios/GPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/G/src/ios/GPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/G/www/plugin-g.js",
    "chars": 33,
    "preview": "//dependencies/G/www/plugin-g.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/H/plugin.xml",
    "chars": 1922,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/H/src/android/H.java",
    "chars": 36,
    "preview": "./dependencies/H/src/android/H.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/H/src/ios/HPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/H/src/ios/HPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/H/src/ios/HPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/H/src/ios/HPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/H/www/plugin-h.js",
    "chars": 33,
    "preview": "//dependencies/H/www/plugin-h.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/I/plugin.xml",
    "chars": 1700,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Iopyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/I/src/android/I.java",
    "chars": 36,
    "preview": "./dependencies/I/src/android/I.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/I/src/ios/IPluginCommand.h",
    "chars": 42,
    "preview": "./dependencies/C/src/ios/CPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/I/src/ios/IPluginCommand.m",
    "chars": 42,
    "preview": "./dependencies/I/src/ios/IPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/I/www/plugin-i.js",
    "chars": 33,
    "preview": "//dependencies/I/www/plugin-i.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/README.md",
    "chars": 397,
    "preview": "Here's a general overview of how the plugins in this directory are dependent on each other:\n\n          F\n         / \\\n  "
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test1/package.json",
    "chars": 201,
    "preview": "{\n  \"name\": \"test1\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test1/plugin.xml",
    "chars": 1395,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test1/src/android/Test1.java",
    "chars": 44,
    "preview": "./dependencies/Test1/src/android/Test1.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test1/www/plugin-test.js",
    "chars": 40,
    "preview": "//dependencies/Test1/www/plugin-test.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test2/package.json",
    "chars": 201,
    "preview": "{\n  \"name\": \"test2\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test2/plugin.xml",
    "chars": 1395,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test2/src/android/Test2.java",
    "chars": 44,
    "preview": "./dependencies/Test2/src/android/Test2.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test2/www/plugin-test.js",
    "chars": 40,
    "preview": "//dependencies/Test2/www/plugin-test.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test3/package.json",
    "chars": 201,
    "preview": "{\n  \"name\": \"test3\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test3/plugin.xml",
    "chars": 1395,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test3/src/android/Test3.java",
    "chars": 44,
    "preview": "./dependencies/Test3/src/android/Test3.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test3/www/plugin-test.js",
    "chars": 40,
    "preview": "//dependencies/Test3/www/plugin-test.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test4/package.json",
    "chars": 201,
    "preview": "{\n  \"name\": \"test4\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test4/plugin.xml",
    "chars": 1431,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright 2013 Anis Kadri\n\n Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test4/src/android/Test4.java",
    "chars": 44,
    "preview": "./dependencies/Test3/src/android/Test4.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/Test4/www/plugin-test.js",
    "chars": 40,
    "preview": "//dependencies/Test4/www/plugin-test.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/D/plugin.xml",
    "chars": 1984,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/D/src/android/D.java",
    "chars": 41,
    "preview": "./dependencies/meta/D/src/android/D.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/D/src/ios/DPluginCommand.h",
    "chars": 47,
    "preview": "./dependencies/meta/D/src/ios/DPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/D/src/ios/DPluginCommand.m",
    "chars": 47,
    "preview": "./dependencies/meta/D/src/ios/DPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/D/www/plugin-d.js",
    "chars": 38,
    "preview": "//dependencies/meta/D/www/plugin-d.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/subdir/E/plugin.xml",
    "chars": 1903,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/subdir/E/src/android/E.java",
    "chars": 48,
    "preview": "./dependencies/meta/subdir/E/src/android/E.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/subdir/E/src/ios/EPluginCommand.h",
    "chars": 54,
    "preview": "./dependencies/meta/subdir/E/src/ios/EPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/subdir/E/src/ios/EPluginCommand.m",
    "chars": 54,
    "preview": "./dependencies/meta/subdir/E/src/ios/EPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/meta/subdir/E/www/plugin-e.js",
    "chars": 45,
    "preview": "//dependencies/meta/subdir/E/www/plugin-e.js\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/subdir/E/plugin.xml",
    "chars": 1903,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/dependencies/subdir/E/src/android/E.java",
    "chars": 43,
    "preview": "./dependencies/subdir/E/src/android/E.java\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/subdir/E/src/ios/EPluginCommand.h",
    "chars": 49,
    "preview": "./dependencies/subdir/E/src/ios/EPluginCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/subdir/E/src/ios/EPluginCommand.m",
    "chars": 49,
    "preview": "./dependencies/subdir/E/src/ios/EPluginCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/dependencies/subdir/E/www/plugin-e.js",
    "chars": 40,
    "preview": "//dependencies/subdir/E/www/plugin-e.js\n"
  },
  {
    "path": "spec/plugman/plugins/org.test.androidonly/plugin.xml",
    "chars": 1268,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/org.test.androidonly/www/android.js",
    "chars": 38,
    "preview": "//org.test.androidonly/www/android.js\n"
  },
  {
    "path": "spec/plugman/plugins/org.test.defaultvariables/plugin.xml",
    "chars": 436,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<plugin xmlns=\"http://cordova.apache.org/ns/plugins/1.0\"\n    xmlns:android=\"http"
  },
  {
    "path": "spec/plugman/plugins/org.test.invalid.engine.no.platform/plugin.xml",
    "chars": 877,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may n"
  },
  {
    "path": "spec/plugman/plugins/org.test.invalid.engine.no.scriptSrc/plugin.xml",
    "chars": 868,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may n"
  },
  {
    "path": "spec/plugman/plugins/org.test.invalid.engine.script/plugin.xml",
    "chars": 896,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may n"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/package.json",
    "chars": 616,
    "preview": "{\n  \"name\": \"childbrowser\",\n  \"version\": \"1.3.1\",\n  \"description\": \"Empty plugin used as part of the tests in cordova-li"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/plugin.xml",
    "chars": 4441,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more c"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/src/android/ChildBrowser.java",
    "chars": 79,
    "preview": "./org.test.plugins.childbrowser/src/android/org.test.plugins.childbrowser.java\n"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/src/ios/ChildBrowserCommand.h",
    "chars": 62,
    "preview": "./org.test.plugins.childbrowser/src/ios/ChildBrowserCommand.h\n"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/src/ios/ChildBrowserCommand.m",
    "chars": 62,
    "preview": "./org.test.plugins.childbrowser/src/ios/ChildBrowserCommand.m\n"
  },
  {
    "path": "spec/plugman/plugins/org.test.plugins.childbrowser/src/ios/ChildBrowserViewController.h",
    "chars": 69,
    "preview": "./org.test.plugins.childbrowser/src/ios/ChildBrowserViewController.h\n"
  }
]

// ... and 78 more files (download for full content)

About this extraction

This page contains the full source code of the apache/cordova-lib GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 278 files (745.1 KB), approximately 182.0k tokens, and a symbol index with 179 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!