瀏覽代碼

feat(api.js): add `os` module (#2299)

* feat(api.js): add `os` module

* use correct endpoint for version

* return version as a string

* clippy

* cleanup ?!

* [skip ci]

* [skip ci]
Amr Bashir 4 年之前
父節點
當前提交
05e679a6d2

+ 4 - 0
.changes/api-os-module.md

@@ -0,0 +1,4 @@
+---
+"api": patch
+---
+Add `os` module which exports `EOL`, `platform()`, `version()`, `type()`, `arch()`, `tempdir()`

+ 3 - 0
core/tauri/Cargo.toml

@@ -69,6 +69,7 @@ os_pipe = { version = "0.9", optional = true }
 rfd = "0.4"
 raw-window-handle = { version = "0.3.3", optional = true }
 minisign-verify = { version = "0.1", optional = true }
+os_info = { version = "3.0.6", optional = true}
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
 gtk = { version = "0.9", features = [ "v3_16" ] }
@@ -97,6 +98,7 @@ api-all = [
   "notification-all",
   "global-shortcut-all",
   "shell-all",
+  "os-all",
   "dialog-all",
   "updater"
 ]
@@ -128,3 +130,4 @@ http-all = [ ]
 http-request = [ ]
 notification-all = [ "notify-rust" ]
 global-shortcut-all = [ ]
+os-all = [ "os_info" ]

+ 3 - 0
core/tauri/build.rs

@@ -51,5 +51,8 @@ fn main() {
 
     // global shortcut
     global_shortcut_all: { any(api_all, feature = "global_shortcut-all") },
+
+    // os
+    os_all: { any(api_all, feature = "os-all") },
   }
 }

文件差異過大導致無法顯示
+ 0 - 0
core/tauri/scripts/bundle.js


+ 4 - 0
core/tauri/src/endpoints.rs

@@ -24,6 +24,7 @@ mod global_shortcut;
 mod http;
 mod internal;
 mod notification;
+mod operating_system;
 mod process;
 mod shell;
 mod window;
@@ -47,6 +48,7 @@ enum Module {
   App(app::Cmd),
   Process(process::Cmd),
   Fs(file_system::Cmd),
+  Os(operating_system::Cmd),
   Window(Box<window::Cmd>),
   Shell(shell::Cmd),
   Event(event::Cmd),
@@ -82,6 +84,8 @@ impl Module {
           .and_then(|r| r.json)
           .map_err(InvokeError::from)
       }),
