Ver código fonte

feat(config): add `$schema` to `tauri.conf.json`, closes #3464 (#4031)

Lucas Fernandes Nogueira 3 anos atrás
pai
commit
715cbde384
31 arquivos alterados com 173 adições e 70 exclusões
  1. 7 0
      .changes/config-$schema.md
  2. 5 1
      core/tauri-utils/src/config.rs
  3. 1 0
      core/tauri/src/test/mod.rs
  4. 1 0
      core/tauri/test/fixture/src-tauri/tauri.conf.json
  5. 1 0
      core/tests/app-updater/tauri.conf.json
  6. 1 0
      examples/api/src-tauri/tauri.conf.json
  7. 1 0
      examples/commands/tauri.conf.json
  8. 1 0
      examples/helloworld/tauri.conf.json
  9. 1 0
      examples/isolation/tauri.conf.json
  10. 1 0
      examples/multiwindow/tauri.conf.json
  11. 1 0
      examples/navigation/tauri.conf.json
  12. 1 0
      examples/parent-window/tauri.conf.json
  13. 1 0
      examples/resources/src-tauri/tauri.conf.json
  14. 1 0
      examples/sidecar/src-tauri/tauri.conf.json
  15. 1 0
      examples/splashscreen/tauri.conf.json
  16. 1 0
      examples/state/tauri.conf.json
  17. 1 0
      examples/streaming/tauri.conf.json
  18. 1 0
      examples/tauri-dynamic-lib/src-tauri/tauri.conf.json
  19. 1 0
      examples/updater/src-tauri/tauri.conf.json
  20. 1 0
      tooling/bench/tests/cpu_intensive/src-tauri/tauri.conf.json
  21. 1 0
      tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json
  22. 1 0
      tooling/bench/tests/helloworld/src-tauri/tauri.conf.json
  23. 2 1
      tooling/cli/node/.gitignore
  24. 4 2
      tooling/cli/node/package.json
  25. 1 0
      tooling/cli/node/test/jest/fixtures/app/src-tauri/tauri.conf.json
  26. 8 1
      tooling/cli/node/yarn.lock
  27. 7 0
      tooling/cli/schema.json
  28. 51 0
      tooling/cli/src/init.rs
  29. 2 0
      tooling/cli/src/lib.rs
  30. 1 65
      tooling/cli/templates/app/src-tauri/tauri.conf.json
  31. 65 0
      tooling/cli/templates/tauri.conf.json

+ 7 - 0
.changes/config-$schema.md

@@ -0,0 +1,7 @@
+---
+"tauri-utils": patch
+"cli.rs": patch
+"cli.js": patch
+---
+
+Added `$schema` support to `tauri.conf.json`.

+ 5 - 1
core/tauri-utils/src/config.rs

