With `customManagers` using `JSONata` queries you can configure Renovate so it finds dependencies in JSON, TOML and YAML files, that are not detected by its other built-in package managers. Renovate uses the `jsonata` package to process the file content using the queries, after the content has been parsed into `json` format. For more on the jsonata query language, read the [jsonata query language site](https://docs.jsonata.org/overview.html). The JSONata manager is unique in Renovate, because: - It can be used with any `datasource` - It can be configured via [JSONata](https://jsonata.org/) queries - You can create multiple "JSONata managers" in the same repository If you have limited managers to run within [`enabledManagers` config option](../../../configuration-options.md#enabledmanagers), you need to add `"custom.jsonata"` to the list. ### Required Fields The first two required fields are `managerFilePatterns` and `matchStrings`: - `managerFilePatterns` works the same as any manager - `matchStrings` is a `JSONata` custom manager concept and is used for configuring a jsonata queries #### Information that Renovate needs about the dependency Before Renovate can look up a dependency and decide about updates, it must have this info about each dependency: | Info type | Required | Notes | Docs | | :--------------------------------------------------- | :------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------ | | Name of the dependency | Yes | | | | `datasource` | Yes | Example datasources: npm, Docker, GitHub tags, and so on. | [Supported datasources](../../datasource/index.md#supported-datasources) | | Version scheme to use. Defaults to `semver-coerced`. | Yes | You may set another version scheme, like `pep440`. | [Supported versioning schemes](../../versioning/index.md#supported-versioning) | | `fileFormat` | Yes | Must be either `json`, `yaml` or `toml`. | [`Configuration Options`](../../../configuration-options.md#custommanagersfileformat) | #### Required fields to be present in the resulting structure returned by the jsonata query You must: - Capture the `currentValue` or `currentDigest` of the dependency _or_ use the `currentValueTemplate` or `currentDigestTemplate` template field - Capture the `depName` or `packageName`. _Or_ use a template field: `depNameTemplate` and `packageNameTemplate` - Capture the `datasource`, _or_ use the `datasourceTemplate` template field #### Optional fields you can include in the resulting structure You may use any of these items: - `depType`, _or_ use the `depTypeTemplate` template field - `versioning`, _or_ the use `versioningTemplate` template field. If neither are present, Renovate defaults to `semver-coerced` - `extractVersion`, _or_ use the `extractVersionTemplate` template field - `registryUrl`, _or_ use the `registryUrlTemplate` template field. If it's a valid URL, it will be converted to the `registryUrls` field as a single-length array - `indentation`. Must be empty, _or_ whitespace. Else Renovate restes only `indentation` to an empty string ### Usage When you configure a JSONata manager, use the following syntax: ```javascript { "customManagers": [ { "customType": "jsonata", "fileFormat": "json", "managerFilePatterns": [""], "matchStrings": [""], ... } ] } ``` Overwrite the `` placeholder text with your [JSONata](https://docs.jsonata.org/overview.html) query. The JSONata query transforms the content to a JSON object, similar to this: ```json title="dependencies information extracted using a JSONata query" [ { "depName": "some_dep", "currentValue": "1.0.0", "datasource": "docker", "versioning": "semver" } ] ``` Creating your Renovate JSONata manager config is easier if you understand JSONata queries. We recommend you follow these steps: 1. Read the official JSONata query language docs 2. Check our example queries below 3. You're ready to make your own config Alternatively, you can use "trial and error" to a working config by adjusting our examples. YAML files are parsed as multi-document files, even those that have only one document. #### YAML parsing To show how the JSONata manager parses YAML, below is an example YAML file and the corresponding parsing to JSON. YAML: ```yaml title="Example multi document YAML file" production: packages: version: 1.2.3 package: foo test: metadata: - version: 4.5.6 package: bar --- development: author: Renovate ``` JSON: ```json title="Example JSON parsing" [ { "production": { "packages": { "version": "1.2.3", "package": "foo" } }, "test": { "metadata": [ { "version": "4.5.6", "package": "bar" } ] } }, { "development": { "author": "Renovate" } } ] ``` #### Example queries Below are some example queries for the generic JSON manager. You can also use the [JSONata test website](https://try.jsonata.org) to experiment with queries. ```json title="Dependencies spread in different nodes, and we want to limit the extraction to a particular node" { "production": [ { "version": "1.2.3", "package": "foo" } ], "development": [ { "version": "4.5.6", "package": "bar" } ] } ``` Query: ``` production.{ "depName": package, "currentValue": version } ``` ```json title="Dependencies spread in different nodes, and we want to extract all of them as if they were in the same node" { "production": [ { "version": "1.2.3", "package": "foo" } ], "development": [ { "version": "4.5.6", "package": "bar" } ] } ``` Query: ``` *.{ "depName": package, "currentValue": version } ``` ```json title="The dependency name is in a JSON node name, and the version is in a child leaf to that node" { "foo": { "version": "1.2.3" }, "bar": { "version": "4.5.6" } } ``` Query: ``` $each(function($v, $n) { { "depName": $n, "currentValue": $v.version } }) ``` ```json title="The dependency name and its version are both value nodes of the same parent node" { "packages": [ { "version": "1.2.3", "package": "foo" }, { "version": "4.5.6", "package": "bar" } ] } ``` Query: ``` packages.{ "depName": package, "currentValue": version } ``` ```json title="The dependency name and version are part of the same string" { "packages": ["foo@1.2.3", "bar@4.5.6"] } ``` Query: ``` $map($map(packages, function ($v) { $split($v, "@") }), function ($v) { { "depName": $v[0], "currentVersion": $v[1] } }) ``` ```json title="JSONata manager config to extract deps from a package.json file in the Renovate repository" { "customManagers": [ { "customType": "jsonata", "fileFormat": "json", "managerFilePatterns": ["/package.json/"], "matchStrings": [ "$each(dependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"dependencies\"}})", "$each(devDependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"devDependencies\"}})", "$each(optionalDependencies, function($v, $k) { {\"depName\":$k, \"currentValue\": $v, \"depType\": \"optionalDependencies\"}})", "{ \"depName\": \"pnpm\", \"currentValue\": $substring(packageManager, 5), \"depType\": \"packageManager\"}" ], "datasourceTemplate": "npm" } ] } ``` ```yaml title="Dependencies in a single node, and we want to extract all of them" packages: - version: 1.2.3 package: foo ``` Query: ``` packages.{ "depName": package, "currentValue": version } ``` ```yaml title="Dependencies in a single node in a multi document yaml, and we want to extract all of them" packages: - version: 1.2.3 package: foo --- packages: - version: 1.2.5 package: bar ``` Query: ``` packages.{ "depName": package, "currentValue": version } ``` ```toml title="JSONata manager config to extract deps from a toml file" [[packages]] version = "1.2.3" package = "foo" [[packages]] version = "1.2.2" package = "bar" ``` Query: ``` packages.{ "depName": package, "currentValue": version } ```