+      Self::Os(cmd) => resolver
+        .respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
       Self::Window(cmd) => resolver.respond_async(async move {
         cmd
           .run(window)

+ 40 - 0
core/tauri/src/endpoints/operating_system.rs

@@ -0,0 +1,40 @@
+// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-License-Identifier: MIT
+
+use super::InvokeResponse;
+use serde::Deserialize;
+
+/// The API descriptor.
+#[derive(Deserialize)]
+#[serde(tag = "cmd", rename_all = "camelCase")]
+pub enum Cmd {
+  Platform,
+  Version,
+  Type,
+  Arch,
+  Tempdir,
+}
+
+impl Cmd {
+  #[allow(unused_variables)]
+  pub fn run(self) -> crate::Result<InvokeResponse> {
+    #[cfg(os_all)]
+    return match self {
+      Self::Platform => Ok(std::env::consts::OS.into()),
+      Self::Version => Ok(os_info::get().version().to_string().into()),
+      Self::Type => {
+        #[cfg(target_os = "linux")]
+        return Ok("Linux".into());
+        #[cfg(target_os = "windows")]
+        return Ok("Windows_NT".into());
+        #[cfg(target_os = "macos")]
+        return Ok("Darwing".into());
+      }
+      Self::Arch => Ok(std::env::consts::ARCH.into()),
+      Self::Tempdir => Ok(std::env::temp_dir().into()),
+    };
+    #[cfg(not(os_all))]
+    Err(crate::Error::ApiNotAllowlisted("os".into()))
+  }
+}

+ 8 - 18
tooling/api/rollup.config.js

@@ -3,6 +3,7 @@
 // SPDX-License-Identifier: MIT
 
 // rollup.config.js
+import { readdirSync } from 'fs'
 import { terser } from 'rollup-plugin-terser'
 import resolve from '@rollup/plugin-node-resolve'
 import commonjs from '@rollup/plugin-commonjs'
@@ -13,24 +14,13 @@ import pkg from './package.json'
 
 export default [
   {
-    input: {
-      app: './src/app.ts',
-      fs: './src/fs.ts',
-      path: './src/path.ts',
-      dialog: './src/dialog.ts',
-      event: './src/event.ts',
-      updater: './src/updater.ts',
-      http: './src/http.ts',
-      index: './src/index.ts',
-      shell: './src/shell.ts',
-      tauri: './src/tauri.ts',
-      window: './src/window.ts',
-      cli: './src/cli.ts',
-      notification: './src/notification.ts',
-      globalShortcut: './src/globalShortcut.ts',
-      process: './src/process.ts',
-      clipboard: './src/clipboard.ts'
-    },
+    input: (() => {
+      let input = {}
+      readdirSync('src')
+        .filter((e) => e.endsWith('.ts') && e !== 'bundle.ts')
+        .forEach((mod) => (input[`${mod.replace('.ts', '')}`] = `./src/${mod}`))
+      return input
+    })(),
     treeshake: true,
     perf: true,
     output: [

+ 7 - 14
tooling/api/scripts/after-build.cjs

@@ -5,14 +5,11 @@
 const { readFileSync, readdirSync, writeFileSync, copyFileSync } = require('fs')
 const { copySync } = require('fs-extra')
 
-/**
- * append our api modules to `exports` in `package.json` then write it to `./dist`
- */
+// append our api modules to `exports` in `package.json` then write it to `./dist`
 const pkg = JSON.parse(readFileSync('package.json', 'utf8'))
-const modules = readdirSync('src').map((mod) => mod.replace('.ts', ''))
-if (!pkg.exports) {
-  pkg.exports = {}
-}
+const modules = readdirSync('src')
+  .filter((e) => e !== 'helpers')
+  .map((mod) => mod.replace('.ts', ''))
 
 const outputPkg = {
   ...pkg,
@@ -33,14 +30,12 @@ const outputPkg = {
     }),
     // if for some reason in the future we manually add something in the `exports` field
     // this will ensure it doesn't get overwritten by the logic above
-    { ...pkg.exports }
+    { ...(pkg.exports || {}) }
   )
 }
 writeFileSync('dist/package.json', JSON.stringify(outputPkg, undefined, 2))
 
-/**
- * copy necessary files like `CHANGELOG.md` , `README.md` and Licenses to `./dist`
- */
+// copy necessary files like `CHANGELOG.md` , `README.md` and Licenses to `./dist`
 const dir = readdirSync('.')
 const files = [
   ...dir.filter((f) => f.startsWith('LICENSE')),
@@ -48,7 +43,5 @@ const files = [
 ]
 files.forEach((f) => copyFileSync(f, `dist/${f}`))
 
-/**
- * copy typescript src files to `./dist`
- */
+// copy typescript src files to `./dist`
 copySync('src', 'dist')

+ 2 - 0
tooling/api/src/bundle.ts

@@ -20,6 +20,7 @@ import * as shell from './shell'
 import * as tauri from './tauri'
 import * as updater from './updater'
 import * as window from './window'
+import * as os from './os'
 const invoke = tauri.invoke
 
 export {
@@ -38,5 +39,6 @@ export {
   tauri,
   updater,
   window,
+  os,
   invoke
 }

+ 19 - 0
tooling/api/src/helpers/os-check.ts

@@ -0,0 +1,19 @@
+// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-License-Identifier: MIT
+
+/** @ignore */ 
+
+function isLinux(): boolean {
+  return navigator.appVersion.includes('Linux')
+}
+
+function isWindows(): boolean {
+  return navigator.appVersion.includes('Win')
+}
+
+function isMacOS(): boolean {
+  return navigator.appVersion.includes('Mac')
+}
+
+export { isLinux, isWindows, isMacOS }

+ 1 - 0
tooling/api/src/helpers/tauri.ts

@@ -9,6 +9,7 @@ import { invoke } from '../tauri'
 type TauriModule =
   | 'App'
   | 'Fs'
+  | 'Os'
   | 'Window'
   | 'Shell'
   | 'Event'

+ 97 - 0
tooling/api/src/os.ts

@@ -0,0 +1,97 @@
+// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-License-Identifier: MIT
+
+/**
+ * Provides operating system-related utility methods and properties.
+ *
+ * This package is also accessible with `window.__TAURI__.fs` when `tauri.conf.json > build > withGlobalTauri` is set to true.
+ *
+ * The APIs must be allowlisted on `tauri.conf.json`:
+ * ```json
+ * {
+ *   "tauri": {
+ *     "allowlist": {
+ *       "os": {
+ *         "all": true, // enable all Os APIs
+ *       }
+ *     }
+ *   }
+ * }
+ * ```
+ * It is recommended to allowlist only the APIs you use for optimal bundle size and security.
+ * @module
+ */
+
+import { isWindows } from './helpers/os-check'
+import { invokeTauriCommand } from './helpers/tauri'
+
+/**
+ * The operating system-specific end-of-line marker.
+ * - `\n` on POSIX
+ * - `\r\n` on Windows
+ * */
+const EOL = isWindows() ? '\r\n' : '\n'
+
+/**
+ * Returns a string identifying the operating system platform.
+ * The value is set at compile time. Possible values are `'aix'`, `'darwin'`, `'freebsd'`, `'linux'`, `'openbsd'`, `'sunos'`, and `'win32'`.
+ */
+async function platform(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Os',
+    message: {
+      cmd: 'platform'
+    }
+  })
+}
+
+/**
+ * Returns a string identifying the kernel version.
+ */
+async function version(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Os',
+    message: {
+      cmd: 'version'
+    }
+  })
+}
+
+/**
+ * Returns `'Linux'` on Linux, `'Darwin'` on macOS, and `'Windows_NT'` on Windows.
+ */
+async function type(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Os',
+    message: {
+      cmd: 'type'
+    }
+  })
+}
+
+/**
+ * Returns the operating system CPU architecture for which the tauri app was compiled. Possible values are `'x86'`, `'x86_64'`, `'arm'`, `'aarch64'`, `'mips'`, `'mips64'`, `'powerpc'`, `'powerpc64'`, `'riscv64'`, `'s390x'`, `'sparc64'`
+ */
+async function arch(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Os',
+    message: {
+      cmd: 'arch'
+    }
+  })
+}
+
+/**
+ * Returns the operating system's default directory for temporary files as a string.
+ */
+async function tempdir(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Os',
+    message: {
+      cmd: 'tempdir'
+    }
+  })
+}
+
+export { EOL, platform, version, type, arch, tempdir }

部分文件因文件數量過多而無法顯示