Compare commits

..
Author SHA1 Message Date
Gregory Schier 099dff2945 Screenshots for the Rust filters PR 2026-10-14 21:21:34 -07:00
550 changed files with 0 additions and 81738 deletions

No files matched your search

-6
View File
@@ -1,6 +0,0 @@
node_modules/
dist/
.eslintrc.cjs
.prettierrc.cjs
src-web/postcss.config.cjs
src-web/vite.config.ts
-47
View File
@@ -1,47 +0,0 @@
module.exports = {
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:import/recommended',
'plugin:jsx-a11y/recommended',
'plugin:@typescript-eslint/recommended',
'eslint-config-prettier',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.json'],
},
ignorePatterns: [
'scripts/**/*',
'plugin-runtime/**/*',
'plugin-runtime-types/**/*',
'src-tauri/**/*',
'src-web/tailwind.config.cjs',
'src-web/vite.config.ts',
],
settings: {
react: {
version: 'detect',
},
'import/resolver': {
node: {
paths: ['src-web'],
extensions: ['.ts', '.tsx'],
},
},
},
rules: {
'jsx-a11y/no-autofocus': 'off',
'react/react-in-jsx-scope': 'off',
'import/no-unresolved': 'off',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: true,
fixStyle: 'separate-type-imports',
},
],
},
};
-45
View File
@@ -1,45 +0,0 @@
name: Bug Report
description: "Something isn't working properly in Yaak"
title: "Short description"
labels: ["bug", "needs triage"]
assignees:
- gschier
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report 🤗
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: input
id: version
attributes:
label: Version
description: What version of our software are you running?
placeholder: 2024.8.0
validations:
required: true
- type: dropdown
id: os
attributes:
label: What operating system are you on?
multiple: false
options:
- macOS
- Windows
- Linux
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Feature Request, Question, etc.
url: https://feedback.yaak.app
about: Report all non-bugs to the feedback board 👉🏼
-18
View File
@@ -1,18 +0,0 @@
on:
pull_request:
branches: [develop]
name: CI (JS)
jobs:
test:
name: Lint/Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm test
-36
View File
@@ -1,36 +0,0 @@
on:
pull_request:
branches: [develop]
paths:
- src-tauri/**
- .github/workflows/**
name: CI (Rust)
defaults:
run:
working-directory: src-tauri
jobs:
test:
name: Check/Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- run: cargo check --all
- run: cargo test --all
-112
View File
@@ -1,112 +0,0 @@
name: Generate Artifacts
on:
push:
tags: [ v* ]
env:
YAAK_PLUGINS_DIR: checkout/plugins
jobs:
build-artifacts:
permissions:
contents: write
name: Build
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest' # for Arm-based Macs (M1 and above).
args: '--target aarch64-apple-darwin'
yaak_arch: 'arm64'
- 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.
args: ''
yaak_arch: 'x64'
- platform: 'windows-latest'
args: ''
yaak_arch: 'x64'
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout yaakapp/app
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install NPM Dependencies
run: |
npm ci
- name: Install Protoc for plugin-runtime
uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run lint
run: npm run lint
- name: Checkout yaakapp/plugins
uses: actions/checkout@v4
with:
repository: yaakapp/plugins
path: ${{ env.YAAK_PLUGINS_DIR }}
- name: Set version
run: npm run replace-version
env:
YAAK_VERSION: ${{ github.ref_name }}
- uses: tauri-apps/tauri-action@v0
env:
YAAK_PLUGINS_DIR: ${{ env.YAAK_PLUGINS_DIR }}
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
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 }}
with:
tagName: 'v__VERSION__'
releaseName: 'Release __VERSION__'
releaseBody: 'https://yaak.app/blog/__VERSION__'
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}
-33
View File
@@ -1,33 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.eslintcache
*.sqlite
*.sqlite-*
.cargo
.tmp
tmp
-1
View File
@@ -1 +0,0 @@
20
-4
View File
@@ -1,4 +0,0 @@
node_modules/
dist/
out/
.prettierrc.cjs
-8
View File
@@ -1,8 +0,0 @@
module.exports = {
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 100,
"bracketSpacing": true
}
-19
View File
@@ -1,19 +0,0 @@
## Developer Setup
Development requires the following tools
- [Node.js](https://nodejs.org/en/download/package-manager)
- [Rust](https://www.rust-lang.org/tools/install)
Then, you can run the app.
1. Checkout the [plugins](https://github.com/yaakapp/plugins) repository
2. Run `YAAK_PLUGINS_DIR="..." npm run bootstrap` to fetch external binaries, build local dependencies, etc.
3. Run the desktop app in dev mode `npm start`
## SQLite Migrations
1. From `src-tauri/`, run `sqlx migrate add migration-name`
2. Migrate the DB by running the app (may need to `cargo clean` first)
_Note: Yaak development builds use a separate database location than production releases_
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 Yaak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-16
View File
@@ -1,16 +0,0 @@
# [Yaak API Client](https://yaak.app)
Yaak is a desktop API client for organizing and executing REST, GraphQL, and gRPC
requests. It's built using [Tauri](https://tauri.app), Rust, and ReactJS.
![screenshot](https://github.com/user-attachments/assets/f18e963f-0b68-4ecb-b8b8-cb71aa9aec02)
## Feedback and Bug Reports
Please [Create an Issue](https://github.com/yaakapp/app/issues/new) for bug reports and
submit all other feedback to the [Feedback Board](https://feedback.yaak.app).
## Contribution Policy
Yaak open source, but currently only accepting contributions for bug fixes. See [
`DEVELOPMENT.md`](DEVELOPMENT.md).
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

-14095
View File
File diff suppressed because it is too large. Load diff
-46
View File
@@ -1,46 +0,0 @@
{
"name": "yaak-app",
"private": true,
"version": "0.0.0",
"repository": {
"type": "git",
"url": "git+https://github.com/yaakapp/app.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-web"
],
"scripts": {
"app-build": "tauri build",
"app-dev": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"bootstrap": "run-p bootstrap:* && npm run --workspace plugin-runtime build",
"bootstrap:vendor-node": "node scripts/vendor-node.cjs",
"bootstrap:vendor-plugins": "node scripts/vendor-plugins.cjs",
"bootstrap:vendor-protoc": "node scripts/vendor-protoc.cjs",
"lint": "npm run --workspaces --if-present lint",
"replace-version": "node scripts/replace-version.cjs",
"tauri": "tauri",
"tauri-before-build": "npm run bootstrap && npm run --workspaces --if-present build",
"tauri-before-dev": "npm run --workspaces --if-present dev"
},
"devDependencies": {
"@tauri-apps/cli": "^2.0.0-rc.16",
"@typescript-eslint/eslint-plugin": "^8.5.0",
"@typescript-eslint/parser": "^8.5.0",
"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",
"nodejs-file-downloader": "^4.13.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",
"typescript": "^5.6.2"
}
}
-2
View File
@@ -1,2 +0,0 @@
lib
node_modules
-47
View File
@@ -1,47 +0,0 @@
{
"name": "@yaakapp/api",
"version": "0.1.17",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@yaakapp/api",
"version": "0.1.17",
"dependencies": {
"@types/node": "^22.5.4"
},
"devDependencies": {
"typescript": "^5.6.2"
}
},
"node_modules/@types/node": {
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
}
},
"node_modules/typescript": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"license": "MIT"
}
}
}
-23
View File
@@ -1,23 +0,0 @@
{
"name": "@yaakapp/api",
"version": "0.2.7",
"main": "lib/index.js",
"typings": "./lib/index.d.ts",
"files": [
"lib/**/*"
],
"scripts": {
"build": "run-s build:copy-types build:tsc",
"build:tsc": "tsc",
"build:copy-types": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/*.ts ./src/bindings/",
"prepublishOnly": "npm run build"
},
"dependencies": {
"@types/node": "^22.5.4"
},
"devDependencies": {
"cpy-cli": "^5.0.0",
"npm-run-all": "^4.1.5",
"typescript": "^5.6.2"
}
}
@@ -1,89 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Environment } from "./models";
import type { Folder } from "./models";
import type { GrpcRequest } from "./models";
import type { HttpRequest } from "./models";
import type { HttpResponse } from "./models";
import type { Workspace } from "./models";
export type BootRequest = { dir: string, };
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 | null, };
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: string | null, };
export type Icon = "copy" | "info" | "check_circle" | "alert_triangle";
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, };
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": "show_toast_request" } & ShowToastRequest | { "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 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 | null, icon?: Icon | null, };
export type TemplateFunction = { name: string, args: Array<TemplateFunctionArg>, };
export type TemplateFunctionArg = { "type": "text" } & TemplateFunctionTextArg | { "type": "select" } & TemplateFunctionSelectArg | { "type": "checkbox" } & TemplateFunctionCheckboxArg | { "type": "http_request" } & TemplateFunctionHttpRequestArg;
export type TemplateFunctionBaseArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
export type TemplateFunctionCheckboxArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
export type TemplateFunctionHttpRequestArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
export type TemplateFunctionSelectArg = { options: Array<TemplateFunctionSelectOption>, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
export type TemplateFunctionSelectOption = { name: string, value: string, };
export type TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
@@ -1,23 +0,0 @@
// 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 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 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 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 HttpRequestHeader = { enabled?: boolean, name: string, value: 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, url: string, version: string | null, };
export type HttpResponseHeader = { name: string, value: string, };
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, };
-1
View File
@@ -1 +0,0 @@
export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
-5
View File
@@ -1,5 +0,0 @@
export type * from './plugins';
export type * from './themes';
export * from './bindings/models';
export * from './bindings/events';
@@ -1,28 +0,0 @@
import {
FindHttpResponsesRequest,
FindHttpResponsesResponse,
GetHttpRequestByIdRequest,
GetHttpRequestByIdResponse,
RenderHttpRequestRequest,
RenderHttpRequestResponse,
SendHttpRequestRequest,
SendHttpRequestResponse,
ShowToastRequest,
} from '..';
export type Context = {
clipboard: {
copyText(text: string): void;
};
toast: {
show(args: ShowToastRequest): void;
};
httpRequest: {
send(args: SendHttpRequestRequest): Promise<SendHttpRequestResponse['httpResponse']>;
getById(args: GetHttpRequestByIdRequest): Promise<GetHttpRequestByIdResponse['httpRequest']>;
render(args: RenderHttpRequestRequest): Promise<RenderHttpRequestResponse['httpRequest']>;
};
httpResponse: {
find(args: FindHttpResponsesRequest): Promise<FindHttpResponsesResponse['httpResponses']>;
};
};
@@ -1,13 +0,0 @@
import { Context } from './Context';
export type FilterPluginResponse = string[];
export type FilterPlugin = {
name: string;
description?: string;
canFilter(ctx: Context, args: { mimeType: string }): Promise<boolean>;
onFilter(
ctx: Context,
args: { payload: string; mimeType: string },
): Promise<FilterPluginResponse>;
};
@@ -1,6 +0,0 @@
import { CallHttpRequestActionArgs, HttpRequestAction } from '..';
import { Context } from './Context';
export type HttpRequestActionPlugin = HttpRequestAction & {
onSelect(ctx: Context, args: CallHttpRequestActionArgs): Promise<void> | void;
};
@@ -1,16 +0,0 @@
import { Environment, Folder, HttpRequest, Workspace } from '..';
import { AtLeast } from '../helpers';
import { 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'>[];
};
export type ImporterPlugin = {
name: string;
description?: string;
onImport(ctx: Context, args: { text: string }): Promise<ImportPluginResponse>;
};
@@ -1,6 +0,0 @@
import { CallTemplateFunctionArgs, TemplateFunction } from '..';
import { Context } from './Context';
export type TemplateFunctionPlugin = TemplateFunction & {
onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise<string | null>;
};
@@ -1,8 +0,0 @@
import { Theme } from '../themes';
import { Context } from './Context';
export type ThemePlugin = {
name: string;
description?: string;
getTheme(ctx: Context, fileContents: string): Promise<Theme>;
};
-18
View File
@@ -1,18 +0,0 @@
import { FilterPlugin } from './FilterPlugin';
import { HttpRequestActionPlugin } from './HttpRequestActionPlugin';
import { ImporterPlugin } from './ImporterPlugin';
import { TemplateFunctionPlugin } from './TemplateFunctionPlugin';
import { ThemePlugin } from './ThemePlugin';
export type { Context } from './Context';
/**
* The global structure of a Yaak plugin
*/
export type PluginDefinition = {
importer?: ImporterPlugin;
theme?: ThemePlugin;
filter?: FilterPlugin;
httpRequestActions?: HttpRequestActionPlugin[];
templateFunctions?: TemplateFunctionPlugin[];
};
-44
View File
@@ -1,44 +0,0 @@
export type Colors = {
surface: string;
surfaceHighlight?: string;
surfaceActive?: string;
text: string;
textSubtle?: string;
textSubtlest?: string;
border?: string;
borderSubtle?: string;
borderFocus?: string;
shadow?: string;
backdrop?: string;
selection?: string;
primary?: string;
secondary?: string;
info?: string;
success?: string;
notice?: string;
warning?: string;
danger?: string;
};
export type Theme = Colors & {
id: string;
name: string;
components?: Partial<{
dialog: Partial<Colors>;
menu: Partial<Colors>;
toast: Partial<Colors>;
sidebar: Partial<Colors>;
responsePane: Partial<Colors>;
appHeader: Partial<Colors>;
button: Partial<Colors>;
banner: Partial<Colors>;
placeholder: Partial<Colors>;
urlBar: Partial<Colors>;
editor: Partial<Colors>;
input: Partial<Colors>;
}>;
};
-15
View File
@@ -1,15 +0,0 @@
{
"compilerOptions": {
"module": "node16",
"target": "es6",
"lib": ["es2021"],
"declaration": true,
"declarationDir": "./lib",
"outDir": "./lib",
"strict": true,
"types": ["node"]
},
"files": [
"src/index.ts"
]
}
-3
View File
@@ -1,3 +0,0 @@
build
node_modules
*.blob
-3187
View File
File diff suppressed because it is too large. Load diff
-20
View File
@@ -1,20 +0,0 @@
{
"name": "@yaakapp-internal/plugin-runtime",
"scripts": {
"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"
},
"dependencies": {
"intercept-stdout": "^0.1.2",
"long": "^5.2.3",
"nice-grpc": "^2.1.9",
"protobufjs": "^7.4.0"
},
"devDependencies": {
"@types/intercept-stdout": "^0.1.3",
"grpc-tools": "^1.12.4",
"ts-proto": "^2.2.0"
}
}
-21
View File
@@ -1,21 +0,0 @@
import { InternalEvent } from '@yaakapp/api';
import EventEmitter from 'node:events';
import { EventStreamEvent } from './gen/plugins/runtime';
export class EventChannel {
emitter: EventEmitter = new EventEmitter();
emit(e: InternalEvent) {
this.emitter.emit('__plugin_event__', { event: JSON.stringify(e) });
}
async *listen(): AsyncGenerator<EventStreamEvent> {
while (true) {
yield new Promise<EventStreamEvent>((resolve) => {
this.emitter.once('__plugin_event__', (event: EventStreamEvent) => {
resolve(event);
});
});
}
}
}
-51
View File
@@ -1,51 +0,0 @@
import { InternalEvent } from '@yaakapp/api';
import path from 'node:path';
import { Worker } from 'node:worker_threads';
import { EventChannel } from './EventChannel';
export class PluginHandle {
#worker: Worker;
constructor(
readonly pluginDir: string,
readonly pluginRefId: string,
readonly events: EventChannel,
) {
this.#worker = this.#createWorker();
}
sendToWorker(event: InternalEvent) {
this.#worker.postMessage(event);
}
async terminate() {
await this.#worker.terminate();
}
#createWorker(): Worker {
const workerPath = process.env.YAAK_WORKER_PATH ?? path.join(__dirname, 'index.worker.cjs');
const worker = new Worker(workerPath, {
workerData: { pluginDir: this.pluginDir, pluginRefId: this.pluginRefId },
});
worker.on('message', (e) => this.events.emit(e));
worker.on('error', this.#handleError.bind(this));
worker.on('exit', this.#handleExit.bind(this));
console.log('Created plugin worker for ', this.pluginDir);
return worker;
}
async #handleError(err: Error) {
console.error('Plugin errored', this.pluginDir, err);
}
async #handleExit(code: number) {
if (code === 0) {
console.log('Plugin exited successfully', this.pluginDir);
} else {
console.log('Plugin exited with status', code, this.pluginDir);
}
}
}
-125
View File
@@ -1,125 +0,0 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.0
// protoc v3.19.1
// source: plugins/runtime.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { type CallContext, type CallOptions } from "nice-grpc-common";
export const protobufPackage = "yaak.plugins.runtime";
export interface EventStreamEvent {
event: string;
}
function createBaseEventStreamEvent(): EventStreamEvent {
return { event: "" };
}
export const EventStreamEvent: MessageFns<EventStreamEvent> = {
encode(message: EventStreamEvent, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.event !== "") {
writer.uint32(10).string(message.event);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): EventStreamEvent {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEventStreamEvent();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.event = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): EventStreamEvent {
return { event: isSet(object.event) ? globalThis.String(object.event) : "" };
},
toJSON(message: EventStreamEvent): unknown {
const obj: any = {};
if (message.event !== "") {
obj.event = message.event;
}
return obj;
},
create(base?: DeepPartial<EventStreamEvent>): EventStreamEvent {
return EventStreamEvent.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<EventStreamEvent>): EventStreamEvent {
const message = createBaseEventStreamEvent();
message.event = object.event ?? "";
return message;
},
};
export type PluginRuntimeDefinition = typeof PluginRuntimeDefinition;
export const PluginRuntimeDefinition = {
name: "PluginRuntime",
fullName: "yaak.plugins.runtime.PluginRuntime",
methods: {
eventStream: {
name: "EventStream",
requestType: EventStreamEvent,
requestStream: true,
responseType: EventStreamEvent,
responseStream: true,
options: {},
},
},
} as const;
export interface PluginRuntimeServiceImplementation<CallContextExt = {}> {
eventStream(
request: AsyncIterable<EventStreamEvent>,
context: CallContext & CallContextExt,
): ServerStreamingMethodResult<DeepPartial<EventStreamEvent>>;
}
export interface PluginRuntimeClient<CallOptionsExt = {}> {
eventStream(
request: AsyncIterable<DeepPartial<EventStreamEvent>>,
options?: CallOptions & CallOptionsExt,
): AsyncIterable<EventStreamEvent>;
}
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
export type ServerStreamingMethodResult<Response> = { [Symbol.asyncIterator](): AsyncIterator<Response, void> };
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
fromJSON(object: any): T;
toJSON(message: T): unknown;
create(base?: DeepPartial<T>): T;
fromPartial(object: DeepPartial<T>): T;
}
-48
View File
@@ -1,48 +0,0 @@
import { InternalEvent } from '@yaakapp/api';
import { createChannel, createClient, Status } from 'nice-grpc';
import { EventChannel } from './EventChannel';
import { PluginRuntimeClient, PluginRuntimeDefinition } from './gen/plugins/runtime';
import { PluginHandle } from './PluginHandle';
const port = process.env.PORT || '50051';
const channel = createChannel(`localhost:${port}`);
const client: PluginRuntimeClient = createClient(PluginRuntimeDefinition, channel);
const events = new EventChannel();
const plugins: Record<string, PluginHandle> = {};
(async () => {
try {
for await (const e of client.eventStream(events.listen())) {
const pluginEvent: InternalEvent = JSON.parse(e.event);
// Handle special event to bootstrap plugin
if (pluginEvent.payload.type === 'boot_request') {
const plugin = new PluginHandle(pluginEvent.payload.dir, pluginEvent.pluginRefId, events);
plugins[pluginEvent.pluginRefId] = plugin;
}
// Once booted, forward all events to the plugin worker
const plugin = plugins[pluginEvent.pluginRefId];
if (!plugin) {
console.warn('Failed to get plugin for event by', pluginEvent.pluginRefId);
continue;
}
if (pluginEvent.payload.type === 'terminate_request') {
await plugin.terminate();
console.log('Terminated plugin worker', pluginEvent.pluginRefId);
delete plugins[pluginEvent.pluginRefId];
}
plugin.sendToWorker(pluginEvent);
}
console.log('Stream ended');
} catch (err: any) {
if (err.code === Status.CANCELLED) {
console.log('Stream was cancelled by server');
} else {
console.log('Client stream errored', err);
}
}
})();
-332
View File
@@ -1,332 +0,0 @@
import {
Context,
FindHttpResponsesResponse,
GetHttpRequestByIdResponse,
HttpRequestAction,
ImportResponse,
InternalEvent,
InternalEventPayload,
RenderHttpRequestResponse,
SendHttpRequestResponse,
TemplateFunction,
} from '@yaakapp/api';
import { HttpRequestActionPlugin } from '@yaakapp/api/lib/plugins/HttpRequestActionPlugin';
import { TemplateFunctionPlugin } from '@yaakapp/api/lib/plugins/TemplateFunctionPlugin';
import interceptStdout from 'intercept-stdout';
import * as console from 'node:console';
import { Stats, readFileSync, statSync, watch } from 'node:fs';
import path from 'node:path';
import * as util from 'node:util';
import { parentPort, workerData } from 'node:worker_threads';
async function initialize() {
const { pluginDir, pluginRefId } = workerData;
const pathPkg = path.join(pluginDir, 'package.json');
const pathMod = path.posix.join(pluginDir, 'build', 'index.js');
async function importModule() {
const id = require.resolve(pathMod);
delete require.cache[id];
return require(id);
}
const pkg = JSON.parse(readFileSync(pathPkg, 'utf8'));
prefixStdout(`[plugin][${pkg.name}] %s`);
let mod = await importModule();
const capabilities: string[] = [];
if (typeof mod.pluginHookExport === 'function') capabilities.push('export');
if (typeof mod.pluginHookImport === 'function') capabilities.push('import');
if (typeof mod.pluginHookResponseFilter === 'function') capabilities.push('filter');
console.log('Plugin initialized', pkg.name, capabilities, Object.keys(mod));
function buildEventToSend(
payload: InternalEventPayload,
replyId: string | null = null,
): InternalEvent {
return { pluginRefId, id: genId(), replyId, payload };
}
function sendEmpty(replyId: string | null = null): string {
return sendPayload({ type: 'empty_response' }, replyId);
}
function sendPayload(payload: InternalEventPayload, replyId: string | null): string {
const event = buildEventToSend(payload, replyId);
sendEvent(event);
return event.id;
}
function sendEvent(event: InternalEvent) {
if (event.payload.type !== 'empty_response') {
console.log('Sending event to app', event.id, event.payload.type);
}
parentPort!.postMessage(event);
}
async function sendAndWaitForReply<T extends Omit<InternalEventPayload, 'type'>>(
payload: InternalEventPayload,
): Promise<T> {
// 1. Build event to send
const eventToSend = buildEventToSend(payload, null);
// 2. Spawn listener in background
const promise = new Promise<InternalEventPayload>(async (resolve) => {
const cb = (event: InternalEvent) => {
if (event.replyId === eventToSend.id) {
parentPort!.off('message', cb); // Unlisten, now that we're done
resolve(event.payload); // Not type-safe but oh well
}
};
parentPort!.on('message', cb);
});
// 3. Send the event after we start listening (to prevent race)
sendEvent(eventToSend);
// 4. Return the listener promise
return promise as unknown as Promise<T>;
}
async function reloadModule() {
mod = await importModule();
}
// Reload plugin if JS or package.json changes
const cb = async () => {
await reloadModule();
return sendPayload({ type: 'reload_response' }, null);
};
watchFile(pathMod, cb);
watchFile(pathPkg, cb);
const ctx: Context = {
clipboard: {
async copyText(text) {
await sendAndWaitForReply({ type: 'copy_text_request', text });
},
},
toast: {
async show(args) {
await sendAndWaitForReply({ type: 'show_toast_request', ...args });
},
},
httpResponse: {
async find(args) {
const payload = { type: 'find_http_responses_request', ...args } as const;
const { httpResponses } = await sendAndWaitForReply<FindHttpResponsesResponse>(payload);
return httpResponses;
},
},
httpRequest: {
async getById(args) {
const payload = { type: 'get_http_request_by_id_request', ...args } as const;
const { httpRequest } = await sendAndWaitForReply<GetHttpRequestByIdResponse>(payload);
return httpRequest;
},
async send(args) {
const payload = { type: 'send_http_request_request', ...args } as const;
const { httpResponse } = await sendAndWaitForReply<SendHttpRequestResponse>(payload);
return httpResponse;
},
async render(args) {
const payload = { type: 'render_http_request_request', ...args } as const;
const result = await sendAndWaitForReply<RenderHttpRequestResponse>(payload);
return result.httpRequest;
},
},
};
// Message comes into the plugin to be processed
parentPort!.on('message', async ({ payload, id: replyId }: InternalEvent) => {
try {
if (payload.type === 'boot_request') {
const payload: InternalEventPayload = {
type: 'boot_response',
name: pkg.name,
version: pkg.version,
capabilities,
};
sendPayload(payload, replyId);
return;
}
if (payload.type === 'terminate_request') {
const payload: InternalEventPayload = {
type: 'terminate_response',
};
sendPayload(payload, replyId);
return;
}
if (payload.type === 'import_request' && typeof mod.pluginHookImport === 'function') {
const reply: ImportResponse | null = await mod.pluginHookImport(ctx, payload.content);
if (reply != null) {
const replyPayload: InternalEventPayload = {
type: 'import_response',
resources: reply?.resources,
};
sendPayload(replyPayload, replyId);
return;
} else {
// Continue, to send back an empty reply
}
}
if (
payload.type === 'export_http_request_request' &&
typeof mod.pluginHookExport === 'function'
) {
const reply: string = await mod.pluginHookExport(ctx, payload.httpRequest);
const replyPayload: InternalEventPayload = {
type: 'export_http_request_response',
content: reply,
};
sendPayload(replyPayload, replyId);
return;
}
if (payload.type === 'filter_request' && typeof mod.pluginHookResponseFilter === 'function') {
const reply: string = await mod.pluginHookResponseFilter(ctx, {
filter: payload.filter,
body: payload.content,
});
const replyPayload: InternalEventPayload = {
type: 'filter_response',
content: reply,
};
sendPayload(replyPayload, replyId);
return;
}
if (
payload.type === 'get_http_request_actions_request' &&
Array.isArray(mod.plugin?.httpRequestActions)
) {
const reply: HttpRequestAction[] = mod.plugin.httpRequestActions.map(
(a: HttpRequestActionPlugin) => ({
...a,
// Add everything except onSelect
onSelect: undefined,
}),
);
const replyPayload: InternalEventPayload = {
type: 'get_http_request_actions_response',
pluginRefId,
actions: reply,
};
sendPayload(replyPayload, replyId);
return;
}
if (
payload.type === 'get_template_functions_request' &&
Array.isArray(mod.plugin?.templateFunctions)
) {
const reply: TemplateFunction[] = mod.plugin.templateFunctions.map(
(a: TemplateFunctionPlugin) => ({
...a,
// Add everything except render
onRender: undefined,
}),
);
const replyPayload: InternalEventPayload = {
type: 'get_template_functions_response',
pluginRefId,
functions: reply,
};
sendPayload(replyPayload, replyId);
return;
}
if (
payload.type === 'call_http_request_action_request' &&
Array.isArray(mod.plugin?.httpRequestActions)
) {
const action = mod.plugin.httpRequestActions.find(
(a: HttpRequestActionPlugin) => a.key === payload.key,
);
if (typeof action?.onSelect === 'function') {
await action.onSelect(ctx, payload.args);
sendEmpty(replyId);
return;
}
}
if (
payload.type === 'call_template_function_request' &&
Array.isArray(mod.plugin?.templateFunctions)
) {
const action = mod.plugin.templateFunctions.find(
(a: TemplateFunctionPlugin) => a.name === payload.name,
);
if (typeof action?.onRender === 'function') {
const result = await action.onRender(ctx, payload.args);
sendPayload({ type: 'call_template_function_response', value: result ?? null }, replyId);
return;
}
}
if (payload.type === 'reload_request') {
await reloadModule();
}
} catch (err) {
console.log('Plugin call threw exception', payload.type, err);
// TODO: Return errors to server
}
// No matches, so send back an empty response so the caller doesn't block forever
sendEmpty(replyId);
});
}
initialize().catch((err) => {
console.log('failed to boot plugin', err);
});
function genId(len = 5): string {
const alphabet = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let id = '';
for (let i = 0; i < len; i++) {
id += alphabet[Math.floor(Math.random() * alphabet.length)];
}
return id;
}
function prefixStdout(s: string) {
if (!s.includes('%s')) {
throw new Error('Console prefix must contain a "%s" replacer');
}
interceptStdout((text) => {
const lines = text.split(/\n/);
let newText = '';
for (let i = 0; i < lines.length; i++) {
if (lines[i] == '') continue;
newText += util.format(s, lines[i]) + '\n';
}
return newText.trimEnd();
});
}
const watchedFiles: Record<string, Stats> = {};
/**
* Watch a file and trigger callback on change.
*
* We also track the stat for each file because fs.watch will
* trigger a "change" event when the access date changes
*/
function watchFile(filepath: string, cb: (filepath: string) => void) {
watch(filepath, (_event, _name) => {
const stat = statSync(filepath);
if (stat.mtimeMs !== watchedFiles[filepath]?.mtimeMs) {
cb(filepath);
}
watchedFiles[filepath] = stat;
});
}
-24
View File
@@ -1,24 +0,0 @@
{
"compilerOptions": {
"module": "node16",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es2021",
"lib": ["es2021"],
"noImplicitAny": false,
"moduleResolution": "node16",
"sourceMap": true,
"outDir": "build",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src"
]
}
-11
View File
@@ -1,11 +0,0 @@
syntax = "proto3";
package yaak.plugins.runtime;
service PluginRuntime {
rpc EventStream (stream EventStreamEvent) returns (stream EventStreamEvent);
}
message EventStreamEvent {
string event = 1;
}
-1
View File
@@ -1 +0,0 @@
edition = "2018"
-1
View File
@@ -1 +0,0 @@
tmp-*
-15
View File
@@ -1,15 +0,0 @@
const path = require('path');
const fs = require('fs');
const version = process.env.YAAK_VERSION?.replace('v', '');
if (!version) {
throw new Error('YAAK_VERSION environment variable not set')
}
const tauriConfigPath = path.join(__dirname, '../src-tauri/tauri.conf.json');
const tauriConfig = JSON.parse(fs.readFileSync(tauriConfigPath, 'utf8'));
tauriConfig.version = version;
console.log('Writing version ' + version + ' to ' + tauriConfigPath)
fs.writeFileSync(tauriConfigPath, JSON.stringify(tauriConfig, null, 2));
-78
View File
@@ -1,78 +0,0 @@
const path = require('node:path');
const decompress = require('decompress');
const Downloader = require('nodejs-file-downloader');
const { rmSync, cpSync, mkdirSync, existsSync } = require('node:fs');
const { execSync } = require('node:child_process');
const NODE_VERSION = 'v22.5.1';
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
const LNX_X64 = 'linux_x64';
const WIN_X64 = 'win32_x64';
const URL_MAP = {
[MAC_ARM]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-darwin-arm64.tar.gz`,
[MAC_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-darwin-x64.tar.gz`,
[LNX_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz`,
[WIN_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-win-x64.zip`,
};
const SRC_BIN_MAP = {
[MAC_ARM]: `node-${NODE_VERSION}-darwin-arm64/bin/node`,
[MAC_X64]: `node-${NODE_VERSION}-darwin-x64/bin/node`,
[LNX_X64]: `node-${NODE_VERSION}-linux-x64/bin/node`,
[WIN_X64]: `node-${NODE_VERSION}-win-x64/node.exe`,
};
const DST_BIN_MAP = {
darwin_arm64: 'yaaknode-aarch64-apple-darwin',
darwin_x64: 'yaaknode-x86_64-apple-darwin',
linux_x64: 'yaaknode-x86_64-unknown-linux-gnu',
win32_x64: 'yaaknode-x86_64-pc-windows-msvc.exe',
};
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
const destDir = path.join(__dirname, `..`, 'src-tauri', 'vendored', 'node');
const binDest = path.join(destDir, DST_BIN_MAP[key]);
console.log(`Vendoring NodeJS ${NODE_VERSION} for ${key}`);
if (existsSync(binDest) && tryExecSync(`${binDest} --version`).trim() === NODE_VERSION) {
console.log('NodeJS already vendored');
return;
}
rmSync(destDir, { recursive: true, force: true });
mkdirSync(destDir, { recursive: true });
const url = URL_MAP[key];
const tmpDir = path.join(__dirname, 'tmp-node');
rmSync(tmpDir, { recursive: true, force: true });
(async function () {
// Download GitHub release artifact
const { filePath } = await new Downloader({ url, directory: tmpDir }).download();
// Decompress to the same directory
await decompress(filePath, tmpDir, {});
// Copy binary
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
cpSync(binSrc, binDest);
rmSync(tmpDir, { recursive: true, force: true });
console.log('Downloaded NodeJS to', binDest);
})().catch((err) => {
console.log('Script failed:', err);
process.exit(1);
});
function tryExecSync(cmd) {
try {
return execSync(cmd).toString('utf-8');
} catch (_) {
return '';
}
}
-25
View File
@@ -1,25 +0,0 @@
const { readdirSync, cpSync } = require('node:fs');
const path = require('node:path');
const { execSync } = require('node:child_process');
const pluginsDir = process.env.YAAK_PLUGINS_DIR;
if (!pluginsDir) {
console.log('YAAK_PLUGINS_DIR is not set');
process.exit(1);
}
console.log('Installing Yaak plugins dependencies', pluginsDir);
execSync('npm ci', { cwd: pluginsDir });
console.log('Building Yaak plugins', pluginsDir);
execSync('npm run build', { cwd: pluginsDir });
console.log('Copying Yaak plugins to', pluginsDir);
const pluginsRoot = path.join(pluginsDir, 'plugins');
for (const name of readdirSync(pluginsRoot)) {
const dir = path.join(pluginsRoot, name);
if (name.startsWith('.')) continue;
const destDir = path.join(__dirname, '../src-tauri/vendored/plugins/', name);
console.log(`Copying ${name} to ${destDir}`);
cpSync(path.join(dir, 'package.json'), path.join(destDir, 'package.json'));
cpSync(path.join(dir, 'build/index.js'), path.join(destDir, 'build/index.js'));
}
-79
View File
@@ -1,79 +0,0 @@
const decompress = require('decompress');
const Downloader = require('nodejs-file-downloader');
const path = require('node:path');
const { rmSync, mkdirSync, cpSync, existsSync } = require('node:fs');
const { execSync } = require('node:child_process');
const VERSION = '27.2';
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
const LNX_X64 = 'linux_x64';
const WIN_X64 = 'win32_x64';
const URL_MAP = {
[MAC_ARM]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-osx-aarch_64.zip`,
[MAC_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-osx-x86_64.zip`,
[LNX_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-linux-x86_64.zip`,
[WIN_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-win64.zip`,
};
const SRC_BIN_MAP = {
[MAC_ARM]: 'bin/protoc',
[MAC_X64]: 'bin/protoc',
[LNX_X64]: 'bin/protoc',
[WIN_X64]: 'bin/protoc.exe',
};
const DST_BIN_MAP = {
[MAC_ARM]: 'yaakprotoc-aarch64-apple-darwin',
[MAC_X64]: 'yaakprotoc-x86_64-apple-darwin',
[LNX_X64]: 'yaakprotoc-x86_64-unknown-linux-gnu',
[WIN_X64]: 'yaakprotoc-x86_64-pc-windows-msvc.exe',
};
const dstDir = path.join(__dirname, `..`, 'src-tauri', 'vendored', 'protoc');
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
console.log(`Vendoring protoc ${VERSION} for ${key}`);
const url = URL_MAP[key];
const tmpDir = path.join(__dirname, 'tmp-protoc');
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
const binDst = path.join(dstDir, DST_BIN_MAP[key]);
if (existsSync(binDst) && tryExecSync(`${binDst} --version`).trim().includes(VERSION)) {
console.log('Protoc already vendored');
return;
}
rmSync(tmpDir, { recursive: true, force: true });
rmSync(dstDir, { recursive: true, force: true });
mkdirSync(dstDir, { recursive: true });
(async function () {
// Download GitHub release artifact
const { filePath } = await new Downloader({ url, directory: tmpDir }).download();
// Decompress to the same directory
await decompress(filePath, tmpDir, {});
// Copy binary
cpSync(binSrc, binDst);
// Copy other files
const includeSrc = path.join(tmpDir, 'include');
const includeDst = path.join(dstDir, 'include');
cpSync(includeSrc, includeDst, { recursive: true });
rmSync(tmpDir, { recursive: true, force: true });
console.log('Downloaded protoc to', binDst);
})().catch((err) => console.log('Script failed:', err));
function tryExecSync(cmd) {
try {
return execSync(cmd).toString('utf-8');
} catch (_) {
return '';
}
}
-5
View File
@@ -1,5 +0,0 @@
# Generated by Cargo
# will have compiled files and executables
target/
vendored
-7886
View File
File diff suppressed because it is too large. Load diff
-67
View File
@@ -1,67 +0,0 @@
[workspace]
members = ["yaak_grpc", "yaak_templates", "yaak_plugin_runtime", "yaak_models"]
[package]
name = "yaak-app"
version = "0.0.0"
edition = "2021"
authors = ["Gregory Schier"]
# Produce a library for mobile support
[lib]
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "lib"]
[profile.release]
strip = true # Automatically strip symbols from the binary.
[build-dependencies]
tauri-build = { version = "2.0.0-rc.12", features = [] }
[target.'cfg(target_os = "macos")'.dependencies]
objc = "0.2.7"
cocoa = "0.26.0"
[target.'cfg(target_os = "linux")'.dependencies]
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_models = { workspace = true }
anyhow = "1.0.86"
base64 = "0.22.0"
chrono = { version = "0.4.31", features = ["serde"] }
datetime = "0.5.2"
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_cookie_store = "0.8.0"
serde = { version = "1.0.198", features = ["derive"] }
serde_json = { version = "1.0.116", features = ["raw_value"] }
serde_yaml = "0.9.34"
tauri = { workspace = true }
tauri-plugin-shell = { workspace = true }
tauri-plugin-clipboard-manager = "2.1.0-beta.7"
tauri-plugin-dialog = "2.0.0-rc.7"
tauri-plugin-fs = "2.0.0-rc.5"
tauri-plugin-log = { version = "2.0.0-rc.2", features = ["colored"] }
tauri-plugin-os = "2.0.0-rc.1"
tauri-plugin-updater = "2.0.0-rc.3"
tauri-plugin-window-state = "2.0.0-rc.5"
tokio = { version = "1.36.0", features = ["sync"] }
tokio-stream = "0.1.15"
uuid = "1.7.0"
thiserror = "1.0.61"
mime_guess = "2.0.5"
urlencoding = "2.1.3"
[workspace.dependencies]
yaak_models = { path = "yaak_models" }
yaak_plugin_runtime = { path = "yaak_plugin_runtime" }
tauri-plugin-shell = "2.0.0-rc.3"
tauri = { version = "2.0.0-rc.15", features = ["devtools", "protocol-asset"] }
-3
View File
@@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}
-48
View File
@@ -1,48 +0,0 @@
{
"$schema": "../gen/schemas/capabilities.json",
"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-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"
]
}
-1
View File
@@ -1 +0,0 @@
{"clipboard-manager":{"default_permission":{"identifier":"default","description":"No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n","permissions":[]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-read-image":{"identifier":"allow-read-image","description":"Enables the read_image command without any pre-configured scope.","commands":{"allow":["read_image"],"deny":[]}},"allow-read-text":{"identifier":"allow-read-text","description":"Enables the read_text command without any pre-configured scope.","commands":{"allow":["read_text"],"deny":[]}},"allow-write-html":{"identifier":"allow-write-html","description":"Enables the write_html command without any pre-configured scope.","commands":{"allow":["write_html"],"deny":[]}},"allow-write-image":{"identifier":"allow-write-image","description":"Enables the write_image command without any pre-configured scope.","commands":{"allow":["write_image"],"deny":[]}},"allow-write-text":{"identifier":"allow-write-text","description":"Enables the write_text command without any pre-configured scope.","commands":{"allow":["write_text"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-read-image":{"identifier":"deny-read-image","description":"Denies the read_image command without any pre-configured scope.","commands":{"allow":[],"deny":["read_image"]}},"deny-read-text":{"identifier":"deny-read-text","description":"Denies the read_text command without any pre-configured scope.","commands":{"allow":[],"deny":["read_text"]}},"deny-write-html":{"identifier":"deny-write-html","description":"Denies the write_html command without any pre-configured scope.","commands":{"allow":[],"deny":["write_html"]}},"deny-write-image":{"identifier":"deny-write-image","description":"Denies the write_image command without any pre-configured scope.","commands":{"allow":[],"deny":["write_image"]}},"deny-write-text":{"identifier":"deny-write-text","description":"Denies the write_text command without any pre-configured scope.","commands":{"allow":[],"deny":["write_text"]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command withoutLine truncated
-1
View File
@@ -1 +0,0 @@
{"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-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"]}}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Loaded 100 of 550 files, more files were not shown because too many files have changed in this diff. Show more