mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-18 05:37:43 +01:00
Compare commits
121 Commits
v2024.12.0
...
v2025.1.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdb4331032 | ||
|
|
8d645eb8c6 | ||
|
|
592cf38e38 | ||
|
|
ac0ecb342d | ||
|
|
439a29ab46 | ||
|
|
db64b54c79 | ||
|
|
49f5e980de | ||
|
|
658e2179ca | ||
|
|
e7184e4d47 | ||
|
|
6719573b2b | ||
|
|
4479164321 | ||
|
|
4295a09515 | ||
|
|
bb5da84c82 | ||
|
|
72ab3f0a3c | ||
|
|
eea87ac02f | ||
|
|
587667fe79 | ||
|
|
84c3987c34 | ||
|
|
40a77be556 | ||
|
|
d37cfad862 | ||
|
|
34c0449a40 | ||
|
|
ad4d695b75 | ||
|
|
969e1b965d | ||
|
|
88ff7f4300 | ||
|
|
8cd9c031e8 | ||
|
|
806ce2f0ba | ||
|
|
dcb17c3ed4 | ||
|
|
d2936cb022 | ||
|
|
ba330047ca | ||
|
|
295aea4f2e | ||
|
|
476dbc432b | ||
|
|
8dff75ad4f | ||
|
|
88b410bf99 | ||
|
|
3d3ff2824f | ||
|
|
3b56f4e142 | ||
|
|
576340db33 | ||
|
|
bcf5b3db84 | ||
|
|
8b5b66acf0 | ||
|
|
f694456ddc | ||
|
|
0a7257c55a | ||
|
|
328e3db56e | ||
|
|
cbc443075a | ||
|
|
37671a50f2 | ||
|
|
95266a9177 | ||
|
|
eeb66ca28a | ||
|
|
d745e91f80 | ||
|
|
7a9c2e2223 | ||
|
|
1d51bd642a | ||
|
|
1920f720a9 | ||
|
|
81005165f3 | ||
|
|
3cf372c01e | ||
|
|
2f7b66fc92 | ||
|
|
4776bbc753 | ||
|
|
79f668c863 | ||
|
|
a164875104 | ||
|
|
bc50891edb | ||
|
|
806a8eb801 | ||
|
|
ab55c2e0ce | ||
|
|
c2ea2a5fe5 | ||
|
|
c72180bb59 | ||
|
|
17fdd608d1 | ||
|
|
40adce921b | ||
|
|
75ead9cc8a | ||
|
|
609bd4cdea | ||
|
|
68e1b5d746 | ||
|
|
53f5ef3515 | ||
|
|
592c1228f1 | ||
|
|
36cecb2d29 | ||
|
|
31440eea76 | ||
|
|
6ad27c4458 | ||
|
|
0dd09062e3 | ||
|
|
5ebf7dc499 | ||
|
|
42cd4a5f0f | ||
|
|
add39bda6e | ||
|
|
be938a81dc | ||
|
|
4b807f221b | ||
|
|
80119f6574 | ||
|
|
dfca17f9b7 | ||
|
|
135c366e32 | ||
|
|
31f2bff0f6 | ||
|
|
61d094d9fd | ||
|
|
c1d5881167 | ||
|
|
dd8ccfe21f | ||
|
|
b4b29babfd | ||
|
|
ecabe9b6ef | ||
|
|
ec999015ab | ||
|
|
51a11b6495 | ||
|
|
27134a52ad | ||
|
|
42bf016e90 | ||
|
|
833dc7d3f7 | ||
|
|
42d350ef27 | ||
|
|
a81f9d07cb | ||
|
|
cb6e3d4ac8 | ||
|
|
5ff5d6fb1d | ||
|
|
e2253786dc | ||
|
|
20140148bf | ||
|
|
4b9dce26ac | ||
|
|
3b2c2960a9 | ||
|
|
a79578142d | ||
|
|
2b61257e50 | ||
|
|
1f4eea89c5 | ||
|
|
1609e46660 | ||
|
|
28d5a2a019 | ||
|
|
40f0f5387a | ||
|
|
88bcfb9e66 | ||
|
|
2b076c90e4 | ||
|
|
0443fbdfdb | ||
|
|
36d24bdac0 | ||
|
|
d4dfc1c820 | ||
|
|
00178ad197 | ||
|
|
f8efd1a31a | ||
|
|
e1363cf151 | ||
|
|
38e0f5ede7 | ||
|
|
9663018e21 | ||
|
|
80a7c2a9c7 | ||
|
|
4687723176 | ||
|
|
41ce2df00c | ||
|
|
794967904a | ||
|
|
74a7a1a21a | ||
|
|
d9587aa314 | ||
|
|
6b208ef67c | ||
|
|
0cfec0ada6 |
@@ -8,14 +8,15 @@ module.exports = {
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'eslint-config-prettier',
|
||||
],
|
||||
plugins: ['react-refresh'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
},
|
||||
ignorePatterns: [
|
||||
'scripts/**/*',
|
||||
'plugin-runtime/**/*',
|
||||
'plugin-runtime-types/**/*',
|
||||
'packages/plugin-runtime/**/*',
|
||||
'packages/plugin-runtime-types/**/*',
|
||||
'src-tauri/**/*',
|
||||
'src-web/tailwind.config.cjs',
|
||||
'src-web/vite.config.ts',
|
||||
@@ -32,6 +33,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'react-refresh/only-export-components': 'error',
|
||||
'jsx-a11y/no-autofocus': 'off',
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
|
||||
43
.github/workflows/release.yml
vendored
43
.github/workflows/release.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- platform: 'macos-latest' # for Intel-based Macs.
|
||||
args: '--target x86_64-apple-darwin'
|
||||
yaak_arch: 'x64'
|
||||
- platform: 'ubuntu-22.04' # for Tauri v1, you could replace this with ubuntu-20.04.
|
||||
- platform: 'ubuntu-22.04'
|
||||
args: ''
|
||||
yaak_arch: 'x64'
|
||||
- platform: 'windows-latest'
|
||||
@@ -38,10 +38,6 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
|
||||
- name: install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
@@ -56,7 +52,7 @@ jobs:
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
src-tauri/target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
|
||||
@@ -66,6 +62,10 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: install dependencies (windows only)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: cargo install --force trusted-signing-cli
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: |
|
||||
npm ci
|
||||
@@ -76,6 +76,9 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run JS build
|
||||
run: npm run build
|
||||
|
||||
- name: Run lint
|
||||
run: npm run lint
|
||||
|
||||
@@ -94,20 +97,32 @@ jobs:
|
||||
env:
|
||||
YAAK_PLUGINS_DIR: ${{ env.YAAK_PLUGINS_DIR }}
|
||||
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
|
||||
|
||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
|
||||
# Apple signing stuff
|
||||
APPLE_CERTIFICATE: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_ID: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_SIGNING_IDENTITY }}
|
||||
APPLE_TEAM_ID: ${{ matrix.platform == 'macos-latest' && secrets.APPLE_TEAM_ID }}
|
||||
|
||||
# Windows signing stuff
|
||||
AZURE_CLIENT_ID: ${{ matrix.platform == 'windows-latest' && secrets.AZURE_CLIENT_ID }}
|
||||
AZURE_CLIENT_SECRET: ${{ matrix.platform == 'windows-latest' && secrets.AZURE_CLIENT_SECRET }}
|
||||
AZURE_TENANT_ID: ${{ matrix.platform == 'windows-latest' && secrets.AZURE_TENANT_ID }}
|
||||
with:
|
||||
tagName: 'v__VERSION__'
|
||||
releaseName: 'Release __VERSION__'
|
||||
releaseBody: 'https://yaak.app/blog/__VERSION__'
|
||||
releaseBody: |
|
||||
> [!IMPORTANT]
|
||||
> The Yaak project is open source. However, to fund development, these pre-built binaries require a license for commercial use. Please see the [Pricing Page](https://yaak.app/pricing) for more details.
|
||||
|
||||
You can view the full release notes here → https://yaak.app/blog/2024.13.0
|
||||
releaseDraft: true
|
||||
prerelease: false
|
||||
args: ${{ matrix.args }}
|
||||
|
||||
10
README.md
10
README.md
@@ -11,10 +11,16 @@ All feedback, bug reports, questions, and feature requests should be reported to
|
||||
[feedback.yaak.app](https://feedback.yaak.app). Issues will be duplicated
|
||||
in this repository if applicable.
|
||||
|
||||
## Community Projects
|
||||
|
||||
- [`yaak2postman`](https://github.com/BiteCraft/yaak2postman) CLI for converting Yaak data
|
||||
exports to Postman-compatible collections
|
||||
|
||||
## Contribution Policy
|
||||
|
||||
Yaak open source, but only accepting contributions for bug fixes. See the
|
||||
Yaak is open source, but only accepting contributions for bug fixes. See the
|
||||
[`good first issue`](https://github.com/yaakapp/app/labels/good%20first%20issue) label for
|
||||
issues that are more approachable for contribution.
|
||||
|
||||
To get started, visit [`DEVELOPMENT.md`](DEVELOPMENT.md) for tips on setting up your environment.
|
||||
To get started, visit [`DEVELOPMENT.md`](DEVELOPMENT.md) for tips on setting up your
|
||||
environment.
|
||||
|
||||
3341
package-lock.json
generated
3341
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
37
package.json
37
package.json
@@ -4,22 +4,25 @@
|
||||
"version": "0.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/yaakapp/app.git"
|
||||
"url": "git+https://github.com/mountain-loop/yaak.git"
|
||||
},
|
||||
"workspaces": [
|
||||
"plugin-runtime",
|
||||
"plugin-runtime-types",
|
||||
"src-tauri/yaak_models",
|
||||
"src-tauri/yaak_plugin_runtime",
|
||||
"src-tauri/yaak_sync",
|
||||
"src-tauri/yaak_templates",
|
||||
"src-tauri/yaak_sse",
|
||||
"packages/plugin-runtime",
|
||||
"packages/plugin-runtime-types",
|
||||
"packages/common-lib",
|
||||
"src-tauri/yaak-license",
|
||||
"src-tauri/yaak-models",
|
||||
"src-tauri/yaak-plugins",
|
||||
"src-tauri/yaak-sse",
|
||||
"src-tauri/yaak-sync",
|
||||
"src-tauri/yaak-templates",
|
||||
"src-web"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "npm run app-dev",
|
||||
"app-build": "tauri build",
|
||||
"app-dev": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
|
||||
"build": "npm run --workspaces --if-present build",
|
||||
"bootstrap": "run-p bootstrap:* && npm run --workspaces --if-present bootstrap",
|
||||
"bootstrap:vendor-node": "node scripts/vendor-node.cjs",
|
||||
"bootstrap:vendor-plugins": "node scripts/vendor-plugins.cjs",
|
||||
@@ -31,18 +34,18 @@
|
||||
"tauri-before-dev": "npm run --workspaces --if-present dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.5.0",
|
||||
"@typescript-eslint/parser": "^8.5.0",
|
||||
"@tauri-apps/cli": "^2.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.18.1",
|
||||
"@typescript-eslint/parser": "^8.18.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-prettier": "^8",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-react": "^7.35.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"nodejs-file-downloader": "^4.13.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "^5.6.2"
|
||||
"prettier": "^3.4.2",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/common-lib/index.ts
Normal file
1
packages/common-lib/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './debounce';
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@yaakapp-internal/plugin",
|
||||
"name": "@yaakapp-internal/lib",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "index.ts"
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@yaakapp/api",
|
||||
"version": "0.2.16",
|
||||
"version": "0.2.17",
|
||||
"main": "lib/index.js",
|
||||
"typings": "./lib/index.d.ts",
|
||||
"files": [
|
||||
@@ -11,8 +11,8 @@
|
||||
"build": "run-s build:copy-types build:tsc",
|
||||
"build:tsc": "tsc",
|
||||
"build:copy-types": "run-p build:copy-types:*",
|
||||
"build:copy-types:root": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/*.ts ./src/bindings",
|
||||
"build:copy-types:next": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/serde_json/*.ts ./src/bindings/serde_json",
|
||||
"build:copy-types:root": "cpy --flat ../../src-tauri/yaak-plugin-runtime/bindings/*.ts ./src/bindings",
|
||||
"build:copy-types:next": "cpy --flat ../../src-tauri/yaak-plugin-runtime/bindings/serde_json/*.ts ./src/bindings/serde_json",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
338
packages/plugin-runtime-types/src/bindings/events.ts
Normal file
338
packages/plugin-runtime-types/src/bindings/events.ts
Normal file
@@ -0,0 +1,338 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type {
|
||||
Environment,
|
||||
Folder,
|
||||
GrpcRequest,
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
Workspace,
|
||||
} from './models';
|
||||
import type { JsonValue } from './serde_json/JsonValue';
|
||||
|
||||
export type BootRequest = { dir: string; watch: boolean };
|
||||
|
||||
export type BootResponse = { name: string; version: string; capabilities: Array<string> };
|
||||
|
||||
export type CallHttpRequestActionArgs = { httpRequest: HttpRequest };
|
||||
|
||||
export type CallHttpRequestActionRequest = {
|
||||
key: string;
|
||||
pluginRefId: string;
|
||||
args: CallHttpRequestActionArgs;
|
||||
};
|
||||
|
||||
export type CallTemplateFunctionArgs = {
|
||||
purpose: RenderPurpose;
|
||||
values: { [key in string]?: string };
|
||||
};
|
||||
|
||||
export type CallTemplateFunctionRequest = { name: string; args: CallTemplateFunctionArgs };
|
||||
|
||||
export type CallTemplateFunctionResponse = { value: string | null };
|
||||
|
||||
export type Color =
|
||||
| 'custom'
|
||||
| 'default'
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'info'
|
||||
| 'success'
|
||||
| 'notice'
|
||||
| 'warning'
|
||||
| 'danger';
|
||||
|
||||
export type CopyTextRequest = { text: string };
|
||||
|
||||
export type ExportHttpRequestRequest = { httpRequest: HttpRequest };
|
||||
|
||||
export type ExportHttpRequestResponse = { content: string };
|
||||
|
||||
export type FilterRequest = { content: string; filter: string };
|
||||
|
||||
export type FilterResponse = { content: string };
|
||||
|
||||
export type FindHttpResponsesRequest = { requestId: string; limit?: number };
|
||||
|
||||
export type FindHttpResponsesResponse = { httpResponses: Array<HttpResponse> };
|
||||
|
||||
export type GetHttpRequestActionsRequest = Record<string, never>;
|
||||
|
||||
export type GetHttpRequestActionsResponse = {
|
||||
actions: Array<HttpRequestAction>;
|
||||
pluginRefId: string;
|
||||
};
|
||||
|
||||
export type GetHttpRequestByIdRequest = { id: string };
|
||||
|
||||
export type GetHttpRequestByIdResponse = { httpRequest: HttpRequest | null };
|
||||
|
||||
export type GetTemplateFunctionsResponse = {
|
||||
functions: Array<TemplateFunction>;
|
||||
pluginRefId: string;
|
||||
};
|
||||
|
||||
export type HttpRequestAction = { key: string; label: string; icon?: Icon };
|
||||
|
||||
export type Icon = 'copy' | 'info' | 'check_circle' | 'alert_triangle' | '_unknown';
|
||||
|
||||
export type ImportRequest = { content: string };
|
||||
|
||||
export type ImportResources = {
|
||||
workspaces: Array<Workspace>;
|
||||
environments: Array<Environment>;
|
||||
folders: Array<Folder>;
|
||||
httpRequests: Array<HttpRequest>;
|
||||
grpcRequests: Array<GrpcRequest>;
|
||||
};
|
||||
|
||||
export type ImportResponse = { resources: ImportResources };
|
||||
|
||||
export type InternalEvent = {
|
||||
id: string;
|
||||
pluginRefId: string;
|
||||
replyId: string | null;
|
||||
payload: InternalEventPayload;
|
||||
windowContext: WindowContext;
|
||||
};
|
||||
|
||||
export type InternalEventPayload =
|
||||
| ({ type: 'boot_request' } & BootRequest)
|
||||
| ({ type: 'boot_response' } & BootResponse)
|
||||
| { type: 'reload_request' }
|
||||
| { type: 'reload_response' }
|
||||
| { type: 'terminate_request' }
|
||||
| { type: 'terminate_response' }
|
||||
| ({ type: 'import_request' } & ImportRequest)
|
||||
| ({ type: 'import_response' } & ImportResponse)
|
||||
| ({ type: 'filter_request' } & FilterRequest)
|
||||
| ({ type: 'filter_response' } & FilterResponse)
|
||||
| ({ type: 'export_http_request_request' } & ExportHttpRequestRequest)
|
||||
| ({ type: 'export_http_request_response' } & ExportHttpRequestResponse)
|
||||
| ({ type: 'send_http_request_request' } & SendHttpRequestRequest)
|
||||
| ({ type: 'send_http_request_response' } & SendHttpRequestResponse)
|
||||
| ({ type: 'get_http_request_actions_request' } & GetHttpRequestActionsRequest)
|
||||
| ({ type: 'get_http_request_actions_response' } & GetHttpRequestActionsResponse)
|
||||
| ({ type: 'call_http_request_action_request' } & CallHttpRequestActionRequest)
|
||||
| { type: 'get_template_functions_request' }
|
||||
| ({ type: 'get_template_functions_response' } & GetTemplateFunctionsResponse)
|
||||
| ({ type: 'call_template_function_request' } & CallTemplateFunctionRequest)
|
||||
| ({ type: 'call_template_function_response' } & CallTemplateFunctionResponse)
|
||||
| ({ type: 'copy_text_request' } & CopyTextRequest)
|
||||
| ({ type: 'render_http_request_request' } & RenderHttpRequestRequest)
|
||||
| ({ type: 'render_http_request_response' } & RenderHttpRequestResponse)
|
||||
| ({ type: 'template_render_request' } & TemplateRenderRequest)
|
||||
| ({ type: 'template_render_response' } & TemplateRenderResponse)
|
||||
| ({ type: 'show_toast_request' } & ShowToastRequest)
|
||||
| ({ type: 'prompt_text_request' } & PromptTextRequest)
|
||||
| ({ type: 'prompt_text_response' } & PromptTextResponse)
|
||||
| ({ type: 'get_http_request_by_id_request' } & GetHttpRequestByIdRequest)
|
||||
| ({ type: 'get_http_request_by_id_response' } & GetHttpRequestByIdResponse)
|
||||
| ({ type: 'find_http_responses_request' } & FindHttpResponsesRequest)
|
||||
| ({ type: 'find_http_responses_response' } & FindHttpResponsesResponse)
|
||||
| { type: 'empty_response' };
|
||||
|
||||
export type OpenFileFilter = {
|
||||
name: string;
|
||||
/**
|
||||
* File extensions to require
|
||||
*/
|
||||
extensions: Array<string>;
|
||||
};
|
||||
|
||||
export type PromptTextRequest = {
|
||||
id: string;
|
||||
title: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
defaultValue?: string;
|
||||
placeholder?: string;
|
||||
/**
|
||||
* Text to add to the confirmation button
|
||||
*/
|
||||
confirmText?: string;
|
||||
/**
|
||||
* Text to add to the cancel button
|
||||
*/
|
||||
cancelText?: string;
|
||||
/**
|
||||
* Require the user to enter a non-empty value
|
||||
*/
|
||||
require?: boolean;
|
||||
};
|
||||
|
||||
export type PromptTextResponse = { value: string | null };
|
||||
|
||||
export type RenderHttpRequestRequest = { httpRequest: HttpRequest; purpose: RenderPurpose };
|
||||
|
||||
export type RenderHttpRequestResponse = { httpRequest: HttpRequest };
|
||||
|
||||
export type RenderPurpose = 'send' | 'preview';
|
||||
|
||||
export type SendHttpRequestRequest = { httpRequest: HttpRequest };
|
||||
|
||||
export type SendHttpRequestResponse = { httpResponse: HttpResponse };
|
||||
|
||||
export type ShowToastRequest = { message: string; color?: Color; icon?: Icon };
|
||||
|
||||
export type TemplateFunction = {
|
||||
name: string;
|
||||
description?: string;
|
||||
/**
|
||||
* Also support alternative names. This is useful for not breaking existing
|
||||
* tags when changing the `name` property
|
||||
*/
|
||||
aliases?: Array<string>;
|
||||
args: Array<TemplateFunctionArg>;
|
||||
};
|
||||
|
||||
export type TemplateFunctionArg =
|
||||
| ({ type: 'text' } & TemplateFunctionTextArg)
|
||||
| ({
|
||||
type: 'select';
|
||||
} & TemplateFunctionSelectArg)
|
||||
| ({ type: 'checkbox' } & TemplateFunctionCheckboxArg)
|
||||
| ({
|
||||
type: 'http_request';
|
||||
} & TemplateFunctionHttpRequestArg)
|
||||
| ({ type: 'file' } & TemplateFunctionFileArg);
|
||||
|
||||
export type TemplateFunctionBaseArg = {
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateFunctionCheckboxArg = {
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateFunctionFileArg = {
|
||||
/**
|
||||
* The title of the file selection window
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Allow selecting multiple files
|
||||
*/
|
||||
multiple?: boolean;
|
||||
directory?: boolean;
|
||||
defaultPath?: string;
|
||||
filters?: Array<OpenFileFilter>;
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateFunctionHttpRequestArg = {
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateFunctionSelectArg = {
|
||||
/**
|
||||
* The options that will be available in the select input
|
||||
*/
|
||||
options: Array<TemplateFunctionSelectOption>;
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateFunctionSelectOption = { label: string; value: string };
|
||||
|
||||
export type TemplateFunctionTextArg = {
|
||||
/**
|
||||
* Placeholder for the text input
|
||||
*/
|
||||
placeholder?: string;
|
||||
/**
|
||||
* The name of the argument. Should be `camelCase` format
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether the user must fill in the argument
|
||||
*/
|
||||
optional?: boolean;
|
||||
/**
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* The default value
|
||||
*/
|
||||
defaultValue?: string;
|
||||
};
|
||||
|
||||
export type TemplateRenderRequest = { data: JsonValue; purpose: RenderPurpose };
|
||||
|
||||
export type TemplateRenderResponse = { data: JsonValue };
|
||||
|
||||
export type WindowContext = { type: 'none' } | { type: 'label'; label: string };
|
||||
@@ -1,16 +1,16 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
|
||||
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, };
|
||||
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, sortPriority: number, };
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, };
|
||||
|
||||
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, };
|
||||
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, description: string, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, description: string, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
|
||||
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, };
|
||||
|
||||
@@ -22,4 +22,4 @@ export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||
|
||||
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, };
|
||||
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
@@ -1,4 +1,4 @@
|
||||
import {
|
||||
import type {
|
||||
FindHttpResponsesRequest,
|
||||
FindHttpResponsesResponse,
|
||||
GetHttpRequestByIdRequest,
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Context } from './Context';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type FilterPluginResponse = string[];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CallHttpRequestActionArgs, HttpRequestAction } from '..';
|
||||
import { Context } from './Context';
|
||||
import type { CallHttpRequestActionArgs, HttpRequestAction } from '..';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type HttpRequestActionPlugin = HttpRequestAction & {
|
||||
onSelect(ctx: Context, args: CallHttpRequestActionArgs): Promise<void> | void;
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Environment, Folder, HttpRequest, Workspace } from '..';
|
||||
import { AtLeast } from '../helpers';
|
||||
import { Context } from './Context';
|
||||
import type { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '..';
|
||||
import type { AtLeast } from '../helpers';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type ImportPluginResponse = null | {
|
||||
workspaces: AtLeast<Workspace, 'name' | 'id' | 'model'>[];
|
||||
environments: AtLeast<Environment, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||
httpRequests: AtLeast<HttpRequest, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||
httpRequests: AtLeast<HttpRequest, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||
grpcRequests: AtLeast<GrpcRequest, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||
};
|
||||
|
||||
export type ImporterPlugin = {
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CallTemplateFunctionArgs, TemplateFunction } from '..';
|
||||
import { Context } from './Context';
|
||||
import type { CallTemplateFunctionArgs, TemplateFunction } from '..';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type TemplateFunctionPlugin = TemplateFunction & {
|
||||
onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise<string | null>;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Theme } from '../themes';
|
||||
import { Context } from './Context';
|
||||
import type { Theme } from '../themes';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type ThemePlugin = {
|
||||
name: string;
|
||||
@@ -1,8 +1,8 @@
|
||||
import { FilterPlugin } from './FilterPlugin';
|
||||
import { HttpRequestActionPlugin } from './HttpRequestActionPlugin';
|
||||
import { ImporterPlugin } from './ImporterPlugin';
|
||||
import { TemplateFunctionPlugin } from './TemplateFunctionPlugin';
|
||||
import { ThemePlugin } from './ThemePlugin';
|
||||
import type { FilterPlugin } from './FilterPlugin';
|
||||
import type { HttpRequestActionPlugin } from './HttpRequestActionPlugin';
|
||||
import type { ImporterPlugin } from './ImporterPlugin';
|
||||
import type { TemplateFunctionPlugin } from './TemplateFunctionPlugin';
|
||||
import type { ThemePlugin } from './ThemePlugin';
|
||||
|
||||
export type { Context } from './Context';
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"scripts": {
|
||||
"bootstrap": "npm run build",
|
||||
"build": "run-p build:*",
|
||||
"build:main": "esbuild src/index.ts --bundle --platform=node --outfile=../src-tauri/vendored/plugin-runtime/index.cjs",
|
||||
"build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=../src-tauri/vendored/plugin-runtime/index.worker.cjs",
|
||||
"build:proto": "grpc_tools_node_protoc --ts_proto_out=src/gen --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false --proto_path=../proto ../proto/plugins/*.proto"
|
||||
"build:main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.cjs",
|
||||
"build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.worker.cjs",
|
||||
"build:proto": "grpc_tools_node_protoc --ts_proto_out=src/gen --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false --proto_path=../../proto ../../proto/plugins/*.proto"
|
||||
},
|
||||
"dependencies": {
|
||||
"intercept-stdout": "^0.1.2",
|
||||
@@ -1,6 +1,6 @@
|
||||
import { InternalEvent } from '@yaakapp/api';
|
||||
import type { InternalEvent } from '@yaakapp/api';
|
||||
import EventEmitter from 'node:events';
|
||||
import { EventStreamEvent } from './gen/plugins/runtime';
|
||||
import type { EventStreamEvent } from './gen/plugins/runtime';
|
||||
|
||||
export class EventChannel {
|
||||
emitter: EventEmitter = new EventEmitter();
|
||||
@@ -1,8 +1,8 @@
|
||||
import { BootRequest, InternalEvent } from '@yaakapp-internal/plugin';
|
||||
import type { BootRequest, InternalEvent } from '@yaakapp-internal/plugins';
|
||||
import path from 'node:path';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
import { EventChannel } from './EventChannel';
|
||||
import { PluginWorkerData } from './index.worker';
|
||||
import type { EventChannel } from './EventChannel';
|
||||
import type { PluginWorkerData } from './index.worker';
|
||||
|
||||
export class PluginHandle {
|
||||
#worker: Worker;
|
||||
@@ -1,12 +1,16 @@
|
||||
import { InternalEvent } from '@yaakapp/api';
|
||||
import type { InternalEvent } from '@yaakapp/api';
|
||||
import { createChannel, createClient, Status } from 'nice-grpc';
|
||||
import { EventChannel } from './EventChannel';
|
||||
import { PluginRuntimeClient, PluginRuntimeDefinition } from './gen/plugins/runtime';
|
||||
import type { PluginRuntimeClient} from './gen/plugins/runtime';
|
||||
import { PluginRuntimeDefinition } from './gen/plugins/runtime';
|
||||
import { PluginHandle } from './PluginHandle';
|
||||
|
||||
const port = process.env.PORT || '50051';
|
||||
|
||||
const channel = createChannel(`localhost:${port}`);
|
||||
const channel = createChannel(`localhost:${port}`, undefined, {
|
||||
'grpc.max_receive_message_length': Number.MAX_SAFE_INTEGER,
|
||||
'grpc.max_send_message_length': Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
const client: PluginRuntimeClient = createClient(PluginRuntimeDefinition, channel);
|
||||
|
||||
const events = new EventChannel();
|
||||
@@ -1,4 +1,4 @@
|
||||
import {
|
||||
import type {
|
||||
BootRequest,
|
||||
FindHttpResponsesResponse,
|
||||
GetHttpRequestByIdResponse,
|
||||
@@ -12,13 +12,14 @@ import {
|
||||
TemplateFunction,
|
||||
TemplateRenderResponse,
|
||||
WindowContext,
|
||||
} from '@yaakapp-internal/plugin';
|
||||
import { Context } from '@yaakapp/api';
|
||||
import { HttpRequestActionPlugin } from '@yaakapp/api/lib/plugins/HttpRequestActionPlugin';
|
||||
import { TemplateFunctionPlugin } from '@yaakapp/api/lib/plugins/TemplateFunctionPlugin';
|
||||
} from '@yaakapp-internal/plugins';
|
||||
import type { Context } from '@yaakapp/api';
|
||||
import type { HttpRequestActionPlugin } from '@yaakapp/api/lib/plugins/HttpRequestActionPlugin';
|
||||
import type { TemplateFunctionPlugin } from '@yaakapp/api/lib/plugins/TemplateFunctionPlugin';
|
||||
import interceptStdout from 'intercept-stdout';
|
||||
import * as console from 'node:console';
|
||||
import { readFileSync, Stats, statSync, watch } from 'node:fs';
|
||||
import type { Stats} from 'node:fs';
|
||||
import { readFileSync, statSync, watch } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import * as util from 'node:util';
|
||||
import { parentPort, workerData } from 'node:worker_threads';
|
||||
@@ -200,7 +201,7 @@ async function initialize() {
|
||||
|
||||
// Message comes into the plugin to be processed
|
||||
parentPort!.on('message', async (event: InternalEvent) => {
|
||||
let { windowContext, payload, id: replyId } = event;
|
||||
const { windowContext, payload, id: replyId } = event;
|
||||
const ctx = newCtx(event);
|
||||
try {
|
||||
if (payload.type === 'boot_request') {
|
||||
@@ -1,10 +1,10 @@
|
||||
const decompress = require('decompress');
|
||||
const Downloader = require('nodejs-file-downloader');
|
||||
const path = require('node:path');
|
||||
const { rmSync, mkdirSync, cpSync, existsSync } = require('node:fs');
|
||||
const { rmSync, mkdirSync, cpSync, existsSync, statSync, chmodSync } = require('node:fs');
|
||||
const { execSync } = require('node:child_process');
|
||||
|
||||
const VERSION = '27.2';
|
||||
const VERSION = '28.3';
|
||||
|
||||
// `${process.platform}_${process.arch}`
|
||||
const MAC_ARM = 'darwin_arm64';
|
||||
@@ -67,6 +67,11 @@ mkdirSync(dstDir, { recursive: true });
|
||||
cpSync(includeSrc, includeDst, { recursive: true });
|
||||
rmSync(tmpDir, { recursive: true, force: true });
|
||||
|
||||
// Make binary writable, so we can sign it during release
|
||||
const stat = statSync(binDst);
|
||||
const newMode = stat.mode | 0o200;
|
||||
chmodSync(binDst, newMode);
|
||||
|
||||
console.log('Downloaded protoc to', binDst);
|
||||
})().catch((err) => console.log('Script failed:', err));
|
||||
|
||||
|
||||
1175
src-tauri/Cargo.lock
generated
1175
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,20 @@
|
||||
[workspace]
|
||||
members = ["yaak_grpc", "yaak_templates", "yaak_plugin_runtime", "yaak_models", "yaak_sse"]
|
||||
members = [
|
||||
"yaak-grpc",
|
||||
"yaak-license",
|
||||
"yaak-models",
|
||||
"yaak-plugins",
|
||||
"yaak-sse",
|
||||
"yaak-sync",
|
||||
"yaak-templates",
|
||||
]
|
||||
|
||||
[package]
|
||||
name = "yaak-app"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
authors = ["Gregory Schier"]
|
||||
publish = false
|
||||
|
||||
# Produce a library for mobile support
|
||||
[lib]
|
||||
@@ -15,8 +24,11 @@ crate-type = ["staticlib", "cdylib", "lib"]
|
||||
[profile.release]
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
||||
[features]
|
||||
cargo-clippy = []
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.0.3", features = [] }
|
||||
tauri-build = { version = "2.0.4", features = [] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc = "0.2.7"
|
||||
@@ -26,46 +38,54 @@ cocoa = "0.26.0"
|
||||
openssl-sys = { version = "0.9", features = ["vendored"] } # For Ubuntu installation to work
|
||||
|
||||
[dependencies]
|
||||
yaak_grpc = { path = "yaak_grpc" }
|
||||
yaak_templates = { path = "yaak_templates" }
|
||||
yaak_plugin_runtime = { workspace = true }
|
||||
yaak_sse = { workspace = true }
|
||||
yaak_models = { workspace = true }
|
||||
base64 = "0.22.0"
|
||||
chrono = { version = "0.4.31", features = ["serde"] }
|
||||
datetime = "0.5.2"
|
||||
eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.13.0" }
|
||||
hex_color = "3.0.0"
|
||||
http = "1"
|
||||
log = "0.4.21"
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.2"
|
||||
reqwest = { version = "0.12.4", features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "native-tls-alpn"] }
|
||||
reqwest = { workspace = true, features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "rustls-tls-manual-roots-no-provider"] }
|
||||
reqwest_cookie_store = "0.8.0"
|
||||
rustls = { version = "0.23.21", default-features = false }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true, features = ["raw_value"] }
|
||||
tauri = { workspace = true, features = ["devtools", "protocol-asset"] }
|
||||
tauri-plugin-clipboard-manager = "2.2.0"
|
||||
tauri-plugin-dialog = "2.2.0"
|
||||
tauri-plugin-fs = "2.2.0"
|
||||
tauri-plugin-log = { version = "2.2.0", features = ["colored"] }
|
||||
tauri-plugin-opener = "2.2.2"
|
||||
tauri-plugin-os = "2.2.0"
|
||||
tauri-plugin-shell = { workspace = true }
|
||||
tauri-plugin-clipboard-manager = "2.0.1"
|
||||
tauri-plugin-dialog = "2.0.3"
|
||||
tauri-plugin-fs = "2.0.3"
|
||||
tauri-plugin-log = { version = "2.0.1", features = ["colored"] }
|
||||
tauri-plugin-os = "2.0.1"
|
||||
tauri-plugin-updater = "2.0.2"
|
||||
tauri-plugin-window-state = "2.0.1"
|
||||
tauri-plugin-single-instance = "2.2.0"
|
||||
tauri-plugin-updater = "2.3.0"
|
||||
tauri-plugin-window-state = "2.2.0"
|
||||
tokio = { version = "1.36.0", features = ["sync"] }
|
||||
tokio-stream = "0.1.15"
|
||||
uuid = "1.7.0"
|
||||
ts-rs = { workspace = true }
|
||||
mime_guess = "2.0.5"
|
||||
urlencoding = "2.1.3"
|
||||
eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.13.0" }
|
||||
uuid = "1.7.0"
|
||||
yaak-grpc = { path = "yaak-grpc" }
|
||||
yaak-license = { path = "yaak-license" }
|
||||
yaak-models = { workspace = true }
|
||||
yaak-plugins = { workspace = true }
|
||||
yaak-sse = { workspace = true }
|
||||
yaak-sync = { path = "yaak-sync" }
|
||||
yaak-templates = { path = "yaak-templates" }
|
||||
|
||||
[workspace.dependencies]
|
||||
yaak_models = { path = "yaak_models" }
|
||||
yaak_sse = { path = "yaak_sse" }
|
||||
yaak_plugin_runtime = { path = "yaak_plugin_runtime" }
|
||||
yaak-models = { path = "yaak-models" }
|
||||
yaak-sse = { path = "yaak-sse" }
|
||||
yaak-plugins = { path = "yaak-plugins" }
|
||||
serde = "1.0.215"
|
||||
serde_json = "1.0.132"
|
||||
tauri-plugin-shell = "2.0.2"
|
||||
tauri = { version = "2.1.1", features = ["devtools", "protocol-asset"] }
|
||||
tauri-plugin-shell = "2.2.0"
|
||||
tauri = "2.2.0"
|
||||
thiserror = "2.0.3"
|
||||
ts-rs = "10.0.0"
|
||||
reqwest = "0.12.12"
|
||||
|
||||
5
src-tauri/bindings/analytics.ts
Normal file
5
src-tauri/bindings/analytics.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type AnalyticsAction = "cancel" | "click" | "commit" | "create" | "delete" | "delete_many" | "duplicate" | "export" | "hide" | "import" | "launch" | "launch_first" | "launch_update" | "send" | "show" | "toggle" | "update" | "upsert";
|
||||
|
||||
export type AnalyticsResource = "app" | "appearance" | "button" | "checkbox" | "cookie_jar" | "dialog" | "environment" | "folder" | "grpc_connection" | "grpc_event" | "grpc_request" | "http_request" | "http_response" | "link" | "key_value" | "plugin" | "select" | "setting" | "sidebar" | "tab" | "theme" | "workspace";
|
||||
@@ -16,6 +16,7 @@
|
||||
"clipboard-manager:allow-read-text",
|
||||
"dialog:allow-open",
|
||||
"dialog:allow-save",
|
||||
"fs:allow-read-dir",
|
||||
"fs:allow-read-file",
|
||||
"fs:allow-read-text-file",
|
||||
{
|
||||
@@ -29,7 +30,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"shell:allow-open",
|
||||
"opener:allow-open-url",
|
||||
"opener:allow-open-path",
|
||||
"opener:allow-default-urls",
|
||||
"opener:allow-reveal-item-in-dir",
|
||||
"core:webview:allow-set-webview-zoom",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-internal-toggle-maximize",
|
||||
@@ -44,6 +48,8 @@
|
||||
"core:window:allow-toggle-maximize",
|
||||
"core:window:allow-unmaximize",
|
||||
"clipboard-manager:allow-read-text",
|
||||
"clipboard-manager:allow-write-text"
|
||||
"clipboard-manager:allow-write-text",
|
||||
"yaak-license:default",
|
||||
"yaak-sync:default"
|
||||
]
|
||||
}
|
||||
|
||||
2
src-tauri/gen/schemas/acl-manifests.json
generated
2
src-tauri/gen/schemas/acl-manifests.json
generated
File diff suppressed because one or more lines are too long
2
src-tauri/gen/schemas/capabilities.json
generated
2
src-tauri/gen/schemas/capabilities.json
generated
@@ -1 +1 @@
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-dir","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"opener:allow-open-url","opener:allow-open-path","opener:allow-default-urls","opener:allow-reveal-item-in-dir","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","yaak-license:default","yaak-sync:default"]}}
|
||||
369
src-tauri/gen/schemas/desktop-schema.json
generated
369
src-tauri/gen/schemas/desktop-schema.json
generated
@@ -140,7 +140,7 @@
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -984,6 +984,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1109,6 +1114,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1581,7 +1591,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1591,7 +1601,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -1605,7 +1615,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1615,7 +1625,167 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "Identifier of the permission or permission set.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Identifier"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"allow": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -2602,6 +2772,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2682,6 +2857,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2897,6 +3077,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2982,6 +3177,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3242,6 +3442,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3327,6 +3542,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3478,7 +3698,7 @@
|
||||
"const": "dialog:deny-save"
|
||||
},
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -4322,6 +4542,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4447,6 +4672,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4922,6 +5152,46 @@
|
||||
"type": "string",
|
||||
"const": "log:deny-log"
|
||||
},
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n",
|
||||
"type": "string",
|
||||
@@ -5141,6 +5411,76 @@
|
||||
"description": "Denies the save_window_state command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "window-state:deny-save-window-state"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-license:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-activate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-check"
|
||||
},
|
||||
{
|
||||
"description": "Denies the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-activate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-check"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-apply"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Enables the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-watch"
|
||||
},
|
||||
{
|
||||
"description": "Denies the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-apply"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Denies the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-watch"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -5238,6 +5578,23 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Application": {
|
||||
"description": "Opener scope application.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Open in default application.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "If true, allow open with any application.",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Allow specific application to open with.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ShellScopeEntryAllowedArg": {
|
||||
"description": "A command argument allowed to be executed by the webview API.",
|
||||
"anyOf": [
|
||||
|
||||
373
src-tauri/gen/schemas/linux-schema.json
generated
373
src-tauri/gen/schemas/linux-schema.json
generated
@@ -37,7 +37,7 @@
|
||||
],
|
||||
"definitions": {
|
||||
"Capability": {
|
||||
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```",
|
||||
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier",
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```",
|
||||
"description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionEntry"
|
||||
@@ -140,7 +140,7 @@
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -984,6 +984,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1109,6 +1114,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1581,7 +1591,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1591,7 +1601,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -1605,7 +1615,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1615,7 +1625,167 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "Identifier of the permission or permission set.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Identifier"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"allow": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -2602,6 +2772,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2682,6 +2857,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2897,6 +3077,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2982,6 +3177,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3242,6 +3442,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3327,6 +3542,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3478,7 +3698,7 @@
|
||||
"const": "dialog:deny-save"
|
||||
},
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -4322,6 +4542,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4447,6 +4672,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4922,6 +5152,46 @@
|
||||
"type": "string",
|
||||
"const": "log:deny-log"
|
||||
},
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n",
|
||||
"type": "string",
|
||||
@@ -5141,6 +5411,76 @@
|
||||
"description": "Denies the save_window_state command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "window-state:deny-save-window-state"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-license:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-activate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-check"
|
||||
},
|
||||
{
|
||||
"description": "Denies the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-activate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-check"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-apply"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Enables the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-watch"
|
||||
},
|
||||
{
|
||||
"description": "Denies the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-apply"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Denies the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-watch"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -5238,6 +5578,23 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Application": {
|
||||
"description": "Opener scope application.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Open in default application.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "If true, allow open with any application.",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Allow specific application to open with.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ShellScopeEntryAllowedArg": {
|
||||
"description": "A command argument allowed to be executed by the webview API.",
|
||||
"anyOf": [
|
||||
|
||||
369
src-tauri/gen/schemas/macOS-schema.json
generated
369
src-tauri/gen/schemas/macOS-schema.json
generated
@@ -140,7 +140,7 @@
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -984,6 +984,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1109,6 +1114,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -1581,7 +1591,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1591,7 +1601,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -1605,7 +1615,7 @@
|
||||
"description": "FS scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs. FS scope path pattern.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@@ -1615,7 +1625,167 @@
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"description": "FS scope path.",
|
||||
"description": "A path that can be accessed by the webview when using the fs APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "Identifier of the permission or permission set.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Identifier"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"allow": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"items": {
|
||||
"title": "OpenerScopeEntry",
|
||||
"description": "Opener scope entry.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this url with, for example: firefox.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"description": "A URL that can be opened by the webview when using the Opener APIs.\n\nWildcards can be used following the UNIX glob pattern.\n\nExamples:\n\n- \"https://*\" : allows all HTTPS origin\n\n- \"https://*.github.com/tauri-apps/tauri\": allows any subdomain of \"github.com\" with the \"tauri-apps/api\" path\n\n- \"https://myapi.service.com/users/*\": allows access to any URLs that begins with \"https://myapi.service.com/users/\"",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"app": {
|
||||
"description": "An application to open this path with, for example: xdg-open.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "A path that can be opened by the webview when using the Opener APIs.\n\nThe pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -2602,6 +2772,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:allow-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2682,6 +2857,11 @@
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-reparent"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:webview:deny-set-webview-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_webview_focus command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2897,6 +3077,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -2982,6 +3177,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:allow-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3242,6 +3442,21 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-always-on-top"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_background_color command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-background-color"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_count command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-count"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_badge_label command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-badge-label"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_closable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3327,6 +3542,11 @@
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-minimizable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_overlay_icon command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "core:window:deny-set-overlay-icon"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_position command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -3478,7 +3698,7 @@
|
||||
"const": "dialog:deny-save"
|
||||
},
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n",
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n",
|
||||
"type": "string",
|
||||
"const": "fs:default"
|
||||
},
|
||||
@@ -4322,6 +4542,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:allow-seek"
|
||||
},
|
||||
{
|
||||
"description": "Enables the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:allow-size"
|
||||
},
|
||||
{
|
||||
"description": "Enables the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4447,6 +4672,11 @@
|
||||
"type": "string",
|
||||
"const": "fs:deny-seek"
|
||||
},
|
||||
{
|
||||
"description": "Denies the size command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "fs:deny-size"
|
||||
},
|
||||
{
|
||||
"description": "Denies the stat command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
@@ -4922,6 +5152,46 @@
|
||||
"type": "string",
|
||||
"const": "log:deny-log"
|
||||
},
|
||||
{
|
||||
"description": "This permission set allows opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application\nas well as reveal file in directories using default file explorer",
|
||||
"type": "string",
|
||||
"const": "opener:default"
|
||||
},
|
||||
{
|
||||
"description": "This enables opening `mailto:`, `tel:`, `https://` and `http://` urls using their default application.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-default-urls"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Enables the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Enables the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:allow-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_path command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-path"
|
||||
},
|
||||
{
|
||||
"description": "Denies the open_url command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-open-url"
|
||||
},
|
||||
{
|
||||
"description": "Denies the reveal_item_in_dir command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "opener:deny-reveal-item-in-dir"
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which\noperating system information are available\nto gather from the frontend.\n\n#### Granted Permissions\n\nAll information except the host name are available.\n\n",
|
||||
"type": "string",
|
||||
@@ -5141,6 +5411,76 @@
|
||||
"description": "Denies the save_window_state command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "window-state:deny-save-window-state"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-license:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-activate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:allow-check"
|
||||
},
|
||||
{
|
||||
"description": "Denies the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-activate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-license:deny-check"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-apply"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Enables the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:allow-watch"
|
||||
},
|
||||
{
|
||||
"description": "Denies the apply command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-apply"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the calculate_fs command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-calculate-fs"
|
||||
},
|
||||
{
|
||||
"description": "Denies the watch command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "yaak-sync:deny-watch"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -5238,6 +5578,23 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Application": {
|
||||
"description": "Opener scope application.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Open in default application.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "If true, allow open with any application.",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Allow specific application to open with.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ShellScopeEntryAllowedArg": {
|
||||
"description": "A command argument allowed to be executed by the webview API.",
|
||||
"anyOf": [
|
||||
|
||||
8
src-tauri/migrations/20241217204951_docs.sql
Normal file
8
src-tauri/migrations/20241217204951_docs.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE http_requests
|
||||
ADD COLUMN description TEXT DEFAULT '' NOT NULL;
|
||||
|
||||
ALTER TABLE grpc_requests
|
||||
ADD COLUMN description TEXT DEFAULT '' NOT NULL;
|
||||
|
||||
ALTER TABLE folders
|
||||
ADD COLUMN description TEXT DEFAULT '' NOT NULL;
|
||||
45
src-tauri/migrations/20241219140051_base-environments.sql
Normal file
45
src-tauri/migrations/20241219140051_base-environments.sql
Normal file
@@ -0,0 +1,45 @@
|
||||
-- Add the new field
|
||||
ALTER TABLE environments
|
||||
ADD COLUMN environment_id TEXT REFERENCES environments (id) ON DELETE CASCADE;
|
||||
|
||||
-- Create temporary column so we know which rows are meant to be base environments. We'll use this to update
|
||||
-- child environments to point to them.
|
||||
ALTER TABLE environments
|
||||
ADD COLUMN migrated_base_env BOOLEAN DEFAULT FALSE NOT NULL;
|
||||
|
||||
-- Create a base environment for each workspace
|
||||
INSERT INTO environments (id, workspace_id, name, variables, migrated_base_env)
|
||||
SELECT (
|
||||
-- This is the best way to generate a random string in SQLite, apparently
|
||||
'ev_' || SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1) ||
|
||||
SUBSTR('abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23457789', (ABS(RANDOM()) % 57) + 1, 1)
|
||||
),
|
||||
workspaces.id,
|
||||
'Global Variables',
|
||||
variables,
|
||||
TRUE
|
||||
FROM workspaces;
|
||||
|
||||
-- Update all non-base environments to point to newly created base environments
|
||||
UPDATE environments
|
||||
SET environment_id = ( SELECT base_env.id
|
||||
FROM environments AS base_env
|
||||
WHERE base_env.workspace_id = environments.workspace_id
|
||||
AND base_env.migrated_base_env IS TRUE )
|
||||
WHERE migrated_base_env IS FALSE;
|
||||
|
||||
-- Drop temporary column
|
||||
ALTER TABLE environments
|
||||
DROP COLUMN migrated_base_env;
|
||||
|
||||
-- Drop the old variables column
|
||||
-- IMPORTANT: Skip to give the user the option to roll back to a previous app version. We can drop it once the migration working in the real world
|
||||
-- ALTER TABLE workspaces DROP COLUMN variables;
|
||||
21
src-tauri/migrations/20250102141937_sync.sql
Normal file
21
src-tauri/migrations/20250102141937_sync.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
ALTER TABLE workspaces
|
||||
ADD COLUMN setting_sync_dir TEXT;
|
||||
|
||||
CREATE TABLE sync_states
|
||||
(
|
||||
id TEXT NOT NULL
|
||||
PRIMARY KEY,
|
||||
model TEXT DEFAULT 'sync_state' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
REFERENCES workspaces
|
||||
ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
flushed_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
model_id TEXT NOT NULL,
|
||||
sync_dir TEXT NOT NULL,
|
||||
rel_path TEXT NOT NULL,
|
||||
|
||||
UNIQUE (workspace_id, model_id)
|
||||
);
|
||||
2
src-tauri/migrations/20250108035425_editor-keymap.sql
Normal file
2
src-tauri/migrations/20250108035425_editor-keymap.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE settings
|
||||
ADD COLUMN editor_keymap TEXT DEFAULT 'codemirror' NOT NULL;
|
||||
11
src-tauri/migrations/20250108205117_workspace-meta.sql
Normal file
11
src-tauri/migrations/20250108205117_workspace-meta.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE workspace_metas
|
||||
(
|
||||
id TEXT NOT NULL
|
||||
PRIMARY KEY,
|
||||
model TEXT DEFAULT 'workspace_meta' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
REFERENCES workspaces ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
setting_sync_dir TEXT
|
||||
);
|
||||
@@ -4,8 +4,11 @@ use log::{debug, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use tauri::{Manager, Runtime, WebviewWindow};
|
||||
|
||||
use yaak_models::queries::{generate_id, get_key_value_int, get_key_value_string, get_or_create_settings, set_key_value_int, set_key_value_string};
|
||||
use ts_rs::TS;
|
||||
use yaak_models::queries::{
|
||||
generate_id, get_key_value_int, get_key_value_string, get_or_create_settings,
|
||||
set_key_value_int, set_key_value_string, UpdateSource,
|
||||
};
|
||||
|
||||
use crate::is_dev;
|
||||
|
||||
@@ -13,11 +16,14 @@ const NAMESPACE: &str = "analytics";
|
||||
const NUM_LAUNCHES_KEY: &str = "num_launches";
|
||||
|
||||
// serializable
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to = "analytics.ts")]
|
||||
pub enum AnalyticsResource {
|
||||
App,
|
||||
Appearance,
|
||||
Button,
|
||||
Checkbox,
|
||||
CookieJar,
|
||||
Dialog,
|
||||
Environment,
|
||||
@@ -27,10 +33,13 @@ pub enum AnalyticsResource {
|
||||
GrpcRequest,
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
Link,
|
||||
KeyValue,
|
||||
Plugin,
|
||||
Select,
|
||||
Setting,
|
||||
Sidebar,
|
||||
Tab,
|
||||
Theme,
|
||||
Workspace,
|
||||
}
|
||||
@@ -43,18 +52,16 @@ impl AnalyticsResource {
|
||||
|
||||
impl Display for AnalyticsResource {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
serde_json::to_string(self).unwrap().replace("\"", "")
|
||||
)
|
||||
write!(f, "{}", serde_json::to_string(self).unwrap().replace("\"", ""))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to = "analytics.ts")]
|
||||
pub enum AnalyticsAction {
|
||||
Cancel,
|
||||
Click,
|
||||
Commit,
|
||||
Create,
|
||||
Delete,
|
||||
@@ -81,11 +88,7 @@ impl AnalyticsAction {
|
||||
|
||||
impl Display for AnalyticsAction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
serde_json::to_string(self).unwrap().replace("\"", "")
|
||||
)
|
||||
write!(f, "{}", serde_json::to_string(self).unwrap().replace("\"", ""))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +110,7 @@ pub async fn track_launch_event<R: Runtime>(w: &WebviewWindow<R>) -> LaunchEvent
|
||||
info.current_version = w.package_info().version.to_string();
|
||||
|
||||
if info.previous_version.is_empty() {
|
||||
track_event(
|
||||
w,
|
||||
AnalyticsResource::App,
|
||||
AnalyticsAction::LaunchFirst,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
track_event(w, AnalyticsResource::App, AnalyticsAction::LaunchFirst, None).await;
|
||||
} else {
|
||||
info.launched_after_update = info.current_version != info.previous_version;
|
||||
if info.launched_after_update {
|
||||
@@ -143,9 +140,11 @@ pub async fn track_launch_event<R: Runtime>(w: &WebviewWindow<R>) -> LaunchEvent
|
||||
NAMESPACE,
|
||||
last_tracked_version_key,
|
||||
info.current_version.as_str(),
|
||||
&UpdateSource::Background,
|
||||
)
|
||||
.await;
|
||||
set_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches).await;
|
||||
set_key_value_int(w, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches, &UpdateSource::Background)
|
||||
.await;
|
||||
|
||||
info
|
||||
}
|
||||
@@ -156,7 +155,6 @@ pub async fn track_event<R: Runtime>(
|
||||
action: AnalyticsAction,
|
||||
attributes: Option<Value>,
|
||||
) {
|
||||
|
||||
let id = get_id(w).await;
|
||||
let event = format!("{}.{}", resource, action);
|
||||
let attributes_json = attributes.unwrap_or("{}".to_string().into()).to_string();
|
||||
@@ -180,16 +178,13 @@ pub async fn track_event<R: Runtime>(
|
||||
("tz", tz),
|
||||
("xy", get_window_size(w)),
|
||||
];
|
||||
let req = reqwest::Client::builder()
|
||||
.build()
|
||||
.unwrap()
|
||||
.get(format!("{base_url}/t/e"))
|
||||
.query(¶ms);
|
||||
let req =
|
||||
reqwest::Client::builder().build().unwrap().get(format!("{base_url}/t/e")).query(¶ms);
|
||||
|
||||
let settings = get_or_create_settings(w).await;
|
||||
if !settings.telemetry {
|
||||
info!("Track event (disabled): {}", event);
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable analytics actual sending in dev
|
||||
@@ -226,18 +221,15 @@ fn get_window_size<R: Runtime>(w: &WebviewWindow<R>) -> String {
|
||||
let width: f64 = size.width as f64 / scale_factor;
|
||||
let height: f64 = size.height as f64 / scale_factor;
|
||||
|
||||
format!(
|
||||
"{}x{}",
|
||||
(width / 100.0).round() * 100.0,
|
||||
(height / 100.0).round() * 100.0
|
||||
)
|
||||
format!("{}x{}", (width / 100.0).round() * 100.0, (height / 100.0).round() * 100.0)
|
||||
}
|
||||
|
||||
async fn get_id<R: Runtime>(w: &WebviewWindow<R>) -> String {
|
||||
let id = get_key_value_string(w, "analytics", "id", "").await;
|
||||
if id.is_empty() {
|
||||
let new_id = generate_id();
|
||||
set_key_value_string(w, "analytics", "id", new_id.as_str()).await;
|
||||
set_key_value_string(w, "analytics", "id", new_id.as_str(), &UpdateSource::Background)
|
||||
.await;
|
||||
new_id
|
||||
} else {
|
||||
id
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{Manager, WebviewWindow};
|
||||
use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, Workspace};
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct WorkspaceExport {
|
||||
pub yaak_version: String,
|
||||
pub yaak_schema: i64,
|
||||
pub timestamp: NaiveDateTime,
|
||||
pub resources: WorkspaceExportResources,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct WorkspaceExportResources {
|
||||
pub workspaces: Vec<Workspace>,
|
||||
pub environments: Vec<Environment>,
|
||||
pub folders: Vec<Folder>,
|
||||
pub http_requests: Vec<HttpRequest>,
|
||||
pub grpc_requests: Vec<GrpcRequest>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
pub struct ImportResult {
|
||||
pub resources: WorkspaceExportResources,
|
||||
}
|
||||
|
||||
pub async fn get_workspace_export_resources(
|
||||
window: &WebviewWindow,
|
||||
workspace_ids: Vec<&str>,
|
||||
) -> WorkspaceExport {
|
||||
let app_handle = window.app_handle();
|
||||
let mut data = WorkspaceExport {
|
||||
yaak_version: app_handle.package_info().version.clone().to_string(),
|
||||
yaak_schema: 2,
|
||||
timestamp: chrono::Utc::now().naive_utc(),
|
||||
resources: WorkspaceExportResources {
|
||||
workspaces: Vec::new(),
|
||||
environments: Vec::new(),
|
||||
folders: Vec::new(),
|
||||
http_requests: Vec::new(),
|
||||
grpc_requests: Vec::new(),
|
||||
},
|
||||
};
|
||||
|
||||
for workspace_id in workspace_ids {
|
||||
data.resources.workspaces.push(
|
||||
yaak_models::queries::get_workspace(window, workspace_id)
|
||||
.await
|
||||
.expect("Failed to get workspace"),
|
||||
);
|
||||
data.resources.environments.append(
|
||||
&mut yaak_models::queries::list_environments(window, workspace_id)
|
||||
.await
|
||||
.expect("Failed to get environments"),
|
||||
);
|
||||
data.resources.folders.append(
|
||||
&mut yaak_models::queries::list_folders(window, workspace_id)
|
||||
.await
|
||||
.expect("Failed to get folders"),
|
||||
);
|
||||
data.resources.http_requests.append(
|
||||
&mut yaak_models::queries::list_http_requests(window, workspace_id)
|
||||
.await
|
||||
.expect("Failed to get http requests"),
|
||||
);
|
||||
data.resources.grpc_requests.append(
|
||||
&mut yaak_models::queries::list_grpc_requests(window, workspace_id)
|
||||
.await
|
||||
.expect("Failed to get grpc requests"),
|
||||
);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -1,9 +1,3 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::render::render_http_request;
|
||||
use crate::response_err;
|
||||
use crate::template_callback::PluginTemplateCallback;
|
||||
@@ -16,7 +10,14 @@ use mime_guess::Mime;
|
||||
use reqwest::redirect::Policy;
|
||||
use reqwest::{multipart, Proxy, Url};
|
||||
use reqwest::{Method, Response};
|
||||
use rustls::ClientConfig;
|
||||
use rustls_platform_verifier::ConfigVerifierExt;
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tauri::{Manager, Runtime, WebviewWindow};
|
||||
use tokio::fs;
|
||||
use tokio::fs::{create_dir_all, File};
|
||||
@@ -28,10 +29,10 @@ use yaak_models::models::{
|
||||
HttpResponseState, ProxySetting, ProxySettingAuth,
|
||||
};
|
||||
use yaak_models::queries::{
|
||||
get_http_response, get_or_create_settings, get_workspace, update_response_if_id,
|
||||
upsert_cookie_jar,
|
||||
get_base_environment, get_http_response, get_or_create_settings, get_workspace,
|
||||
update_response_if_id, upsert_cookie_jar, UpdateSource,
|
||||
};
|
||||
use yaak_plugin_runtime::events::{RenderPurpose, WindowContext};
|
||||
use yaak_plugins::events::{RenderPurpose, WindowContext};
|
||||
|
||||
pub async fn send_http_request<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
@@ -43,6 +44,9 @@ pub async fn send_http_request<R: Runtime>(
|
||||
) -> Result<HttpResponse, String> {
|
||||
let workspace =
|
||||
get_workspace(window, &request.workspace_id).await.expect("Failed to get Workspace");
|
||||
let base_environment = get_base_environment(window, &request.workspace_id)
|
||||
.await
|
||||
.expect("Failed to get base environment");
|
||||
let settings = get_or_create_settings(window).await;
|
||||
let cb = PluginTemplateCallback::new(
|
||||
window.app_handle(),
|
||||
@@ -54,7 +58,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
let response = Arc::new(Mutex::new(og_response.clone()));
|
||||
|
||||
let rendered_request =
|
||||
render_http_request(&request, &workspace, environment.as_ref(), &cb).await;
|
||||
render_http_request(&request, &base_environment, environment.as_ref(), &cb).await;
|
||||
|
||||
let mut url_string = rendered_request.url;
|
||||
|
||||
@@ -74,9 +78,21 @@ pub async fn send_http_request<R: Runtime>(
|
||||
.brotli(true)
|
||||
.deflate(true)
|
||||
.referer(false)
|
||||
.danger_accept_invalid_certs(!workspace.setting_validate_certificates)
|
||||
.tls_info(true);
|
||||
|
||||
if workspace.setting_validate_certificates {
|
||||
// Use platform-native verifier to validate certificates
|
||||
client_builder =
|
||||
client_builder.use_preconfigured_tls(ClientConfig::with_platform_verifier())
|
||||
} else {
|
||||
// Use rustls to skip validation because rustls_platform_verifier does not have this
|
||||
// ability
|
||||
client_builder = client_builder
|
||||
.use_rustls_tls()
|
||||
.danger_accept_invalid_hostnames(true)
|
||||
.danger_accept_invalid_certs(true);
|
||||
}
|
||||
|
||||
match settings.proxy {
|
||||
Some(ProxySetting::Disabled) => client_builder = client_builder.no_proxy(),
|
||||
Some(ProxySetting::Enabled { http, https, auth }) => {
|
||||
@@ -243,7 +259,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
|
||||
let request_body = rendered_request.body;
|
||||
if let Some(body_type) = &rendered_request.body_type {
|
||||
if request_body.contains_key("query") && request_body.contains_key("variables") {
|
||||
if body_type == "graphql" {
|
||||
let query = get_str_h(&request_body, "query");
|
||||
let variables = get_str_h(&request_body, "variables");
|
||||
let body = if variables.trim().is_empty() {
|
||||
@@ -255,9 +271,6 @@ pub async fn send_http_request<R: Runtime>(
|
||||
)
|
||||
};
|
||||
request_builder = request_builder.body(body.to_owned());
|
||||
} else if request_body.contains_key("text") {
|
||||
let body = get_str_h(&request_body, "text");
|
||||
request_builder = request_builder.body(body.to_owned());
|
||||
} else if body_type == "application/x-www-form-urlencoded"
|
||||
&& request_body.contains_key("form")
|
||||
{
|
||||
@@ -359,6 +372,9 @@ pub async fn send_http_request<R: Runtime>(
|
||||
}
|
||||
headers.remove("Content-Type"); // reqwest will add this automatically
|
||||
request_builder = request_builder.multipart(multipart_form);
|
||||
} else if request_body.contains_key("text") {
|
||||
let body = get_str_h(&request_body, "text");
|
||||
request_builder = request_builder.body(body.to_owned());
|
||||
} else {
|
||||
warn!("Unsupported body type: {}", body_type);
|
||||
}
|
||||
@@ -436,7 +452,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
};
|
||||
|
||||
r.state = HttpResponseState::Connected;
|
||||
update_response_if_id(&window, &r)
|
||||
update_response_if_id(&window, &r, &UpdateSource::Window)
|
||||
.await
|
||||
.expect("Failed to update response after connected");
|
||||
}
|
||||
@@ -465,7 +481,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
f.flush().await.expect("Failed to flush file");
|
||||
written_bytes += bytes.len();
|
||||
r.content_length = Some(written_bytes as i32);
|
||||
update_response_if_id(&window, &r)
|
||||
update_response_if_id(&window, &r, &UpdateSource::Window)
|
||||
.await
|
||||
.expect("Failed to update response");
|
||||
}
|
||||
@@ -487,7 +503,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
None => Some(written_bytes as i32),
|
||||
};
|
||||
r.state = HttpResponseState::Closed;
|
||||
update_response_if_id(&window, &r)
|
||||
update_response_if_id(&window, &r, &UpdateSource::Window)
|
||||
.await
|
||||
.expect("Failed to update response");
|
||||
};
|
||||
@@ -513,7 +529,9 @@ pub async fn send_http_request<R: Runtime>(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
cookie_jar.cookies = json_cookies;
|
||||
if let Err(e) = upsert_cookie_jar(&window, &cookie_jar).await {
|
||||
if let Err(e) =
|
||||
upsert_cookie_jar(&window, &cookie_jar, &UpdateSource::Window).await
|
||||
{
|
||||
error!("Failed to update cookie jar: {}", e);
|
||||
};
|
||||
}
|
||||
@@ -535,7 +553,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
match get_http_response(window, response_id.as_str()).await {
|
||||
Ok(mut r) => {
|
||||
r.state = HttpResponseState::Closed;
|
||||
update_response_if_id(&window, &r).await.expect("Failed to update response")
|
||||
update_response_if_id(&window, &r, &UpdateSource::Window).await.expect("Failed to update response")
|
||||
},
|
||||
_ => {
|
||||
response_err(&*response.lock().await, "Ephemeral request was cancelled".to_string(), &window).await
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ use log::debug;
|
||||
use reqwest::Method;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{Emitter, Manager, Runtime, WebviewWindow};
|
||||
use yaak_models::queries::{get_key_value_raw, set_key_value_raw};
|
||||
use yaak_models::queries::{get_key_value_raw, set_key_value_raw, UpdateSource};
|
||||
|
||||
// Check for updates every hour
|
||||
const MAX_UPDATE_CHECK_SECONDS: u64 = 60 * 60;
|
||||
@@ -47,7 +47,7 @@ impl YaakNotifier {
|
||||
seen.push(id.to_string());
|
||||
debug!("Marked notification as seen {}", id);
|
||||
let seen_json = serde_json::to_string(&seen).map_err(|e| e.to_string())?;
|
||||
set_key_value_raw(w, KV_NAMESPACE, KV_KEY, seen_json.as_str()).await;
|
||||
set_key_value_raw(w, KV_NAMESPACE, KV_KEY, seen_json.as_str(), &UpdateSource::Window).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -74,10 +74,7 @@ impl YaakNotifier {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let notification = resp
|
||||
.json::<YaakNotification>()
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
let notification = resp.json::<YaakNotification>().await.map_err(|e| e.to_string())?;
|
||||
|
||||
let age = notification.timestamp.signed_duration_since(Utc::now());
|
||||
let seen = get_kv(window).await?;
|
||||
|
||||
@@ -3,37 +3,37 @@ use serde_json::{json, Map, Value};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use yaak_models::models::{
|
||||
Environment, EnvironmentVariable, GrpcMetadataEntry, GrpcRequest, HttpRequest,
|
||||
HttpRequestHeader, HttpUrlParameter, Workspace,
|
||||
HttpRequestHeader, HttpUrlParameter,
|
||||
};
|
||||
use yaak_templates::{parse_and_render, TemplateCallback};
|
||||
|
||||
pub async fn render_template<T: TemplateCallback>(
|
||||
template: &str,
|
||||
w: &Workspace,
|
||||
e: Option<&Environment>,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
cb: &T,
|
||||
) -> String {
|
||||
let vars = &make_vars_hashmap(w, e);
|
||||
let vars = &make_vars_hashmap(base_environment, environment);
|
||||
render(template, vars, cb).await
|
||||
}
|
||||
|
||||
pub async fn render_json_value<T: TemplateCallback>(
|
||||
value: Value,
|
||||
w: &Workspace,
|
||||
e: Option<&Environment>,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
cb: &T,
|
||||
) -> Value {
|
||||
let vars = &make_vars_hashmap(w, e);
|
||||
let vars = &make_vars_hashmap(base_environment, environment);
|
||||
render_json_value_raw(value, vars, cb).await
|
||||
}
|
||||
|
||||
pub async fn render_grpc_request<T: TemplateCallback>(
|
||||
r: &GrpcRequest,
|
||||
w: &Workspace,
|
||||
e: Option<&Environment>,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
cb: &T,
|
||||
) -> GrpcRequest {
|
||||
let vars = &make_vars_hashmap(w, e);
|
||||
let vars = &make_vars_hashmap(base_environment, environment);
|
||||
|
||||
let mut metadata = Vec::new();
|
||||
for p in r.metadata.clone() {
|
||||
@@ -41,6 +41,7 @@ pub async fn render_grpc_request<T: TemplateCallback>(
|
||||
enabled: p.enabled,
|
||||
name: render(p.name.as_str(), vars, cb).await,
|
||||
value: render(p.value.as_str(), vars, cb).await,
|
||||
id: p.id,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -61,11 +62,11 @@ pub async fn render_grpc_request<T: TemplateCallback>(
|
||||
|
||||
pub async fn render_http_request(
|
||||
r: &HttpRequest,
|
||||
w: &Workspace,
|
||||
e: Option<&Environment>,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
cb: &PluginTemplateCallback,
|
||||
) -> HttpRequest {
|
||||
let vars = &make_vars_hashmap(w, e);
|
||||
let vars = &make_vars_hashmap(base_environment, environment);
|
||||
|
||||
let mut url_parameters = Vec::new();
|
||||
for p in r.url_parameters.clone() {
|
||||
@@ -73,6 +74,7 @@ pub async fn render_http_request(
|
||||
enabled: p.enabled,
|
||||
name: render(p.name.as_str(), vars, cb).await,
|
||||
value: render(p.value.as_str(), vars, cb).await,
|
||||
id: p.id,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -82,6 +84,7 @@ pub async fn render_http_request(
|
||||
enabled: p.enabled,
|
||||
name: render(p.name.as_str(), vars, cb).await,
|
||||
value: render(p.value.as_str(), vars, cb).await,
|
||||
id: p.id,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -110,11 +113,11 @@ pub async fn render_http_request(
|
||||
}
|
||||
|
||||
pub fn make_vars_hashmap(
|
||||
workspace: &Workspace,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
) -> HashMap<String, String> {
|
||||
let mut variables = HashMap::new();
|
||||
variables = add_variable_to_map(variables, &workspace.variables);
|
||||
variables = add_variable_to_map(variables, &base_environment.variables);
|
||||
|
||||
if let Some(e) = environment {
|
||||
variables = add_variable_to_map(variables, &e.variables);
|
||||
@@ -309,6 +312,7 @@ mod placeholder_tests {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo/bar"),
|
||||
@@ -322,6 +326,7 @@ mod placeholder_tests {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
@@ -335,6 +340,7 @@ mod placeholder_tests {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo?:foo"),
|
||||
@@ -348,6 +354,7 @@ mod placeholder_tests {
|
||||
enabled: true,
|
||||
name: "".to_string(),
|
||||
value: "".to_string(),
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:missing"),
|
||||
@@ -361,6 +368,7 @@ mod placeholder_tests {
|
||||
enabled: false,
|
||||
name: ":foo".to_string(),
|
||||
value: "xxx".to_string(),
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
@@ -374,6 +382,7 @@ mod placeholder_tests {
|
||||
name: ":foo".into(),
|
||||
value: "xxx".into(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foooo"),
|
||||
@@ -387,6 +396,7 @@ mod placeholder_tests {
|
||||
name: ":foo".into(),
|
||||
value: "Hello World".into(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
replace_path_placeholder(&p, "https://example.com/:foo"),
|
||||
@@ -403,17 +413,17 @@ mod placeholder_tests {
|
||||
name: "b".to_string(),
|
||||
value: "bbb".to_string(),
|
||||
enabled: true,
|
||||
id: "p1".into(),
|
||||
},
|
||||
HttpUrlParameter {
|
||||
name: ":a".to_string(),
|
||||
value: "aaa".to_string(),
|
||||
enabled: true,
|
||||
id: "p2".into(),
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
println!("HELLO?: {result:?}");
|
||||
|
||||
assert_eq!(result.url, "example.com/aaa/bar");
|
||||
assert_eq!(result.url_parameters.len(), 1);
|
||||
assert_eq!(result.url_parameters[0].name, "b");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::MAIN_WINDOW_PREFIX;
|
||||
use hex_color::HexColor;
|
||||
use log::warn;
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
@@ -6,7 +7,6 @@ use tauri::{
|
||||
plugin::{Builder, TauriPlugin},
|
||||
Emitter, Listener, Manager, Runtime, Window, WindowEvent,
|
||||
};
|
||||
use crate::MAIN_WINDOW_PREFIX;
|
||||
|
||||
const WINDOW_CONTROL_PAD_X: f64 = 13.0;
|
||||
const WINDOW_CONTROL_PAD_Y: f64 = 18.0;
|
||||
@@ -202,10 +202,9 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ns_win = window
|
||||
.ns_window()
|
||||
.expect("NS Window should exist to mount traffic light delegate.")
|
||||
as id;
|
||||
let ns_win =
|
||||
window.ns_window().expect("NS Window should exist to mount traffic light delegate.")
|
||||
as id;
|
||||
|
||||
let current_delegate: id = ns_win.delegate();
|
||||
|
||||
@@ -322,10 +321,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
) {
|
||||
unsafe {
|
||||
with_window_state(&*this, |state: &mut WindowState<R>| {
|
||||
state
|
||||
.window
|
||||
.emit("did-enter-fullscreen", ())
|
||||
.expect("Failed to emit event");
|
||||
state.window.emit("did-enter-fullscreen", ()).expect("Failed to emit event");
|
||||
});
|
||||
|
||||
let super_del: id = *this.get_ivar("super_delegate");
|
||||
@@ -339,10 +335,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
) {
|
||||
unsafe {
|
||||
with_window_state(&*this, |state: &mut WindowState<R>| {
|
||||
state
|
||||
.window
|
||||
.emit("will-enter-fullscreen", ())
|
||||
.expect("Failed to emit event");
|
||||
state.window.emit("will-enter-fullscreen", ()).expect("Failed to emit event");
|
||||
});
|
||||
|
||||
let super_del: id = *this.get_ivar("super_delegate");
|
||||
@@ -356,10 +349,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
) {
|
||||
unsafe {
|
||||
with_window_state(&*this, |state: &mut WindowState<R>| {
|
||||
state
|
||||
.window
|
||||
.emit("did-exit-fullscreen", ())
|
||||
.expect("Failed to emit event");
|
||||
state.window.emit("did-exit-fullscreen", ()).expect("Failed to emit event");
|
||||
|
||||
let id = state.window.ns_window().expect("Failed to emit event") as id;
|
||||
position_traffic_lights(
|
||||
@@ -381,10 +371,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
) {
|
||||
unsafe {
|
||||
with_window_state(&*this, |state: &mut WindowState<R>| {
|
||||
state
|
||||
.window
|
||||
.emit("will-exit-fullscreen", ())
|
||||
.expect("Failed to emit event");
|
||||
state.window.emit("will-exit-fullscreen", ()).expect("Failed to emit event");
|
||||
});
|
||||
|
||||
let super_del: id = *this.get_ivar("super_delegate");
|
||||
@@ -432,11 +419,8 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
|
||||
window: window.clone(),
|
||||
};
|
||||
let app_box = Box::into_raw(Box::new(app_state)) as *mut c_void;
|
||||
let random_str: String = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(20)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
let random_str: String =
|
||||
rand::thread_rng().sample_iter(&Alphanumeric).take(20).map(char::from).collect();
|
||||
|
||||
// We need to ensure we have a unique delegate name, otherwise we will panic while trying to create a duplicate
|
||||
// delegate with the same name.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use tauri::{AppHandle, Manager, Runtime};
|
||||
use yaak_plugin_runtime::events::{RenderPurpose, TemplateFunctionArg, WindowContext};
|
||||
use yaak_plugin_runtime::manager::PluginManager;
|
||||
use yaak_plugins::events::{RenderPurpose, TemplateFunctionArg, WindowContext};
|
||||
use yaak_plugins::manager::PluginManager;
|
||||
use yaak_templates::TemplateCallback;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -31,11 +31,7 @@ impl TemplateCallback for PluginTemplateCallback {
|
||||
let window_context = self.window_context.to_owned();
|
||||
// The beta named the function `Response` but was changed in stable.
|
||||
// Keep this here for a while because there's no easy way to migrate
|
||||
let fn_name = if fn_name == "Response" {
|
||||
"response"
|
||||
} else {
|
||||
fn_name
|
||||
};
|
||||
let fn_name = if fn_name == "Response" { "response" } else { fn_name };
|
||||
|
||||
let function = self
|
||||
.plugin_manager
|
||||
|
||||
@@ -6,7 +6,7 @@ use tauri::{AppHandle, Manager};
|
||||
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
|
||||
use tauri_plugin_updater::UpdaterExt;
|
||||
use tokio::task::block_in_place;
|
||||
use yaak_plugin_runtime::manager::PluginManager;
|
||||
use yaak_plugins::manager::PluginManager;
|
||||
|
||||
use crate::is_dev;
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
"active": true,
|
||||
"category": "DeveloperTool",
|
||||
"externalBin": [
|
||||
"vendored/protoc/yaakprotoc",
|
||||
"vendored/node/yaaknode"
|
||||
"vendored/node/yaaknode",
|
||||
"vendored/protoc/yaakprotoc"
|
||||
],
|
||||
"icon": [
|
||||
"icons/release/32x32.png",
|
||||
@@ -79,8 +79,7 @@
|
||||
"frameworks": []
|
||||
},
|
||||
"windows": {
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
"signCommand": "trusted-signing-cli -e https://eus.codesigning.azure.net/ -a Yaak -c yaakapp %1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,30 +265,31 @@ __export(src_exports, {
|
||||
module.exports = __toCommonJS(src_exports);
|
||||
var import_shell_quote = __toESM(require_shell_quote());
|
||||
var DATA_FLAGS = ["d", "data", "data-raw", "data-urlencode", "data-binary", "data-ascii"];
|
||||
var SUPPORTED_ARGS = [
|
||||
["url"],
|
||||
// Specify the URL explicitly
|
||||
["user", "u"],
|
||||
// Authentication
|
||||
["digest"],
|
||||
// Apply auth as digest
|
||||
["header", "H"],
|
||||
var SUPPORTED_FLAGS = [
|
||||
["cookie", "b"],
|
||||
["get", "G"],
|
||||
// Put the post data in the URL
|
||||
["d", "data"],
|
||||
// Add url encoded data
|
||||
["data-ascii"],
|
||||
["data-binary"],
|
||||
["data-raw"],
|
||||
["data-urlencode"],
|
||||
["data-binary"],
|
||||
["data-ascii"],
|
||||
["digest"],
|
||||
// Apply auth as digest
|
||||
["form", "F"],
|
||||
// Add multipart data
|
||||
["get", "G"],
|
||||
// Put the post data in the URL
|
||||
["header", "H"],
|
||||
["request", "X"],
|
||||
// Request method
|
||||
["url"],
|
||||
// Specify the URL explicitly
|
||||
["url-query"],
|
||||
["user", "u"],
|
||||
// Authentication
|
||||
DATA_FLAGS
|
||||
].flatMap((v) => v);
|
||||
var BOOL_FLAGS = ["G", "get", "digest"];
|
||||
var BOOLEAN_FLAGS = ["G", "get", "digest"];
|
||||
function pluginHookImport(_ctx, rawData) {
|
||||
if (!rawData.match(/^\s*curl /)) {
|
||||
return null;
|
||||
@@ -345,7 +346,7 @@ function pluginHookImport(_ctx, rawData) {
|
||||
};
|
||||
}
|
||||
function importCommand(parseEntries, workspaceId) {
|
||||
const pairsByName = {};
|
||||
const flagsByName = {};
|
||||
const singletons = [];
|
||||
for (let i = 1; i < parseEntries.length; i++) {
|
||||
let parseEntry = parseEntries[i];
|
||||
@@ -355,12 +356,12 @@ function importCommand(parseEntries, workspaceId) {
|
||||
if (typeof parseEntry === "string" && parseEntry.match(/^-{1,2}[\w-]+/)) {
|
||||
const isSingleDash = parseEntry[0] === "-" && parseEntry[1] !== "-";
|
||||
let name = parseEntry.replace(/^-{1,2}/, "");
|
||||
if (!SUPPORTED_ARGS.includes(name)) {
|
||||
if (!SUPPORTED_FLAGS.includes(name)) {
|
||||
continue;
|
||||
}
|
||||
let value;
|
||||
const nextEntry = parseEntries[i + 1];
|
||||
const hasValue = !BOOL_FLAGS.includes(name);
|
||||
const hasValue = !BOOLEAN_FLAGS.includes(name);
|
||||
if (isSingleDash && name.length > 1) {
|
||||
value = name.slice(1);
|
||||
name = name.slice(0, 1);
|
||||
@@ -370,31 +371,42 @@ function importCommand(parseEntries, workspaceId) {
|
||||
} else {
|
||||
value = true;
|
||||
}
|
||||
pairsByName[name] = pairsByName[name] || [];
|
||||
pairsByName[name].push(value);
|
||||
flagsByName[name] = flagsByName[name] || [];
|
||||
flagsByName[name].push(value);
|
||||
} else if (parseEntry) {
|
||||
singletons.push(parseEntry);
|
||||
}
|
||||
}
|
||||
let urlParameters;
|
||||
let url;
|
||||
const urlArg = getPairValue(pairsByName, singletons[0] || "", ["url"]);
|
||||
const urlArg = getPairValue(flagsByName, singletons[0] || "", ["url"]);
|
||||
const [baseUrl, search] = splitOnce(urlArg, "?");
|
||||
urlParameters = search?.split("&").map((p) => {
|
||||
const v = splitOnce(p, "=");
|
||||
return { name: decodeURIComponent(v[0] ?? ""), value: decodeURIComponent(v[1] ?? ""), enabled: true };
|
||||
}) ?? [];
|
||||
url = baseUrl ?? urlArg;
|
||||
const [username, password] = getPairValue(pairsByName, "", ["u", "user"]).split(/:(.*)$/);
|
||||
const isDigest = getPairValue(pairsByName, false, ["digest"]);
|
||||
for (const p of flagsByName["url-query"] ?? []) {
|
||||
if (typeof p !== "string") {
|
||||
continue;
|
||||
}
|
||||
const [name, value] = p.split("=");
|
||||
urlParameters.push({
|
||||
name: name ?? "",
|
||||
value: value ?? "",
|
||||
enabled: true
|
||||
});
|
||||
}
|
||||
const [username, password] = getPairValue(flagsByName, "", ["u", "user"]).split(/:(.*)$/);
|
||||
const isDigest = getPairValue(flagsByName, false, ["digest"]);
|
||||
const authenticationType = username ? isDigest ? "digest" : "basic" : null;
|
||||
const authentication = username ? {
|
||||
username: username.trim(),
|
||||
password: (password ?? "").trim()
|
||||
} : {};
|
||||
const headers = [
|
||||
...pairsByName["header"] || [],
|
||||
...pairsByName["H"] || []
|
||||
...flagsByName["header"] || [],
|
||||
...flagsByName["H"] || []
|
||||
].map((header) => {
|
||||
const [name, value] = header.split(/:(.*)$/);
|
||||
if (!value) {
|
||||
@@ -411,8 +423,8 @@ function importCommand(parseEntries, workspaceId) {
|
||||
};
|
||||
});
|
||||
const cookieHeaderValue = [
|
||||
...pairsByName["cookie"] || [],
|
||||
...pairsByName["b"] || []
|
||||
...flagsByName["cookie"] || [],
|
||||
...flagsByName["b"] || []
|
||||
].map((str) => {
|
||||
const name = str.split("=", 1)[0];
|
||||
const value = str.replace(`${name}=`, "");
|
||||
@@ -428,12 +440,12 @@ function importCommand(parseEntries, workspaceId) {
|
||||
enabled: true
|
||||
});
|
||||
}
|
||||
const dataParameters = pairsToDataParameters(pairsByName);
|
||||
const dataParameters = pairsToDataParameters(flagsByName);
|
||||
const contentTypeHeader = headers.find((header) => header.name.toLowerCase() === "content-type");
|
||||
const mimeType = contentTypeHeader ? contentTypeHeader.value.split(";")[0] : null;
|
||||
const formDataParams = [
|
||||
...pairsByName["form"] || [],
|
||||
...pairsByName["F"] || []
|
||||
...flagsByName["form"] || [],
|
||||
...flagsByName["F"] || []
|
||||
].map((str) => {
|
||||
const parts = str.split("=");
|
||||
const name = parts[0] ?? "";
|
||||
@@ -451,7 +463,7 @@ function importCommand(parseEntries, workspaceId) {
|
||||
});
|
||||
let body = {};
|
||||
let bodyType = null;
|
||||
const bodyAsGET = getPairValue(pairsByName, false, ["G", "get"]);
|
||||
const bodyAsGET = getPairValue(flagsByName, false, ["G", "get"]);
|
||||
if (dataParameters.length > 0 && bodyAsGET) {
|
||||
urlParameters.push(...dataParameters);
|
||||
} else if (dataParameters.length > 0 && (mimeType == null || mimeType === "application/x-www-form-urlencoded")) {
|
||||
@@ -486,7 +498,7 @@ function importCommand(parseEntries, workspaceId) {
|
||||
});
|
||||
}
|
||||
}
|
||||
let method = getPairValue(pairsByName, "", ["X", "request"]).toUpperCase();
|
||||
let method = getPairValue(flagsByName, "", ["X", "request"]).toUpperCase();
|
||||
if (method === "" && body) {
|
||||
method = "text" in body || "form" in body ? "POST" : "GET";
|
||||
}
|
||||
|
||||
@@ -7232,56 +7232,54 @@ function pluginHookImport(ctx, contents) {
|
||||
folders: []
|
||||
};
|
||||
const workspacesToImport = parsed.resources.filter(isWorkspace);
|
||||
for (const workspaceToImport of workspacesToImport) {
|
||||
const baseEnvironment = parsed.resources.find(
|
||||
(r) => isEnvironment(r) && r.parentId === workspaceToImport._id
|
||||
);
|
||||
for (const w of workspacesToImport) {
|
||||
resources.workspaces.push({
|
||||
id: convertId(workspaceToImport._id),
|
||||
createdAt: new Date(workspacesToImport.created ?? Date.now()).toISOString().replace("Z", ""),
|
||||
updatedAt: new Date(workspacesToImport.updated ?? Date.now()).toISOString().replace("Z", ""),
|
||||
id: convertId(w._id),
|
||||
createdAt: w.created ? new Date(w.created).toISOString().replace("Z", "") : void 0,
|
||||
updatedAt: w.updated ? new Date(w.updated).toISOString().replace("Z", "") : void 0,
|
||||
model: "workspace",
|
||||
name: workspaceToImport.name,
|
||||
variables: baseEnvironment ? parseVariables(baseEnvironment.data) : []
|
||||
name: w.name,
|
||||
description: w.description || void 0
|
||||
});
|
||||
const environmentsToImport = parsed.resources.filter(
|
||||
(r) => isEnvironment(r) && r.parentId === baseEnvironment?._id
|
||||
(r) => isEnvironment(r)
|
||||
);
|
||||
resources.environments.push(
|
||||
...environmentsToImport.map((r) => importEnvironment(r, workspaceToImport._id))
|
||||
...environmentsToImport.map((r) => importEnvironment(r, w._id))
|
||||
);
|
||||
const nextFolder = (parentId) => {
|
||||
const children = parsed.resources.filter((r) => r.parentId === parentId);
|
||||
let sortPriority = 0;
|
||||
for (const child of children) {
|
||||
if (isRequestGroup(child)) {
|
||||
resources.folders.push(importFolder(child, workspaceToImport._id));
|
||||
resources.folders.push(importFolder(child, w._id));
|
||||
nextFolder(child._id);
|
||||
} else if (isHttpRequest(child)) {
|
||||
resources.httpRequests.push(
|
||||
importHttpRequest(child, workspaceToImport._id, sortPriority++)
|
||||
importHttpRequest(child, w._id, sortPriority++)
|
||||
);
|
||||
} else if (isGrpcRequest(child)) {
|
||||
resources.grpcRequests.push(
|
||||
importGrpcRequest(child, workspaceToImport._id, sortPriority++)
|
||||
importGrpcRequest(child, w._id, sortPriority++)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
nextFolder(workspaceToImport._id);
|
||||
nextFolder(w._id);
|
||||
}
|
||||
resources.httpRequests = resources.httpRequests.filter(Boolean);
|
||||
resources.grpcRequests = resources.grpcRequests.filter(Boolean);
|
||||
resources.environments = resources.environments.filter(Boolean);
|
||||
resources.workspaces = resources.workspaces.filter(Boolean);
|
||||
return { resources };
|
||||
return { resources: deleteUndefinedAttrs(resources) };
|
||||
}
|
||||
function importEnvironment(e, workspaceId) {
|
||||
return {
|
||||
id: convertId(e._id),
|
||||
createdAt: new Date(e.created ?? Date.now()).toISOString().replace("Z", ""),
|
||||
updatedAt: new Date(e.updated ?? Date.now()).toISOString().replace("Z", ""),
|
||||
createdAt: e.created ? new Date(e.created).toISOString().replace("Z", "") : void 0,
|
||||
updatedAt: e.updated ? new Date(e.updated).toISOString().replace("Z", "") : void 0,
|
||||
workspaceId: convertId(workspaceId),
|
||||
environmentId: e.parentId === workspaceId ? null : convertId(e.parentId),
|
||||
model: "environment",
|
||||
name: e.name,
|
||||
variables: Object.entries(e.data).map(([name, value]) => ({
|
||||
@@ -7294,10 +7292,11 @@ function importEnvironment(e, workspaceId) {
|
||||
function importFolder(f, workspaceId) {
|
||||
return {
|
||||
id: convertId(f._id),
|
||||
createdAt: new Date(f.created ?? Date.now()).toISOString().replace("Z", ""),
|
||||
updatedAt: new Date(f.updated ?? Date.now()).toISOString().replace("Z", ""),
|
||||
createdAt: f.created ? new Date(f.created).toISOString().replace("Z", "") : void 0,
|
||||
updatedAt: f.updated ? new Date(f.updated).toISOString().replace("Z", "") : void 0,
|
||||
folderId: f.parentId === workspaceId ? null : convertId(f.parentId),
|
||||
workspaceId: convertId(workspaceId),
|
||||
description: f.description || void 0,
|
||||
model: "folder",
|
||||
name: f.name
|
||||
};
|
||||
@@ -7308,13 +7307,14 @@ function importGrpcRequest(r, workspaceId, sortPriority = 0) {
|
||||
const method = parts[1] ?? null;
|
||||
return {
|
||||
id: convertId(r._id),
|
||||
createdAt: new Date(r.created ?? Date.now()).toISOString().replace("Z", ""),
|
||||
updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace("Z", ""),
|
||||
createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : void 0,
|
||||
updatedAt: r.updated ? new Date(r.updated).toISOString().replace("Z", "") : void 0,
|
||||
workspaceId: convertId(workspaceId),
|
||||
folderId: r.parentId === workspaceId ? null : convertId(r.parentId),
|
||||
model: "grpc_request",
|
||||
sortPriority,
|
||||
name: r.name,
|
||||
description: r.description || void 0,
|
||||
url: convertSyntax(r.url),
|
||||
service,
|
||||
method,
|
||||
@@ -7374,13 +7374,14 @@ function importHttpRequest(r, workspaceId, sortPriority = 0) {
|
||||
}
|
||||
return {
|
||||
id: convertId(r._id),
|
||||
createdAt: new Date(r.created ?? Date.now()).toISOString().replace("Z", ""),
|
||||
updatedAt: new Date(r.updated ?? Date.now()).toISOString().replace("Z", ""),
|
||||
createdAt: r.created ? new Date(r.created).toISOString().replace("Z", "") : void 0,
|
||||
updatedAt: r.updated ? new Date(r.updated).toISOString().replace("Z", "") : void 0,
|
||||
workspaceId: convertId(workspaceId),
|
||||
folderId: r.parentId === workspaceId ? null : convertId(r.parentId),
|
||||
model: "http_request",
|
||||
sortPriority,
|
||||
name: r.name,
|
||||
description: r.description || void 0,
|
||||
url: convertSyntax(r.url),
|
||||
body,
|
||||
bodyType,
|
||||
@@ -7394,13 +7395,6 @@ function importHttpRequest(r, workspaceId, sortPriority = 0) {
|
||||
})).filter(({ name, value }) => name !== "" || value !== "")
|
||||
};
|
||||
}
|
||||
function parseVariables(data) {
|
||||
return Object.entries(data).map(([name, value]) => ({
|
||||
enabled: true,
|
||||
name,
|
||||
value: `${value}`
|
||||
}));
|
||||
}
|
||||
function convertSyntax(variable) {
|
||||
if (!isJSString(variable)) return variable;
|
||||
return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, "${[$2]}");
|
||||
@@ -7432,6 +7426,17 @@ function convertId(id) {
|
||||
}
|
||||
return `GENERATE_ID::${id}`;
|
||||
}
|
||||
function deleteUndefinedAttrs(obj) {
|
||||
if (Array.isArray(obj) && obj != null) {
|
||||
return obj.map(deleteUndefinedAttrs);
|
||||
} else if (typeof obj === "object" && obj != null) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).filter(([, v]) => v !== void 0).map(([k, v]) => [k, deleteUndefinedAttrs(v)])
|
||||
);
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
pluginHookImport
|
||||
|
||||
@@ -145878,13 +145878,20 @@ function pluginHookImport(_ctx, contents) {
|
||||
model: "workspace",
|
||||
id: generateId("workspace"),
|
||||
name: info.name || "Postman Import",
|
||||
description: info.description?.content ?? info.description ?? "",
|
||||
description: info.description?.content ?? info.description
|
||||
};
|
||||
exportResources.workspaces.push(workspace);
|
||||
const environment = {
|
||||
model: "environment",
|
||||
id: generateId("environment"),
|
||||
name: "Global Variables",
|
||||
workspaceId: workspace.id,
|
||||
variables: root.variable?.map((v) => ({
|
||||
name: v.key,
|
||||
value: v.value
|
||||
})) ?? []
|
||||
};
|
||||
exportResources.workspaces.push(workspace);
|
||||
exportResources.environments.push(environment);
|
||||
const importItem = (v, folderId = null) => {
|
||||
if (typeof v.name === "string" && Array.isArray(v.item)) {
|
||||
const folder = {
|
||||
@@ -145924,6 +145931,7 @@ function pluginHookImport(_ctx, contents) {
|
||||
workspaceId: workspace.id,
|
||||
folderId,
|
||||
name: v.name,
|
||||
description: v.description || void 0,
|
||||
method: r.method || "GET",
|
||||
url,
|
||||
urlParameters,
|
||||
@@ -145941,7 +145949,8 @@ function pluginHookImport(_ctx, contents) {
|
||||
for (const item of root.item) {
|
||||
importItem(item);
|
||||
}
|
||||
return { resources: convertTemplateSyntax(exportResources) };
|
||||
const resources = deleteUndefinedAttrs(convertTemplateSyntax(exportResources));
|
||||
return { resources };
|
||||
}
|
||||
function convertUrl(url) {
|
||||
if (typeof url === "string") {
|
||||
@@ -146123,6 +146132,17 @@ function convertTemplateSyntax(obj) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
function deleteUndefinedAttrs(obj) {
|
||||
if (Array.isArray(obj) && obj != null) {
|
||||
return obj.map(deleteUndefinedAttrs);
|
||||
} else if (typeof obj === "object" && obj != null) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).filter(([, v]) => v !== void 0).map(([k, v]) => [k, deleteUndefinedAttrs(v)])
|
||||
);
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
var idCount = {};
|
||||
function generateId(model) {
|
||||
idCount[model] = (idCount[model] ?? -1) + 1;
|
||||
|
||||
@@ -45,13 +45,20 @@ function pluginHookImport(_ctx, contents) {
|
||||
model: "workspace",
|
||||
id: generateId("workspace"),
|
||||
name: info.name || "Postman Import",
|
||||
description: info.description?.content ?? info.description ?? "",
|
||||
description: info.description?.content ?? info.description
|
||||
};
|
||||
exportResources.workspaces.push(workspace);
|
||||
const environment = {
|
||||
model: "environment",
|
||||
id: generateId("environment"),
|
||||
name: "Global Variables",
|
||||
workspaceId: workspace.id,
|
||||
variables: root.variable?.map((v) => ({
|
||||
name: v.key,
|
||||
value: v.value
|
||||
})) ?? []
|
||||
};
|
||||
exportResources.workspaces.push(workspace);
|
||||
exportResources.environments.push(environment);
|
||||
const importItem = (v, folderId = null) => {
|
||||
if (typeof v.name === "string" && Array.isArray(v.item)) {
|
||||
const folder = {
|
||||
@@ -91,6 +98,7 @@ function pluginHookImport(_ctx, contents) {
|
||||
workspaceId: workspace.id,
|
||||
folderId,
|
||||
name: v.name,
|
||||
description: v.description || void 0,
|
||||
method: r.method || "GET",
|
||||
url,
|
||||
urlParameters,
|
||||
@@ -108,7 +116,8 @@ function pluginHookImport(_ctx, contents) {
|
||||
for (const item of root.item) {
|
||||
importItem(item);
|
||||
}
|
||||
return { resources: convertTemplateSyntax(exportResources) };
|
||||
const resources = deleteUndefinedAttrs(convertTemplateSyntax(exportResources));
|
||||
return { resources };
|
||||
}
|
||||
function convertUrl(url) {
|
||||
if (typeof url === "string") {
|
||||
@@ -290,6 +299,17 @@ function convertTemplateSyntax(obj) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
function deleteUndefinedAttrs(obj) {
|
||||
if (Array.isArray(obj) && obj != null) {
|
||||
return obj.map(deleteUndefinedAttrs);
|
||||
} else if (typeof obj === "object" && obj != null) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).filter(([, v]) => v !== void 0).map(([k, v]) => [k, deleteUndefinedAttrs(v)])
|
||||
);
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
var idCount = {};
|
||||
function generateId(model) {
|
||||
idCount[model] = (idCount[model] ?? -1) + 1;
|
||||
|
||||
@@ -41,6 +41,24 @@ function pluginHookImport(_ctx, contents) {
|
||||
parsed.resources.httpRequests = parsed.resources.requests;
|
||||
delete parsed.resources["requests"];
|
||||
}
|
||||
for (const workspace of parsed.resources.workspaces ?? []) {
|
||||
if ("variables" in workspace) {
|
||||
const baseEnvironment = {
|
||||
id: `GENERATE_ID::base_env_${workspace["id"]}`,
|
||||
name: "Global Variables",
|
||||
variables: workspace.variables,
|
||||
workspaceId: workspace.id
|
||||
};
|
||||
parsed.resources.environments = parsed.resources.environments ?? [];
|
||||
parsed.resources.environments.push(baseEnvironment);
|
||||
delete workspace.variables;
|
||||
for (const environment of parsed.resources.environments) {
|
||||
if (environment.workspaceId === workspace.id && environment.id !== baseEnvironment.id) {
|
||||
environment.environmentId = baseEnvironment.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { resources: parsed.resources };
|
||||
}
|
||||
function isJSObject(obj) {
|
||||
|
||||
@@ -29,6 +29,7 @@ var plugin = {
|
||||
description: "Prompt the user for input when sending a request",
|
||||
args: [
|
||||
{ type: "text", name: "title", label: "Title" },
|
||||
{ type: "text", name: "label", label: "Label", optional: true },
|
||||
{ type: "text", name: "defaultValue", label: "Default Value", optional: true },
|
||||
{ type: "text", name: "placeholder", label: "Placeholder", optional: true }
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "template-function-response",
|
||||
"name": "@yaakapp/template-function-response",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
[package]
|
||||
name = "yaak_grpc"
|
||||
name = "yaak-grpc"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
tonic = "0.10.2"
|
||||
@@ -22,4 +23,4 @@ tauri = { workspace = true }
|
||||
tauri-plugin-shell = { workspace = true }
|
||||
md5 = "0.7.0"
|
||||
dunce = "1.0.4"
|
||||
async-recursion = "1.1.1"
|
||||
async-recursion = "1.1.1"
|
||||
@@ -33,8 +33,7 @@ impl Encoder for DynamicCodec {
|
||||
type Error = Status;
|
||||
|
||||
fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
|
||||
item.encode(dst)
|
||||
.expect("buffer is too small to decode this message");
|
||||
item.encode(dst).expect("buffer is too small to decode this message");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -45,8 +44,7 @@ impl Decoder for DynamicCodec {
|
||||
|
||||
fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
|
||||
let mut msg = DynamicMessage::new(self.0.output());
|
||||
msg.merge(src)
|
||||
.map_err(|err| Status::internal(err.to_string()))?;
|
||||
msg.merge(src).map_err(|err| Status::internal(err.to_string()))?;
|
||||
Ok(Some(msg))
|
||||
}
|
||||
}
|
||||
@@ -30,15 +30,13 @@ pub struct MethodDefinition {
|
||||
pub server_streaming: bool,
|
||||
}
|
||||
|
||||
static SERIALIZE_OPTIONS: &'static SerializeOptions = &SerializeOptions::new()
|
||||
.skip_default_fields(false)
|
||||
.stringify_64_bit_integers(false);
|
||||
static SERIALIZE_OPTIONS: &'static SerializeOptions =
|
||||
&SerializeOptions::new().skip_default_fields(false).stringify_64_bit_integers(false);
|
||||
|
||||
pub fn serialize_message(msg: &DynamicMessage) -> Result<String, String> {
|
||||
let mut buf = Vec::new();
|
||||
let mut se = serde_json::Serializer::pretty(&mut buf);
|
||||
msg.serialize_with_options(&mut se, SERIALIZE_OPTIONS)
|
||||
.map_err(|e| e.to_string())?;
|
||||
msg.serialize_with_options(&mut se, SERIALIZE_OPTIONS).map_err(|e| e.to_string())?;
|
||||
let s = String::from_utf8(buf).expect("serde_json to emit valid utf8");
|
||||
Ok(s)
|
||||
}
|
||||
@@ -54,19 +54,14 @@ impl From<Status> for StreamError {
|
||||
|
||||
impl GrpcConnection {
|
||||
pub fn service(&self, service: &str) -> Result<ServiceDescriptor, String> {
|
||||
let service = self
|
||||
.pool
|
||||
.get_service_by_name(service)
|
||||
.ok_or("Failed to find service")?;
|
||||
let service = self.pool.get_service_by_name(service).ok_or("Failed to find service")?;
|
||||
Ok(service)
|
||||
}
|
||||
|
||||
pub fn method(&self, service: &str, method: &str) -> Result<MethodDescriptor, String> {
|
||||
let service = self.service(service)?;
|
||||
let method = service
|
||||
.methods()
|
||||
.find(|m| m.name() == method)
|
||||
.ok_or("Failed to find method")?;
|
||||
let method =
|
||||
service.methods().find(|m| m.name() == method).ok_or("Failed to find method")?;
|
||||
Ok(method)
|
||||
}
|
||||
|
||||
@@ -132,13 +127,10 @@ impl GrpcConnection {
|
||||
let path = method_desc_to_path(method);
|
||||
let codec = DynamicCodec::new(method.clone());
|
||||
client.ready().await.unwrap();
|
||||
client
|
||||
.client_streaming(req, path, codec)
|
||||
.await
|
||||
.map_err(|e| StreamError {
|
||||
message: e.message().to_string(),
|
||||
status: Some(e),
|
||||
})
|
||||
client.client_streaming(req, path, codec).await.map_err(|e| StreamError {
|
||||
message: e.message().to_string(),
|
||||
status: Some(e),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn server_streaming(
|
||||
@@ -197,8 +189,7 @@ impl GrpcHandle {
|
||||
fill_pool_from_files(&self.app_handle, proto_files).await
|
||||
}?;
|
||||
|
||||
self.pools
|
||||
.insert(make_pool_key(id, uri, proto_files), pool.clone());
|
||||
self.pools.insert(make_pool_key(id, uri, proto_files), pool.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -211,9 +202,7 @@ impl GrpcHandle {
|
||||
// Ensure reflection is up-to-date
|
||||
self.reflect(id, uri, proto_files).await?;
|
||||
|
||||
let pool = self
|
||||
.get_pool(id, uri, proto_files)
|
||||
.ok_or("Failed to get pool".to_string())?;
|
||||
let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool".to_string())?;
|
||||
Ok(self.services_from_pool(&pool))
|
||||
}
|
||||
|
||||
@@ -234,7 +223,7 @@ impl GrpcHandle {
|
||||
&pool,
|
||||
input_message,
|
||||
))
|
||||
.unwrap(),
|
||||
.unwrap(),
|
||||
})
|
||||
}
|
||||
def
|
||||
@@ -249,9 +238,7 @@ impl GrpcHandle {
|
||||
proto_files: &Vec<PathBuf>,
|
||||
) -> Result<GrpcConnection, String> {
|
||||
self.reflect(id, uri, proto_files).await?;
|
||||
let pool = self
|
||||
.get_pool(id, uri, proto_files)
|
||||
.ok_or("Failed to get pool")?;
|
||||
let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool")?;
|
||||
|
||||
let uri = uri_from_str(uri)?;
|
||||
let conn = get_transport();
|
||||
@@ -301,4 +288,4 @@ fn make_pool_key(id: &str, uri: &str, proto_files: &Vec<PathBuf>) -> String {
|
||||
);
|
||||
|
||||
format!("{:x}", md5::compute(pool_key))
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ pub async fn fill_pool_from_reflection(uri: &Uri) -> Result<DescriptorPool, Stri
|
||||
if service == "grpc.reflection.v1alpha.ServerReflection" {
|
||||
continue;
|
||||
}
|
||||
if service == "grpc.reflection.v1.ServerReflection"{
|
||||
if service == "grpc.reflection.v1.ServerReflection" {
|
||||
// TODO: update reflection client to use v1
|
||||
continue;
|
||||
}
|
||||
@@ -316,8 +316,8 @@ mod topology {
|
||||
zero_indegree.push(node.clone());
|
||||
}
|
||||
}
|
||||
for (node, deps) in data.out_graph.iter(){
|
||||
if deps.is_empty(){
|
||||
for (node, deps) in data.out_graph.iter() {
|
||||
if deps.is_empty() {
|
||||
zero_indegree.push(node.clone());
|
||||
}
|
||||
}
|
||||
@@ -344,8 +344,8 @@ mod topology {
|
||||
}
|
||||
|
||||
let node = self.zero_indegree.pop().unwrap();
|
||||
if let Some(parents) = self.data.in_graph.get(&node){
|
||||
for parent in parents.iter(){
|
||||
if let Some(parents) = self.data.in_graph.get(&node) {
|
||||
for parent in parents.iter() {
|
||||
let deps = self.data.out_graph.get_mut(parent).unwrap();
|
||||
deps.remove(&node);
|
||||
if deps.is_empty() {
|
||||
@@ -360,7 +360,7 @@ mod topology {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort(){
|
||||
fn test_sort() {
|
||||
{
|
||||
let mut topo_sort = SimpleTopoSort::new();
|
||||
topo_sort.insert("a", []);
|
||||
@@ -390,5 +390,4 @@ mod topology {
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
20
src-tauri/yaak-license/Cargo.toml
Normal file
20
src-tauri/yaak-license/Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "yaak-license"
|
||||
links = "yaak-license"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
reqwest = { workspace = true, features = ["json"] }
|
||||
serde = { version = "1.0.208", features = ["derive"] }
|
||||
ts-rs = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tauri = { workspace = true }
|
||||
yaak-models = { workspace = true }
|
||||
chrono = "0.4.38"
|
||||
log = "0.4.22"
|
||||
serde_json = "1.0.132"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-plugin = { version = "2.0.3", features = ["build"] }
|
||||
11
src-tauri/yaak-license/bindings/license.ts
Normal file
11
src-tauri/yaak-license/bindings/license.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type APIErrorResponsePayload = { error: string, message: string, };
|
||||
|
||||
export type ActivateLicenseRequestPayload = { licenseKey: string, appVersion: string, appPlatform: string, };
|
||||
|
||||
export type ActivateLicenseResponsePayload = { activationId: string, };
|
||||
|
||||
export type CheckActivationResponsePayload = { active: boolean, };
|
||||
|
||||
export type LicenseCheckStatus = { "type": "personal_use", trial_ended: string, } | { "type": "commercial_use" } | { "type": "invalid_license" } | { "type": "trialing", end: string, };
|
||||
3
src-tauri/yaak-license/bindings/models.ts
Normal file
3
src-tauri/yaak-license/bindings/models.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type CheckActivationRequestPayload = { activationId: string, };
|
||||
5
src-tauri/yaak-license/build.rs
Normal file
5
src-tauri/yaak-license/build.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
const COMMANDS: &[&str] = &["activate", "check"];
|
||||
|
||||
fn main() {
|
||||
tauri_plugin::Builder::new(COMMANDS).build();
|
||||
}
|
||||
37
src-tauri/yaak-license/index.ts
Normal file
37
src-tauri/yaak-license/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import { useEffect } from 'react';
|
||||
import { LicenseCheckStatus } from './bindings/license';
|
||||
|
||||
export * from './bindings/license';
|
||||
|
||||
export function useLicense() {
|
||||
const queryClient = useQueryClient();
|
||||
const activate = useMutation<void, string, { licenseKey: string }>({
|
||||
mutationKey: ['license.activate'],
|
||||
mutationFn: (payload) => invoke('plugin:yaak-license|activate', payload),
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY }),
|
||||
});
|
||||
|
||||
// Check the license again after a license is activated
|
||||
useEffect(() => {
|
||||
const unlisten = listen('license-activated', async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY });
|
||||
});
|
||||
return () => {
|
||||
unlisten.then((fn) => fn());
|
||||
};
|
||||
}, []);
|
||||
|
||||
const CHECK_QUERY_KEY = ['license.check'];
|
||||
const check = useQuery<void, string, LicenseCheckStatus>({
|
||||
queryKey: CHECK_QUERY_KEY,
|
||||
queryFn: () => invoke('plugin:yaak-license|check'),
|
||||
});
|
||||
|
||||
return {
|
||||
activate,
|
||||
check,
|
||||
} as const;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@yaakapp-internal/template",
|
||||
"name": "@yaakapp-internal/license",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "index.ts"
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-activate"
|
||||
description = "Enables the activate command without any pre-configured scope."
|
||||
commands.allow = ["activate"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-activate"
|
||||
description = "Denies the activate command without any pre-configured scope."
|
||||
commands.deny = ["activate"]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-check"
|
||||
description = "Enables the check command without any pre-configured scope."
|
||||
commands.allow = ["check"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-check"
|
||||
description = "Denies the check command without any pre-configured scope."
|
||||
commands.deny = ["check"]
|
||||
@@ -0,0 +1,68 @@
|
||||
## Default Permission
|
||||
|
||||
Default permissions for the plugin
|
||||
|
||||
- `allow-check`
|
||||
- `allow-activate`
|
||||
|
||||
## Permission Table
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Identifier</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`yaak-license:allow-activate`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Enables the activate command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`yaak-license:deny-activate`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Denies the activate command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`yaak-license:allow-check`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Enables the check command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`yaak-license:deny-check`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Denies the check command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
3
src-tauri/yaak-license/permissions/default.toml
Normal file
3
src-tauri/yaak-license/permissions/default.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[default]
|
||||
description = "Default permissions for the plugin"
|
||||
permissions = ["allow-check", "allow-activate"]
|
||||
325
src-tauri/yaak-license/permissions/schemas/schema.json
Normal file
325
src-tauri/yaak-license/permissions/schemas/schema.json
Normal file
@@ -0,0 +1,325 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PermissionFile",
|
||||
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "The default permission set for the plugin",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/DefaultPermission"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"set": {
|
||||
"description": "A list of permissions sets defined",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionSet"
|
||||
}
|
||||
},
|
||||
"permission": {
|
||||
"description": "A list of inlined permissions",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Permission"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DefaultPermission": {
|
||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PermissionSet": {
|
||||
"description": "A set of direct permissions grouped together under a new name.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description",
|
||||
"identifier",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does.",
|
||||
"type": "string"
|
||||
},
|
||||
"permissions": {
|
||||
"description": "All permissions this set contains.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionKind"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Permission": {
|
||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"identifier"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"description": "The version of the permission.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 1.0
|
||||
},
|
||||
"identifier": {
|
||||
"description": "A unique identifier for the permission.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"description": "Allowed or denied commands when using this permission.",
|
||||
"default": {
|
||||
"allow": [],
|
||||
"deny": []
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope": {
|
||||
"description": "Allowed or denied scoped when using this permission.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Scopes"
|
||||
}
|
||||
]
|
||||
},
|
||||
"platforms": {
|
||||
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Target"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Commands": {
|
||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Allowed command.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Denied command, which takes priority.",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scopes": {
|
||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"description": "Data that defines what is allowed by the scope.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
"deny": {
|
||||
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Value": {
|
||||
"description": "All supported ACL values.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents a null JSON value.",
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`bool`].",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"description": "Represents a valid ACL [`Number`].",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Number"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`String`].",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Represents a list of other [`Value`]s.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Represents a map of [`String`] keys to [`Value`]s.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Value"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Number": {
|
||||
"description": "A valid ACL number.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Represents an [`i64`].",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
{
|
||||
"description": "Represents a [`f64`].",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Target": {
|
||||
"description": "Platform target.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "MacOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"macOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Windows.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"windows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Linux.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Android.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "iOS.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionKind": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Enables the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "allow-activate"
|
||||
},
|
||||
{
|
||||
"description": "Denies the activate command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "deny-activate"
|
||||
},
|
||||
{
|
||||
"description": "Enables the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "allow-check"
|
||||
},
|
||||
{
|
||||
"description": "Denies the check command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "deny-check"
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin",
|
||||
"type": "string",
|
||||
"const": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src-tauri/yaak-license/src/commands.rs
Normal file
37
src-tauri/yaak-license/src/commands.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use crate::errors::Result;
|
||||
use crate::{activate_license, check_license, ActivateLicenseRequestPayload, LicenseCheckStatus};
|
||||
use log::{debug, info};
|
||||
use std::string::ToString;
|
||||
use tauri::{command, AppHandle, Manager, Runtime, WebviewWindow};
|
||||
|
||||
#[command]
|
||||
pub async fn check<R: Runtime>(app_handle: AppHandle<R>) -> Result<LicenseCheckStatus> {
|
||||
debug!("Checking license");
|
||||
check_license(&app_handle).await
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub async fn activate<R: Runtime>(license_key: &str, window: WebviewWindow<R>) -> Result<()> {
|
||||
info!("Activating license {}", license_key);
|
||||
activate_license(
|
||||
&window,
|
||||
ActivateLicenseRequestPayload {
|
||||
license_key: license_key.to_string(),
|
||||
app_platform: get_os().to_string(),
|
||||
app_version: window.app_handle().package_info().version.to_string(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn get_os() -> &'static str {
|
||||
if cfg!(target_os = "windows") {
|
||||
"windows"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"macos"
|
||||
} else if cfg!(target_os = "linux") {
|
||||
"linux"
|
||||
} else {
|
||||
"unknown"
|
||||
}
|
||||
}
|
||||
28
src-tauri/yaak-license/src/errors.rs
Normal file
28
src-tauri/yaak-license/src/errors.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use serde::{Serialize, Serializer};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("Reqwest error: {0}")]
|
||||
APIError(#[from] reqwest::Error),
|
||||
|
||||
#[error("JSON error: {0}")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
|
||||
#[error("{message}")]
|
||||
ClientError { message: String, error: String },
|
||||
|
||||
#[error("Internal server error")]
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl Serialize for Error {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.to_string().as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
16
src-tauri/yaak-license/src/lib.rs
Normal file
16
src-tauri/yaak-license/src/lib.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use tauri::{
|
||||
generate_handler,
|
||||
plugin::{Builder, TauriPlugin},
|
||||
Runtime,
|
||||
};
|
||||
|
||||
mod commands;
|
||||
mod errors;
|
||||
mod license;
|
||||
|
||||
use crate::commands::{activate, check};
|
||||
pub use license::*;
|
||||
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
Builder::new("yaak-license").invoke_handler(generate_handler![check, activate]).build()
|
||||
}
|
||||
158
src-tauri/yaak-license/src/license.rs
Normal file
158
src-tauri/yaak-license/src/license.rs
Normal file
@@ -0,0 +1,158 @@
|
||||
use crate::errors::Error::{ClientError, ServerError};
|
||||
use crate::errors::Result;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use log::{debug, info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Add;
|
||||
use std::time::Duration;
|
||||
use tauri::{is_dev, AppHandle, Emitter, Runtime, WebviewWindow};
|
||||
use ts_rs::TS;
|
||||
use yaak_models::queries::UpdateSource;
|
||||
|
||||
const KV_NAMESPACE: &str = "license";
|
||||
const KV_ACTIVATION_ID_KEY: &str = "activation_id";
|
||||
const TRIAL_SECONDS: u64 = 3600 * 24 * 14;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct CheckActivationRequestPayload {
|
||||
pub activation_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "license.ts")]
|
||||
pub struct CheckActivationResponsePayload {
|
||||
pub active: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "license.ts")]
|
||||
pub struct ActivateLicenseRequestPayload {
|
||||
pub license_key: String,
|
||||
pub app_version: String,
|
||||
pub app_platform: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "license.ts")]
|
||||
pub struct ActivateLicenseResponsePayload {
|
||||
pub activation_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "license.ts")]
|
||||
pub struct APIErrorResponsePayload {
|
||||
pub error: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
pub async fn activate_license<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
p: ActivateLicenseRequestPayload,
|
||||
) -> Result<()> {
|
||||
let client = reqwest::Client::new();
|
||||
let response = client.post(build_url("/activate")).json(&p).send().await?;
|
||||
|
||||
if response.status().is_client_error() {
|
||||
let body: APIErrorResponsePayload = response.json().await?;
|
||||
return Err(ClientError {
|
||||
message: body.message,
|
||||
error: body.error,
|
||||
});
|
||||
}
|
||||
|
||||
if response.status().is_server_error() {
|
||||
return Err(ServerError);
|
||||
}
|
||||
|
||||
let body: ActivateLicenseResponsePayload = response.json().await?;
|
||||
yaak_models::queries::set_key_value_string(
|
||||
window,
|
||||
KV_ACTIVATION_ID_KEY,
|
||||
KV_NAMESPACE,
|
||||
body.activation_id.as_str(),
|
||||
&UpdateSource::Window,
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Err(e) = window.emit("license-activated", true) {
|
||||
warn!("Failed to emit check-license event: {}", e);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case", tag = "type")]
|
||||
#[ts(export, export_to = "license.ts")]
|
||||
pub enum LicenseCheckStatus {
|
||||
PersonalUse { trial_ended: NaiveDateTime },
|
||||
CommercialUse,
|
||||
InvalidLicense,
|
||||
Trialing { end: NaiveDateTime },
|
||||
}
|
||||
|
||||
pub async fn check_license<R: Runtime>(app_handle: &AppHandle<R>) -> Result<LicenseCheckStatus> {
|
||||
let activation_id = yaak_models::queries::get_key_value_string(
|
||||
app_handle,
|
||||
KV_ACTIVATION_ID_KEY,
|
||||
KV_NAMESPACE,
|
||||
"",
|
||||
)
|
||||
.await;
|
||||
|
||||
let settings = yaak_models::queries::get_or_create_settings(app_handle).await;
|
||||
let trial_end = settings.created_at.add(Duration::from_secs(TRIAL_SECONDS));
|
||||
|
||||
debug!("Trial ending at {trial_end:?}");
|
||||
|
||||
let has_activation_id = !activation_id.is_empty();
|
||||
let trial_period_active = Utc::now().naive_utc() < trial_end;
|
||||
|
||||
match (has_activation_id, trial_period_active) {
|
||||
(false, true) => Ok(LicenseCheckStatus::Trialing { end: trial_end }),
|
||||
(false, false) => Ok(LicenseCheckStatus::PersonalUse {
|
||||
trial_ended: trial_end,
|
||||
}),
|
||||
(true, _) => {
|
||||
info!("Checking license activation");
|
||||
// A license has been activated, so let's check the license server
|
||||
let client = reqwest::Client::new();
|
||||
let payload = CheckActivationRequestPayload {
|
||||
activation_id: activation_id.clone(),
|
||||
};
|
||||
let response = client.post(build_url("/check")).json(&payload).send().await?;
|
||||
|
||||
if response.status().is_client_error() {
|
||||
let body: APIErrorResponsePayload = response.json().await?;
|
||||
return Err(ClientError {
|
||||
message: body.message,
|
||||
error: body.error,
|
||||
});
|
||||
}
|
||||
|
||||
if response.status().is_server_error() {
|
||||
return Err(ServerError);
|
||||
}
|
||||
|
||||
let body: CheckActivationResponsePayload = response.json().await?;
|
||||
if !body.active {
|
||||
return Ok(LicenseCheckStatus::InvalidLicense);
|
||||
}
|
||||
|
||||
Ok(LicenseCheckStatus::CommercialUse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_url(path: &str) -> String {
|
||||
if is_dev() {
|
||||
format!("http://localhost:9444/licenses{path}")
|
||||
} else {
|
||||
format!("https://license.yaak.app/licenses{path}")
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
[package]
|
||||
name = "yaak_models"
|
||||
name = "yaak-models"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
rusqlite = { version = "0.31.0", features = ["bundled", "chrono"] }
|
||||
sea-query = { version = "0.31.0", features = ["with-chrono", "attr"] }
|
||||
sea-query-rusqlite = { version = "0.6.0", features = ["with-chrono"] }
|
||||
log = "0.4.22"
|
||||
nanoid = "0.4.0"
|
||||
r2d2 = "0.8.10"
|
||||
r2d2_sqlite = { version = "0.25.0" }
|
||||
rusqlite = { version = "0.32.1", features = ["bundled", "chrono"] }
|
||||
sea-query = { version = "0.32.1", features = ["with-chrono", "attr"] }
|
||||
sea-query-rusqlite = { version = "0.7.0", features = ["with-chrono"] }
|
||||
serde = { version = "1.0.204", features = ["derive"] }
|
||||
serde_json = "1.0.122"
|
||||
thiserror = "1.0.63"
|
||||
ts-rs = { version = "10.0.0", features = ["chrono-impl", "serde-json-impl"] }
|
||||
tauri = { workspace = true }
|
||||
sqlx = { version = "0.8.0", features = ["sqlite", "runtime-tokio-rustls"] }
|
||||
log = "0.4.22"
|
||||
rand = "0.8.5"
|
||||
r2d2 = "0.8.10"
|
||||
r2d2_sqlite = { version = "0.24.0" }
|
||||
tauri = { workspace = true }
|
||||
thiserror = "1.0.63"
|
||||
ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] }
|
||||
@@ -1,6 +1,6 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type AnyModel = CookieJar | Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | Plugin | Settings | KeyValue | Workspace;
|
||||
export type AnyModel = CookieJar | Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | Plugin | Settings | KeyValue | Workspace | WorkspaceMeta;
|
||||
|
||||
export type Cookie = { raw_cookie: string, domain: CookieDomain, expires: CookieExpires, path: [string, boolean], };
|
||||
|
||||
@@ -10,11 +10,13 @@ export type CookieExpires = { "AtUtc": string } | "SessionEnd";
|
||||
|
||||
export type CookieJar = { model: "cookie_jar", id: string, createdAt: string, updatedAt: string, workspaceId: string, cookies: Array<Cookie>, name: string, };
|
||||
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
export type EditorKeymap = "default" | "vim" | "vscode" | "emacs";
|
||||
|
||||
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, };
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, sortPriority: number, };
|
||||
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, };
|
||||
|
||||
export type GrpcConnection = { model: "grpc_connection", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, elapsed: number, error: string | null, method: string, service: string, status: number, state: GrpcConnectionState, trailers: { [key in string]?: string }, url: string, };
|
||||
|
||||
@@ -24,13 +26,13 @@ export type GrpcEvent = { model: "grpc_event", id: string, createdAt: string, up
|
||||
|
||||
export type GrpcEventType = "info" | "error" | "client_message" | "server_message" | "connection_start" | "connection_end";
|
||||
|
||||
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, };
|
||||
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, description: string, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, description: string, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
|
||||
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, };
|
||||
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type HttpResponse = { model: "http_response", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, bodyPath: string | null, contentLength: number | null, elapsed: number, elapsedHeaders: number, error: string | null, headers: Array<HttpResponseHeader>, remoteAddr: string | null, status: number, statusReason: string | null, state: HttpResponseState, url: string, version: string | null, };
|
||||
|
||||
@@ -38,16 +40,26 @@ export type HttpResponseHeader = { name: string, value: string, };
|
||||
|
||||
export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||
|
||||
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, };
|
||||
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, key: string, namespace: string, value: string, };
|
||||
|
||||
export type ModelPayload = { model: AnyModel, windowLabel: string, updateSource: UpdateSource, };
|
||||
|
||||
export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, };
|
||||
|
||||
export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" };
|
||||
|
||||
export type ProxySettingAuth = { user: string, password: string, };
|
||||
|
||||
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, proxy: ProxySetting | null, };
|
||||
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, proxy: ProxySetting | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, editorKeymap: EditorKeymap, };
|
||||
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
export type SyncHistory = { model: "sync_history", id: string, workspaceId: string, createdAt: string, states: Array<SyncState>, checksum: string, relPath: string, syncDir: string, };
|
||||
|
||||
export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, };
|
||||
|
||||
export type UpdateSource = "sync" | "window" | "plugin" | "background";
|
||||
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
|
||||
export type WorkspaceMeta = { model: "workspace_meta", id: string, workspaceId: string, createdAt: string, updatedAt: string, settingSyncDir: string | null, };
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod error;
|
||||
pub mod models;
|
||||
pub mod queries;
|
||||
mod error;
|
||||
|
||||
pub mod plugin;
|
||||
pub mod plugin;
|
||||
@@ -1,9 +1,11 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use rusqlite::Row;
|
||||
use sea_query::Iden;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
@@ -26,6 +28,48 @@ pub struct ProxySettingAuth {
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum EditorKeymap {
|
||||
Default,
|
||||
Vim,
|
||||
Vscode,
|
||||
Emacs,
|
||||
}
|
||||
|
||||
impl FromStr for EditorKeymap {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"default" => Ok(Self::Default),
|
||||
"vscode" => Ok(Self::Vscode),
|
||||
"vim" => Ok(Self::Vim),
|
||||
"emacs" => Ok(Self::Emacs),
|
||||
_ => Ok(Self::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for EditorKeymap {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let str = match self {
|
||||
EditorKeymap::Default => "default".to_string(),
|
||||
EditorKeymap::Vscode => "vscode".to_string(),
|
||||
EditorKeymap::Vim => "vim".to_string(),
|
||||
EditorKeymap::Emacs => "emacs".to_string(),
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EditorKeymap {
|
||||
fn default() -> Self {
|
||||
Self::Default
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
@@ -42,12 +86,13 @@ pub struct Settings {
|
||||
pub interface_font_size: i32,
|
||||
pub interface_scale: f32,
|
||||
pub open_workspace_new_window: Option<bool>,
|
||||
pub proxy: Option<ProxySetting>,
|
||||
pub telemetry: bool,
|
||||
pub theme: String,
|
||||
pub theme_dark: String,
|
||||
pub theme_light: String,
|
||||
pub update_channel: String,
|
||||
pub proxy: Option<ProxySetting>,
|
||||
pub editor_keymap: EditorKeymap,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
@@ -61,6 +106,7 @@ pub enum SettingsIden {
|
||||
|
||||
Appearance,
|
||||
EditorFontSize,
|
||||
EditorKeymap,
|
||||
EditorSoftWrap,
|
||||
InterfaceFontSize,
|
||||
InterfaceScale,
|
||||
@@ -78,6 +124,7 @@ impl<'s> TryFrom<&Row<'s>> for Settings {
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
let proxy: Option<String> = r.get("proxy")?;
|
||||
let editor_keymap: String = r.get("editor_keymap")?;
|
||||
Ok(Settings {
|
||||
id: r.get("id")?,
|
||||
model: r.get("model")?,
|
||||
@@ -85,6 +132,7 @@ impl<'s> TryFrom<&Row<'s>> for Settings {
|
||||
updated_at: r.get("updated_at")?,
|
||||
appearance: r.get("appearance")?,
|
||||
editor_font_size: r.get("editor_font_size")?,
|
||||
editor_keymap: EditorKeymap::from_str(editor_keymap.as_str()).unwrap(),
|
||||
editor_soft_wrap: r.get("editor_soft_wrap")?,
|
||||
interface_font_size: r.get("interface_font_size")?,
|
||||
interface_scale: r.get("interface_scale")?,
|
||||
@@ -110,7 +158,6 @@ pub struct Workspace {
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub variables: Vec<EnvironmentVariable>,
|
||||
|
||||
// Settings
|
||||
#[serde(default = "default_true")]
|
||||
@@ -134,14 +181,12 @@ pub enum WorkspaceIden {
|
||||
SettingFollowRedirects,
|
||||
SettingRequestTimeout,
|
||||
SettingValidateCertificates,
|
||||
Variables,
|
||||
}
|
||||
|
||||
impl<'s> TryFrom<&Row<'s>> for Workspace {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
let variables: String = r.get("variables")?;
|
||||
Ok(Workspace {
|
||||
id: r.get("id")?,
|
||||
model: r.get("model")?,
|
||||
@@ -149,10 +194,9 @@ impl<'s> TryFrom<&Row<'s>> for Workspace {
|
||||
updated_at: r.get("updated_at")?,
|
||||
name: r.get("name")?,
|
||||
description: r.get("description")?,
|
||||
variables: serde_json::from_str(variables.as_str()).unwrap_or_default(),
|
||||
setting_validate_certificates: r.get("setting_validate_certificates")?,
|
||||
setting_follow_redirects: r.get("setting_follow_redirects")?,
|
||||
setting_request_timeout: r.get("setting_request_timeout")?,
|
||||
setting_validate_certificates: r.get("setting_validate_certificates")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -169,6 +213,47 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct WorkspaceMeta {
|
||||
#[ts(type = "\"workspace_meta\"")]
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub setting_sync_dir: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum WorkspaceMetaIden {
|
||||
#[iden = "workspace_metas"]
|
||||
Table,
|
||||
Model,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
|
||||
SettingSyncDir,
|
||||
}
|
||||
|
||||
impl<'s> TryFrom<&Row<'s>> for WorkspaceMeta {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
Ok(WorkspaceMeta {
|
||||
id: r.get("id")?,
|
||||
workspace_id: r.get("workspace_id")?,
|
||||
model: r.get("model")?,
|
||||
created_at: r.get("created_at")?,
|
||||
updated_at: r.get("updated_at")?,
|
||||
setting_sync_dir: r.get("setting_sync_dir")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
enum CookieDomain {
|
||||
@@ -248,6 +333,7 @@ pub struct Environment {
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub environment_id: Option<String>,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
|
||||
@@ -263,6 +349,7 @@ pub enum EnvironmentIden {
|
||||
Id,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
EnvironmentId,
|
||||
WorkspaceId,
|
||||
|
||||
Name,
|
||||
@@ -278,6 +365,7 @@ impl<'s> TryFrom<&Row<'s>> for Environment {
|
||||
id: r.get("id")?,
|
||||
model: r.get("model")?,
|
||||
workspace_id: r.get("workspace_id")?,
|
||||
environment_id: r.get("environment_id")?,
|
||||
created_at: r.get("created_at")?,
|
||||
updated_at: r.get("updated_at")?,
|
||||
name: r.get("name")?,
|
||||
@@ -295,6 +383,7 @@ pub struct EnvironmentVariable {
|
||||
pub enabled: bool,
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
@@ -310,6 +399,7 @@ pub struct Folder {
|
||||
pub folder_id: Option<String>,
|
||||
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub sort_priority: f32,
|
||||
}
|
||||
|
||||
@@ -325,6 +415,7 @@ pub enum FolderIden {
|
||||
UpdatedAt,
|
||||
|
||||
Name,
|
||||
Description,
|
||||
SortPriority,
|
||||
}
|
||||
|
||||
@@ -341,6 +432,7 @@ impl<'s> TryFrom<&Row<'s>> for Folder {
|
||||
updated_at: r.get("updated_at")?,
|
||||
folder_id: r.get("folder_id")?,
|
||||
name: r.get("name")?,
|
||||
description: r.get("description")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -354,6 +446,7 @@ pub struct HttpRequestHeader {
|
||||
pub enabled: bool,
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
@@ -365,6 +458,7 @@ pub struct HttpUrlParameter {
|
||||
pub enabled: bool,
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
@@ -385,6 +479,7 @@ pub struct HttpRequest {
|
||||
#[ts(type = "Record<string, any>")]
|
||||
pub body: BTreeMap<String, Value>,
|
||||
pub body_type: Option<String>,
|
||||
pub description: String,
|
||||
pub headers: Vec<HttpRequestHeader>,
|
||||
#[serde(default = "default_http_request_method")]
|
||||
pub method: String,
|
||||
@@ -409,6 +504,7 @@ pub enum HttpRequestIden {
|
||||
AuthenticationType,
|
||||
Body,
|
||||
BodyType,
|
||||
Description,
|
||||
Headers,
|
||||
Method,
|
||||
Name,
|
||||
@@ -437,6 +533,7 @@ impl<'s> TryFrom<&Row<'s>> for HttpRequest {
|
||||
method: r.get("method")?,
|
||||
body: serde_json::from_str(body.as_str()).unwrap_or_default(),
|
||||
body_type: r.get("body_type")?,
|
||||
description: r.get("description")?,
|
||||
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
|
||||
authentication_type: r.get("authentication_type")?,
|
||||
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
|
||||
@@ -567,6 +664,7 @@ pub struct GrpcMetadataEntry {
|
||||
pub enabled: bool,
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
@@ -584,6 +682,7 @@ pub struct GrpcRequest {
|
||||
pub authentication_type: Option<String>,
|
||||
#[ts(type = "Record<string, any>")]
|
||||
pub authentication: BTreeMap<String, Value>,
|
||||
pub description: String,
|
||||
pub message: String,
|
||||
pub metadata: Vec<GrpcMetadataEntry>,
|
||||
pub method: Option<String>,
|
||||
@@ -606,6 +705,7 @@ pub enum GrpcRequestIden {
|
||||
|
||||
Authentication,
|
||||
AuthenticationType,
|
||||
Description,
|
||||
Message,
|
||||
Metadata,
|
||||
Method,
|
||||
@@ -629,6 +729,7 @@ impl<'s> TryFrom<&Row<'s>> for GrpcRequest {
|
||||
updated_at: r.get("updated_at")?,
|
||||
folder_id: r.get("folder_id")?,
|
||||
name: r.get("name")?,
|
||||
description: r.get("description")?,
|
||||
service: r.get("service")?,
|
||||
method: r.get("method")?,
|
||||
message: r.get("message")?,
|
||||
@@ -852,6 +953,76 @@ impl<'s> TryFrom<&Row<'s>> for Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct SyncState {
|
||||
#[ts(type = "\"sync_state\"")]
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub flushed_at: NaiveDateTime,
|
||||
|
||||
pub model_id: String,
|
||||
pub checksum: String,
|
||||
pub rel_path: String,
|
||||
pub sync_dir: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct SyncHistory {
|
||||
#[ts(type = "\"sync_history\"")]
|
||||
pub model: String,
|
||||
pub id: String,
|
||||
pub workspace_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
|
||||
pub states: Vec<SyncState>,
|
||||
pub checksum: String,
|
||||
pub rel_path: String,
|
||||
pub sync_dir: String,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum SyncStateIden {
|
||||
#[iden = "sync_states"]
|
||||
Table,
|
||||
Model,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
|
||||
Checksum,
|
||||
FlushedAt,
|
||||
ModelId,
|
||||
RelPath,
|
||||
SyncDir,
|
||||
}
|
||||
|
||||
impl<'s> TryFrom<&Row<'s>> for SyncState {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
Ok(SyncState {
|
||||
id: r.get("id")?,
|
||||
workspace_id: r.get("workspace_id")?,
|
||||
model: r.get("model")?,
|
||||
created_at: r.get("created_at")?,
|
||||
updated_at: r.get("updated_at")?,
|
||||
flushed_at: r.get("flushed_at")?,
|
||||
checksum: r.get("checksum")?,
|
||||
model_id: r.get("model_id")?,
|
||||
sync_dir: r.get("sync_dir")?,
|
||||
rel_path: r.get("rel_path")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
@@ -913,6 +1084,8 @@ pub enum ModelType {
|
||||
TypeHttpResponse,
|
||||
TypePlugin,
|
||||
TypeWorkspace,
|
||||
TypeWorkspaceMeta,
|
||||
TypeSyncState,
|
||||
}
|
||||
|
||||
impl ModelType {
|
||||
@@ -928,12 +1101,14 @@ impl ModelType {
|
||||
ModelType::TypeHttpResponse => "rs",
|
||||
ModelType::TypePlugin => "pg",
|
||||
ModelType::TypeWorkspace => "wk",
|
||||
ModelType::TypeWorkspaceMeta => "wm",
|
||||
ModelType::TypeSyncState => "ss",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[derive(Debug, Clone, Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum AnyModel {
|
||||
@@ -949,4 +1124,52 @@ pub enum AnyModel {
|
||||
Settings(Settings),
|
||||
KeyValue(KeyValue),
|
||||
Workspace(Workspace),
|
||||
WorkspaceMeta(WorkspaceMeta),
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for AnyModel {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value = Value::deserialize(deserializer)?;
|
||||
let model = value.as_object().unwrap();
|
||||
|
||||
let model = match model.get("model") {
|
||||
Some(m) if m == "http_request" => {
|
||||
AnyModel::HttpRequest(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "grpc_request" => {
|
||||
AnyModel::GrpcRequest(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "workspace" => {
|
||||
AnyModel::Workspace(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "environment" => {
|
||||
AnyModel::Environment(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "folder" => AnyModel::Folder(serde_json::from_value(value).unwrap()),
|
||||
Some(m) if m == "key_value" => {
|
||||
AnyModel::KeyValue(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "grpc_connection" => {
|
||||
AnyModel::GrpcConnection(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "grpc_event" => {
|
||||
AnyModel::GrpcEvent(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "cookie_jar" => {
|
||||
AnyModel::CookieJar(serde_json::from_value(value).unwrap())
|
||||
}
|
||||
Some(m) if m == "plugin" => AnyModel::Plugin(serde_json::from_value(value).unwrap()),
|
||||
Some(m) => {
|
||||
return Err(serde::de::Error::custom(format!("Unknown model {}", m)));
|
||||
}
|
||||
None => {
|
||||
return Err(serde::de::Error::custom("Missing or invalid model"));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(model)
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,14 @@ use r2d2_sqlite::SqliteConnectionManager;
|
||||
use serde::Deserialize;
|
||||
use sqlx::migrate::Migrator;
|
||||
use sqlx::sqlite::SqliteConnectOptions;
|
||||
use sqlx::SqlitePool;
|
||||
use std::fs::{create_dir_all, File};
|
||||
use sqlx::{ConnectOptions, SqlitePool};
|
||||
use std::fs::create_dir_all;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use tauri::async_runtime::Mutex;
|
||||
use tauri::path::BaseDirectory;
|
||||
use tauri::plugin::TauriPlugin;
|
||||
use tauri::{plugin, AppHandle, Manager, Runtime};
|
||||
use tauri::{plugin, AppHandle, Manager, Runtime, Url};
|
||||
|
||||
pub struct SqliteConnection(pub Mutex<Pool<SqliteConnectionManager>>);
|
||||
|
||||
@@ -62,25 +61,17 @@ impl Builder {
|
||||
}
|
||||
}
|
||||
|
||||
async fn must_migrate_db<R: Runtime>(app_handle: &AppHandle<R>, path: &PathBuf) {
|
||||
let app_data_dir = app_handle.path().app_data_dir().unwrap();
|
||||
let sqlite_file_path = app_data_dir.join("db.sqlite");
|
||||
|
||||
info!("Creating database file at {:?}", sqlite_file_path);
|
||||
File::options()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(&sqlite_file_path)
|
||||
.expect("Problem creating database file!");
|
||||
|
||||
fn db_connection_url(sqlite_file_path: &PathBuf) -> Url {
|
||||
let p_string = sqlite_file_path.to_string_lossy().replace(' ', "%20");
|
||||
let url = format!("sqlite://{}?mode=rwc", p_string);
|
||||
Url::parse(&url).unwrap()
|
||||
}
|
||||
|
||||
async fn must_migrate_db<R: Runtime>(app_handle: &AppHandle<R>, sqlite_file_path: &PathBuf) {
|
||||
let url = db_connection_url(sqlite_file_path);
|
||||
info!("Connecting to database at {}", url);
|
||||
let opts = SqliteConnectOptions::from_str(path.to_string_lossy().to_string().as_str()).unwrap();
|
||||
let pool = SqlitePool::connect_with(opts)
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
let opts = SqliteConnectOptions::from_url(&url).unwrap();
|
||||
let pool = SqlitePool::connect_with(opts).await.expect("Failed to connect to database");
|
||||
let p = app_handle
|
||||
.path()
|
||||
.resolve("migrations", BaseDirectory::Resource)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,14 @@
|
||||
[package]
|
||||
name = "yaak_plugin_runtime"
|
||||
name = "yaak-plugins"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
command-group = "5.0.1"
|
||||
dunce = "1.0.4"
|
||||
log = "0.4.21"
|
||||
prost = "0.13.1"
|
||||
rand = "0.8.5"
|
||||
reqwest = { version = "0.12.5", features = ["stream"] }
|
||||
serde = { version = "1.0.198", features = ["derive"] }
|
||||
serde_json = "1.0.113"
|
||||
tauri = { workspace = true }
|
||||
@@ -18,8 +16,8 @@ tauri-plugin-shell = { workspace = true }
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "process"] }
|
||||
tonic = "0.12.1"
|
||||
ts-rs = "10.0.0"
|
||||
thiserror = "1.0.63"
|
||||
yaak_models = { workspace = true }
|
||||
thiserror = "2.0.7"
|
||||
yaak-models = { workspace = true }
|
||||
regex = "1.10.6"
|
||||
path-slash = "0.2.1"
|
||||
|
||||
@@ -114,7 +114,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -132,7 +132,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -158,7 +158,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -176,7 +176,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -198,7 +198,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -222,7 +222,7 @@ name: string,
|
||||
*/
|
||||
optional?: boolean,
|
||||
/**
|
||||
* The label of the input
|
||||
* The label of the input
|
||||
*/
|
||||
label?: string,
|
||||
/**
|
||||
@@ -1,18 +1,18 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
|
||||
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, };
|
||||
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, sortPriority: number, };
|
||||
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, };
|
||||
|
||||
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, };
|
||||
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, description: string, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, description: string, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||
|
||||
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, };
|
||||
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type HttpResponse = { model: "http_response", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, bodyPath: string | null, contentLength: number | null, elapsed: number, elapsedHeaders: number, error: string | null, headers: Array<HttpResponseHeader>, remoteAddr: string | null, status: number, statusReason: string | null, state: HttpResponseState, url: string, version: string | null, };
|
||||
|
||||
@@ -20,6 +20,6 @@ export type HttpResponseHeader = { name: string, value: string, };
|
||||
|
||||
export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||
|
||||
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, };
|
||||
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id: string, };
|
||||
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user