{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {"$ref": "https://schemastore.azurewebsites.net/schemas/json/package.json"}
  ],
  "properties": {
    "name": {
      "description": "The name of the package. Must start with \"flipper-plugin-\" prefix.",
      "type": "string",
      "maxLength": 214,
      "pattern": "^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?flipper-plugin-[a-z0-9-._~]*$",
      "errorMessage": "should start with \"flipper-plugin-\", e.g. \"flipper-plugin-example\""
    },
    "id": {
      "type": "string",
      "description": "Used as the plugin native identifier and must match the mobile plugin identifier. Also shown in the Flipper main sidebar if \"title\" property is omitted."
    },
    "flipperBundlerEntry": {
      "type": "string",
      "filePathExists": true,
      "description": "Points to the source entry point which will be used for the plugin code bundling. \"flipper-pkg\" takes the path specified in this property as source, transpiles and bundles it, and saves the output to the path specified in property \"main\"."
    },
    "serverAddOn": {
      "type": "string",
      "description": "Path to the bundled and ready-to-execute code of the server add-on."
    },
    "flipperBundlerEntryServerAddOn": {
      "type": "string",
      "filePathExists": true,
      "description": "Points to the source entry point which will be used for the server add-on code bundling. \"flipper-pkg\" takes the path specified in this property as source, transpiles and bundles it, and saves the output to the path specified in property \"serverAddOn\"."
    },
    "title": {
      "type": "string",
      "description": "Shown in the Flipper main sidebar as the human-readable name of the plugin. If omitted, \"id\" is used instead."
    },
    "icon": {
      "type": "string",
      "description": "Determines the plugin icon which is displayed in the main sidebar. The list of available icons is static for now and can be found in https://github.com/facebook/flipper/blob/main/desktop/static/icons.json."
    },
    "keywords": {
      "description": "This helps people discover your package as it's listed in 'npm search'. To make the plugin discoverable in Flipper, the property must contain \"flipper-plugin\" keyword.",
      "type": "array",
      "items": {
        "type": "string"
      },
      "contains": {
        "type": "string",
        "pattern": "flipper-plugin"
      },
      "errorMessage": "should contain keyword \"flipper-plugin\""
    },
    "pluginType": {
      "description": "Type of the plugin - \"client\" if the plugin connects to a specific client plugin running in a mobile app, or \"device\" if it connects to devices. If omitted, \"client\" type is assumed by default.",
      "type": "string",
      "enum": ["client", "device"]
    },
    "supportedDevices": {
      "description": "List of devices supported by the plugin. The list could contain multiple devices each defined as conjunction of several properties.",
      "type": "array",
      "items": {
        "description": "Device definition. E.g. {\"os\": \"Android\", \"type\": \"physical\", \"archived\": false} means that plugin supports only Android physical unarchived devices.",
        "type": "object",
        "properties": {
          "os": {
            "description": "Device OS: iOS, Android, Metro, MacOS, Linux, Windows. Lack of this property means that all OSes supported.",
            "type": "string",
            "enum": ["iOS", "Android", "Metro", "MacOS", "Linux", "Windows"]
          },
          "type": {
            "description": "Device type: physical or emulator or dummy. Lack of this property means it supports physical, emulator and dummy devices.",
            "type": "string",
            "enum": ["physical", "emulator", "dummy"]
          },
          "archived": {
            "description": "Specifies support for archived devices. Lack of this property means that both live and archived devices supported. False means only live devices supported. True means only archived devices supported.",
            "type": "boolean"
          },
          "specs": {
            "description": "Additional specs required for plugin, e.g. \"KaiOS\" runtime.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["KaiOS"]
            }
          }
        }
      }
    },
    "supportedApps": {
      "description": "List of apps supported by the plugin.",
      "type": "array",
      "items": {
        "description": "App definition. E.g. {\"appID\": \"Facebook\", \"os\": \"Android\", \"type\": \"physical\"} means that plugin supports only Facebook app on Android physical devices.",
        "type": "object",
        "properties": {
          "appID": {
            "description": "App name: Facebook, Instagram or Messenger.",
            "type": "string"
          },
          "os": {
            "description": "Device OS: iOS, Android or Metro. Lack of this property means that all OSes supported.",
            "type": "string",
            "enum": ["iOS", "Android", "Metro"]
          },
          "type": {
            "description": "Device type: physical or emulator or dummy. Lack of this property means it supports physical, emulator and dummy devices.",
            "type": "string",
            "enum": ["physical", "emulator"]
          }
        }
      }
    },
    "headless": {
      "type": "boolean",
      "description": "Specifies if plugin works in a headless mode. Default: false."
    },
    "deprecated": {
      "type": "string",
      "description": "Mark plugin as deprecated and exclude it from the bundle. Optionally, provide a reason for deprecation. Set to '' to use the default deprecation reason."
    }
  },
  "required": [
    "name",
    "version",
    "id",
    "main",
    "flipperBundlerEntry",
    "keywords"
  ]
}