@@ -2125,6 +2125,9 @@ impl PackageConfig {
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
 pub struct Config {
+  /// The JSON schema for the Tauri config.
+  #[serde(rename = "$schema")]
+  pub schema: Option<String>,
   /// Package settings.
   #[serde(default)]
   pub package: PackageConfig,
@@ -2887,12 +2890,13 @@ mod build {
 
   impl ToTokens for Config {
     fn to_tokens(&self, tokens: &mut TokenStream) {
+      let schema = quote!(None);
       let package = &self.package;
       let tauri = &self.tauri;
       let build = &self.build;
       let plugins = &self.plugins;
 
-      literal_struct!(tokens, Config, package, tauri, build, plugins);
+      literal_struct!(tokens, Config, schema, package, tauri, build, plugins);
     }
   }
 }

+ 1 - 0
core/tauri/src/test/mod.rs

@@ -42,6 +42,7 @@ pub fn noop_assets() -> NoopAsset {
 pub fn mock_context<A: Assets>(assets: A) -> crate::Context<A> {
   crate::Context {
     config: Config {
+      schema: None,
       package: Default::default(),
       tauri: TauriConfig {
         pattern: PatternKind::Brownfield,

+ 1 - 0
core/tauri/test/fixture/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../../../tooling/cli/schema.json",
   "build": {
     "distDir": "../dist",
     "devPath": "http://localhost:4000"

+ 1 - 0
core/tests/app-updater/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": [],
     "devPath": []

+ 1 - 0
examples/api/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": "../dist",
     "devPath": "http://localhost:5000",

+ 1 - 0
examples/commands/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/helloworld/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/isolation/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "package": {
     "productName": "isolation",
     "version": "0.1.0"

+ 1 - 0
examples/multiwindow/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/navigation/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": "public",
     "devPath": "public",

+ 1 - 0
examples/parent-window/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/resources/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": ["../index.html"],
     "devPath": ["../index.html"],

+ 1 - 0
examples/sidecar/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": ["../index.html"],
     "devPath": ["../index.html"],

+ 1 - 0
examples/splashscreen/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": "dist",
     "devPath": "dist",

+ 1 - 0
examples/state/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/streaming/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../tooling/cli/schema.json",
   "build": {
     "distDir": ["index.html"],
     "devPath": ["index.html"],

+ 1 - 0
examples/tauri-dynamic-lib/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": ["src/index.html"],
     "devPath": ["src/index.html"],

+ 1 - 0
examples/updater/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../tooling/cli/schema.json",
   "build": {
     "distDir": ["../index.html"],
     "devPath": ["../index.html"],

+ 1 - 0
tooling/bench/tests/cpu_intensive/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../../../tooling/cli/schema.json",
   "build": {
     "distDir": "../public",
     "devPath": "../public",

+ 1 - 0
tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../../../tooling/cli/schema.json",
   "build": {
     "distDir": "../public",
     "devPath": "../public",

+ 1 - 0
tooling/bench/tests/helloworld/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../../../tooling/cli/schema.json",
   "build": {
     "distDir": "../public",
     "devPath": "../public",

+ 2 - 1
tooling/cli/node/.gitignore

@@ -1,2 +1,3 @@
 # Automatically generated
-/*.node
+/*.node
+schema.json

+ 4 - 2
tooling/cli/node/package.json

@@ -38,6 +38,7 @@
   },
   "devDependencies": {
     "@napi-rs/cli": "2.7.0",
+    "cross-env": "7.0.3",
     "cross-spawn": "7.0.3",
     "fs-extra": "10.1.0",
     "jest": "28.0.3",
@@ -52,9 +53,10 @@
   },
   "scripts": {
     "artifacts": "napi artifacts",
-    "build:release": "napi build --platform --release",
-    "build": "napi build --platform",
+    "build:release": "cross-env TARGET=node napi build --platform --release",
+    "build": "cross-env TARGET=node napi build --platform",
     "prepublishOnly": "napi prepublish -t npm",
+    "prepack": "cp ../schema.json .",
     "test": "jest --runInBand --forceExit --no-cache",
     "version": "napi version",
     "tauri": "node ./tauri.js",

+ 1 - 0
tooling/cli/node/test/jest/fixtures/app/src-tauri/tauri.conf.json

@@ -1,4 +1,5 @@
 {
+  "$schema": "../../../../../../../../tooling/cli/schema.json",
   "build": {
     "devPath": "../dist",
     "distDir": "../dist",

+ 8 - 1
tooling/cli/node/yarn.lock

@@ -1041,7 +1041,14 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
   dependencies:
     safe-buffer "~5.1.1"
 
-cross-spawn@7.0.3, cross-spawn@^7.0.3:
+cross-env@^7.0.3:
+  version "7.0.3"
+  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
+  integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
+  dependencies:
+    cross-spawn "^7.0.1"
+
+cross-spawn@7.0.3, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
   version "7.0.3"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
   integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==

+ 7 - 0
tooling/cli/schema.json

@@ -4,6 +4,13 @@
   "description": "The config type mapped to `tauri.conf.json`.",
   "type": "object",
   "properties": {
+    "$schema": {
+      "description": "The JSON schema for the Tauri config.",
+      "type": [
+        "string",
+        "null"
+      ]
+    },
     "build": {
       "description": "The build configuration.",
       "default": {

+ 51 - 0
tooling/cli/src/init.rs

@@ -27,6 +27,7 @@ use include_dir::{include_dir, Dir};
 use serde::Deserialize;
 
 const TEMPLATE_DIR: Dir<'_> = include_dir!("templates/app");
+const TAURI_CONF_TEMPLATE: &str = include_str!("../templates/tauri.conf.json");
 
 #[derive(Debug, Parser)]
 #[clap(about = "Initializes a Tauri project")]
@@ -185,6 +186,56 @@ pub fn command(mut options: Options) -> Result<()> {
       to_json(options.window_title.unwrap_or_else(|| "Tauri".to_string())),
     );
 
+    let mut config = serde_json::from_str(
+      &handlebars
+        .render_template(TAURI_CONF_TEMPLATE, &data)
+        .expect("Failed to render tauri.conf.json template"),
+    )
+    .unwrap();
+    if crate::TARGET == Some("node") {
+      let mut dir = current_dir().expect("failed to read cwd");
+      let mut count = 0;
+      let mut cli_node_module_path = None;
+      let cli_path = "node_modules/@tauri-apps/cli";
+
+      // only go up three folders max
+      while count <= 2 {
+        let test_path = dir.join(cli_path);
+        if test_path.exists() {
+          let mut node_module_path = PathBuf::from("..");
+          for _ in 0..count {
+            node_module_path.push("..");
+          }
+          node_module_path.push(cli_path);
+          node_module_path.push("schema.json");
+          cli_node_module_path.replace(node_module_path);
+          break;
+        }
+        count += 1;
+        match dir.parent() {
+          Some(parent) => {
+            dir = parent.to_path_buf();
+          }
+          None => break,
+        }
+      }
+
+      if let Some(cli_node_module_path) = cli_node_module_path {
+        let mut map = serde_json::Map::default();
+        map.insert(
+          "$schema".into(),
+          serde_json::Value::String(cli_node_module_path.display().to_string()),
+        );
+        let merge_config = serde_json::Value::Object(map);
+        json_patch::merge(&mut config, &merge_config);
+      }
+    }
+
+    data.insert(
+      "tauri_config",
+      to_json(serde_json::to_string_pretty(&config).unwrap()),
+    );
+
     template::render(&handlebars, &data, &TEMPLATE_DIR, &options.directory)
       .with_context(|| "failed to render Tauri template")?;
   }

+ 2 - 0
tooling/cli/src/lib.rs

@@ -17,6 +17,8 @@ use clap::{FromArgMatches, IntoApp, Parser, Subcommand};
 
 use std::ffi::OsString;
 
+const TARGET: Option<&str> = option_env!("TARGET");
+
 pub(crate) trait CommandExt {
   fn pipe(&mut self) -> Result<&mut Self>;
 }

+ 1 - 65
tooling/cli/templates/app/src-tauri/tauri.conf.json

@@ -1,65 +1 @@
-{
-  "package": {
-    "productName": "{{ app_name }}",
-    "version": "0.1.0"
-  },
-  "build": {
-    "distDir": "{{ dist_dir }}",
-    "devPath": "{{ dev_path }}",
-    "beforeDevCommand": "",
-    "beforeBuildCommand": ""
-  },
-  "tauri": {
-    "bundle": {
-      "active": true,
-      "targets": "all",
-      "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": [],
-        "exceptionDomain": "",
-        "signingIdentity": null,
-        "providerShortName": null,
-        "entitlements": null
-      },
-      "windows": {
-        "certificateThumbprint": null,
-        "digestAlgorithm": "sha256",
-        "timestampUrl": ""
-      }
-    },
-    "updater": {
-      "active": false
-    },
-    "allowlist": {
-      "all": true
-    },
-    "windows": [
-      {
-        "title": "{{ window_title }}",
-        "width": 800,
-        "height": 600,
-        "resizable": true,
-        "fullscreen": false
-      }
-    ],
-    "security": {
-      "csp": null
-    }
-  }
-}
+{{{ tauri_config }}}

+ 65 - 0
tooling/cli/templates/tauri.conf.json

@@ -0,0 +1,65 @@
+{
+  "package": {
+    "productName": "{{ app_name }}",
+    "version": "0.1.0"
+  },
+  "build": {
+    "distDir": "{{ dist_dir }}",
+    "devPath": "{{ dev_path }}",
+    "beforeDevCommand": "",
+    "beforeBuildCommand": ""
+  },
+  "tauri": {
+    "bundle": {
+      "active": true,
+      "targets": "all",
+      "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": [],
+        "exceptionDomain": "",
+        "signingIdentity": null,
+        "providerShortName": null,
+        "entitlements": null
+      },
+      "windows": {
+        "certificateThumbprint": null,
+        "digestAlgorithm": "sha256",
+        "timestampUrl": ""
+      }
+    },
+    "updater": {
+      "active": false
+    },
+    "allowlist": {
+      "all": true
+    },
+    "windows": [
+      {
+        "title": "{{ window_title }}",
+        "width": 800,
+        "height": 600,
+        "resizable": true,
+        "fullscreen": false
+      }
+    ],
+    "security": {
+      "csp": null
+    }
+  }
+}