diff --git a/.changes/config.json b/.changes/config.json
index 1cff960aa..77134069f 100644
--- a/.changes/config.json
+++ b/.changes/config.json
@@ -269,7 +269,7 @@
"path": "./tooling/cli.rs",
"manager": "rust",
"dependencies": ["tauri-bundler"],
- "postversion": "node ../../.scripts/covector/generate-cli-doc.js && cargo check"
+ "postversion": "node ../../.scripts/covector/generate-cli-doc.js && node ../../.scripts/covector/generate-config-doc.js && cargo check"
},
"create-tauri-app": {
"path": "./tooling/create-tauri-app",
diff --git a/.scripts/covector/generate-config-doc.js b/.scripts/covector/generate-config-doc.js
new file mode 100644
index 000000000..2264b8043
--- /dev/null
+++ b/.scripts/covector/generate-config-doc.js
@@ -0,0 +1,114 @@
+const fs = require('fs')
+const path = require('path')
+const schema = JSON.parse(fs.readFileSync('tooling/cli.rs/schema.json').toString())
+const templatePath = path.join(__dirname, '../../docs/.templates/config.md')
+const targetPath = path.join(__dirname, '../../docs/api/config.md')
+const template = fs.readFileSync(templatePath, 'utf8')
+
+function formatDescription(description) {
+ return description ?
+ description
+ .replace(/`/g, '\\`')
+ .replace(/\n/g, ' ')
+ .replace(/ /g, ' ')
+ .replace(/{/g, '\\{')
+ .replace(/}/g, '\\}') :
+ ''
+}
+
+function generatePropertiesEl(schema, anchorRoot, definition, tab) {
+ const previousTabLevel = tab.replace(' ', '')
+ const fields = [`anchorRoot="${anchorRoot}"`]
+
+ if (definition.additionalProperties) {
+ fields.push(`type="${definition.type}"`)
+ fields.push(`description="${formatDescription(definition.description)}"`)
+ }
+
+ const rows = []
+ for (const propertyName in definition.properties) {
+ const property = definition.properties[propertyName]
+ if ('type' in property) {
+ let type
+ if ('items' in property) {
+ if (property.items.type) {
+ type = `${property.items.type}[]`
+ } else {
+ const typeName = property.items.$ref.replace('#/definitions/', '')
+ const propDefinition = schema.definitions[typeName]
+ const propertyEl = generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `)
+ rows.push({
+ property: propertyName,
+ optional: ('default' in property) || property.type.includes('null'),
+ type: `${typeName}[]`,
+ description: property.description,
+ child: `\n${tab}${propertyEl}\n${previousTabLevel}`
+ })
+ continue
+ }
+ } else if (Array.isArray(property.type)) {
+ type = property.type.join(' | ')
+ } else {
+ type = property.type
+ }
+ rows.push({
+ property: propertyName,
+ optional: true,
+ type,
+ description: property.description,
+ default: property.default
+ })
+ } else if ('anyOf' in property) {
+ const subType = property.anyOf[0].$ref.replace('#/definitions/', '')
+ const propDefinition = schema.definitions[subType]
+ const propertyEl = generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `)
+ rows.push({
+ property: propertyName,
+ optional: property.anyOf.length > 1 && property.anyOf[1].type === 'null',
+ type: subType,
+ description: property.description,
+ child: propertyEl
+ })
+ } else if ('allOf' in property) {
+ const subType = property.allOf[0].$ref.replace('#/definitions/', '')
+ const propDefinition = schema.definitions[subType]
+ const propertyEl = propDefinition.properties ? generatePropertiesEl(schema, `${anchorRoot}.${propertyName}`, propDefinition, `${tab} `) : undefined
+ rows.push({
+ property: propertyName,
+ optional: 'default' in property,
+ type: property.type || subType,
+ description: property.description,
+ child: propertyEl
+ })
+ }
+ }
+
+ if (rows.length > 0) {
+ const serializedRows = rows
+ .map(row => {
+ const fields = [`property: "${row.property}"`, `optional: ${row.optional}`, `type: "${row.type}"`, `description: \`${formatDescription(row.description)}\``]
+ if (row.child) {
+ fields.push(`child: ${row.child}`)
+ }
+ return `{ ${fields.join(', ')} },`
+ })
+ .join(`\n${tab}`)
+ fields.push(`rows={[\n${tab}${serializedRows}\n${previousTabLevel}]}`)
+ } else {
+ fields.push('rows={[]}')
+ }
+
+ return ``
+}
+
+const output = []
+
+for (const propertyName in schema.properties) {
+ const property = schema.properties[propertyName]
+ const definitionName = property.allOf[0].$ref.replace('#/definitions/', '')
+ const definition = schema.definitions[definitionName]
+ let contents = `## \`${propertyName}\`\n\n${generatePropertiesEl(schema, propertyName, definition, ' ')}`
+ output.push(contents)
+}
+
+fs.writeFileSync(targetPath, template.replace('{properties}', output.join('\n\n')))
diff --git a/docs/.templates/config.md b/docs/.templates/config.md
new file mode 100644
index 000000000..3d9d2391c
--- /dev/null
+++ b/docs/.templates/config.md
@@ -0,0 +1,103 @@
+---
+title: Configuration
+---
+
+import Properties from '@theme/Properties'
+import Array from '@theme/Array'
+import Alert from '@theme/Alert'
+
+The `tauri.conf.json` is a file generated by the `tauri init` command (see here) that lives in your Tauri application source directory (src-tauri).
+
+Once generated, you may modify it at will to customize your Tauri application.
+
+# Platform-specific configuration
+
+In addition to the JSON defined on the `tauri.conf.json` file, Tauri reads a platform-specific configuration on `tauri.linux.conf.json`, `tauri.windows.conf.json` and `tauri.macos.conf.json` and merges it with the main `tauri.conf.json` configuration.
+
+# Configuration structure
+
+`tauri.conf.json` is composed of the following properties:
+
+{properties}
+
+
+
+
+
+Instead of launching the app directly, we configure the bundled app to run a script that tries to expose the environment variables to the app; without that you'll have trouble using system CLI apps like Node.js.
+
+
+```js title=Example
+"tauri": {
+ "cli": {
+ "description": "Tauri communication example",
+ "longDescription": null,
+ "beforeHelp": null,
+ "afterHelp": null,
+ "args": [{
+ "short": "c",
+ "name": "config",
+ "takesValue": true,
+ "description": "Config path"
+ }, {
+ "short": "t",
+ "name": "theme",
+ "takesValue": true,
+ "description": "App theme",
+ "possibleValues": ["light", "dark", "system"]
+ }, {
+ "short": "v",
+ "name": "verbose",
+ "multipleOccurrences": true,
+ "description": "Verbosity level"
+ }],
+ "subcommands": {
+ "update": {
+ "description": "Updates the app",
+ "longDescription": null,
+ "beforeHelp": null,
+ "afterHelp": null,
+ "args": [{
+ "short": "b",
+ "name": "background",
+ "description": "Update in background"
+ }],
+ "subcommands": null
+ }
+ }
+ },
+ "bundle": {
+ "active": true,
+ "targets": ["deb"],
+ "identifier": "com.tauri.dev",
+ "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
+ "resources": [],
+ "externalBin": [],
+ "copyright": "",
+ "category": "DeveloperTool",
+ "shortDescription": "",
+ "longDescription": "",
+ "deb": {
+ "depends": []
+ },
+ "macOS": {
+ "frameworks": [],
+ "minimumSystemVersion": "",
+ "exceptionDomain": ""
+ }
+ },
+ "allowlist": {
+ "all": true
+ },
+ "windows": [{
+ "title": "Tauri App",
+ "width": 800,
+ "height": 600,
+ "resizable": true,
+ "fullscreen": false
+ }],
+ "security": {
+ "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'"
+ }
+}
+```
diff --git a/tooling/cli.rs/config_definition.rs b/tooling/cli.rs/config_definition.rs
index 54ed08a6c..48648f655 100644
--- a/tooling/cli.rs/config_definition.rs
+++ b/tooling/cli.rs/config_definition.rs
@@ -841,8 +841,6 @@ fn default_dist_dir() -> AppUrl {
AppUrl::Url("../dist".to_string())
}
-type JsonObject = HashMap;
-
/// The tauri.conf.json mapper.
#[skip_serializing_none]
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
@@ -859,9 +857,13 @@ pub struct Config {
pub build: BuildConfig,
/// The plugins config.
#[serde(default)]
- pub plugins: HashMap,
+ pub plugins: PluginConfig,
}
+/// The plugin configs holds a HashMap mapping a plugin name to its configuration object.
+#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize, JsonSchema)]
+pub struct PluginConfig(pub HashMap);
+
fn default_build() -> BuildConfig {
BuildConfig {
runner: None,
diff --git a/tooling/cli.rs/schema.json b/tooling/cli.rs/schema.json
index 4210d79be..6d1a4f33c 100644
--- a/tooling/cli.rs/schema.json
+++ b/tooling/cli.rs/schema.json
@@ -29,11 +29,11 @@
"plugins": {
"description": "The plugins config.",
"default": {},
- "type": "object",
- "additionalProperties": {
- "type": "object",
- "additionalProperties": true
- }
+ "allOf": [
+ {
+ "$ref": "#/definitions/PluginConfig"
+ }
+ ]
},
"tauri": {
"description": "The Tauri configuration.",
@@ -954,6 +954,11 @@
},
"additionalProperties": false
},
+ "PluginConfig": {
+ "description": "The plugin configs holds a HashMap mapping a plugin name to its configuration object.",
+ "type": "object",
+ "additionalProperties": true
+ },
"SecurityConfig": {
"type": "object",
"properties": {