mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-19 01:57:41 +01:00
Compare commits
99 Commits
v2024.7.0-
...
v2024.8.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e18933178 | ||
|
|
97a4770464 | ||
|
|
db02dbcaa4 | ||
|
|
badcbc7aef | ||
|
|
4b91601b98 | ||
|
|
93e0202b86 | ||
|
|
e75d6abe33 | ||
|
|
24a4e3494e | ||
|
|
124fb35dcd | ||
|
|
1aa2839c51 | ||
|
|
8d3260f394 | ||
|
|
7e194b9148 | ||
|
|
f4abc1c7cb | ||
|
|
6766bc8f59 | ||
|
|
adda44e861 | ||
|
|
6aab017d3b | ||
|
|
68c1dca9d1 | ||
|
|
066b7ea4f4 | ||
|
|
0763c1b9b8 | ||
|
|
323e27a047 | ||
|
|
bd02206df2 | ||
|
|
3411575ecc | ||
|
|
1193e1d7aa | ||
|
|
1b63f33d43 | ||
|
|
9f04cfb673 | ||
|
|
1fd1a901f8 | ||
|
|
06517417b7 | ||
|
|
d924709b0c | ||
|
|
6d274cea56 | ||
|
|
b95fa25898 | ||
|
|
12f4c2c668 | ||
|
|
e47a2c5fab | ||
|
|
fc279f67a1 | ||
|
|
6ed6e3e0e0 | ||
|
|
b5242b9a3f | ||
|
|
a0950ce5b8 | ||
|
|
1dd8034cf9 | ||
|
|
7e73b680e6 | ||
|
|
352ffe9415 | ||
|
|
e461851f6f | ||
|
|
673f2920a1 | ||
|
|
e4ba408534 | ||
|
|
96ae1d467b | ||
|
|
48c239b7dc | ||
|
|
331f1eb9b9 | ||
|
|
1e9f10a99f | ||
|
|
6eb2cbd582 | ||
|
|
d9a7dba2e2 | ||
|
|
d885e6cb0a | ||
|
|
4cafc30f21 | ||
|
|
598a051bf8 | ||
|
|
965b579eb7 | ||
|
|
d3a6125488 | ||
|
|
7f3492a1f0 | ||
|
|
c3970ba756 | ||
|
|
6f0a0a55a4 | ||
|
|
30fe3ee5cb | ||
|
|
1f637c583a | ||
|
|
3050995fed | ||
|
|
8081c86ec6 | ||
|
|
ed300dd320 | ||
|
|
989b5a8058 | ||
|
|
71013fd701 | ||
|
|
76dd4380ce | ||
|
|
a643713139 | ||
|
|
1cb86bc1b7 | ||
|
|
cc9bd2bc70 | ||
|
|
90bf96c7c1 | ||
|
|
4e4c93c34e | ||
|
|
c2ce446692 | ||
|
|
d1a2c9622d | ||
|
|
ecd8b93bd1 | ||
|
|
dd032a9e4d | ||
|
|
f350f3b5f4 | ||
|
|
45cb1ef0fe | ||
|
|
d586ec5fb4 | ||
|
|
ad8a4933da | ||
|
|
499d0b09ba | ||
|
|
ac1181c1b4 | ||
|
|
b9671781d3 | ||
|
|
42fd7cb21e | ||
|
|
fe9f765c1d | ||
|
|
087a1e5ea1 | ||
|
|
6e156497da | ||
|
|
ad3c2ed113 | ||
|
|
166bae6104 | ||
|
|
b3e6a2b34f | ||
|
|
547f1c9139 | ||
|
|
4d7ded61f8 | ||
|
|
c92472dbac | ||
|
|
d347f2db77 | ||
|
|
80c1675331 | ||
|
|
23fba45fcb | ||
|
|
80777f712c | ||
|
|
6ffb0015c6 | ||
|
|
9d9b855c04 | ||
|
|
e7cbcc7b20 | ||
|
|
20a5ab3666 | ||
|
|
311fda887f |
@@ -1,37 +1,47 @@
|
||||
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"
|
||||
'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",
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.json"]
|
||||
project: ['./tsconfig.json'],
|
||||
},
|
||||
ignorePatterns: ["scripts/**/*", "plugin-runtime/**/*", "src-tauri/**/*", "plugins/**/*"],
|
||||
ignorePatterns: [
|
||||
'scripts/**/*',
|
||||
'plugin-runtime/**/*',
|
||||
'plugin-runtime-types/**/*',
|
||||
'src-tauri/**/*',
|
||||
'plugins/**/*',
|
||||
'tailwind.config.cjs',
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect"
|
||||
version: 'detect',
|
||||
},
|
||||
"import/resolver": {
|
||||
'import/resolver': {
|
||||
node: {
|
||||
paths: ["src-web"],
|
||||
extensions: [".ts", ".tsx"]
|
||||
}
|
||||
}
|
||||
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"
|
||||
}]
|
||||
}
|
||||
'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',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -114,7 +114,7 @@ jobs:
|
||||
with:
|
||||
tagName: 'v__VERSION__'
|
||||
releaseName: 'Release __VERSION__'
|
||||
releaseBody: 'https://yaak.app/changelog/__VERSION__'
|
||||
releaseBody: 'https://yaak.app/blog/__VERSION__'
|
||||
releaseDraft: true
|
||||
prerelease: false
|
||||
args: ${{ matrix.args }}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<envs>
|
||||
<env name="RUST_BACKTRACE" value="1" />
|
||||
</envs>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
</component>
|
||||
@@ -14,3 +14,8 @@ cargo sqlx migrate add ${MIGRATION_NAME}
|
||||
cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
|
||||
cargo sqlx prepare --database-url 'sqlite://db.sqlite'
|
||||
```
|
||||
|
||||
## Add App->Plugin API
|
||||
|
||||
- Add event in `events.rs`
|
||||
- Add handler to `index.worker.ts`
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Yaak App</title>
|
||||
<script src="http://localhost:8097"></script>
|
||||
<!-- <script src="http://localhost:8097"></script>-->
|
||||
|
||||
<!-- Certain elements like webview (and maybe <select>?) will use background
|
||||
color depending on document background color-->
|
||||
|
||||
771
package-lock.json
generated
771
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
28
package.json
28
package.json
@@ -11,14 +11,14 @@
|
||||
"tauri": "tauri",
|
||||
"dev:js": "vite dev",
|
||||
"lint": "tsc && eslint . --ext .ts,.tsx",
|
||||
"build": "run-p build:*",
|
||||
"build:icon:release": "tauri icon design/icon.png --output ./src-tauri/icons/release",
|
||||
"build:icon:dev": "tauri icon design/icon-dev.png --output ./src-tauri/icons/dev",
|
||||
"build": "run-p build:*",
|
||||
"build:js": "vite build",
|
||||
"build:plugin-runtime": "npm run --prefix plugin-runtime build",
|
||||
"build:vendor-protoc": "node scripts/vendor-protoc.cjs",
|
||||
"build:vendor-plugins": "node scripts/vendor-plugins.cjs",
|
||||
"build:vendor-node": "node scripts/vendor-node.cjs",
|
||||
"build:plugin-runtime": "npm run --prefix plugin-runtime build",
|
||||
"prepare": "husky install",
|
||||
"replace-version": "node scripts/replace-version.cjs"
|
||||
},
|
||||
@@ -35,12 +35,14 @@
|
||||
"@react-hook/resize-observer": "^1.2.6",
|
||||
"@tailwindcss/container-queries": "^0.1.0",
|
||||
"@tanstack/react-query": "^5.45.1",
|
||||
"@tauri-apps/api": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.1",
|
||||
"@tauri-apps/plugin-dialog": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-fs": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-os": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/plugin-shell": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/api": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-fs": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
||||
"@yaakapp/api": "^0.1.13",
|
||||
"buffer": "^6.0.3",
|
||||
"classnames": "^2.3.2",
|
||||
"cm6-graphql": "^0.0.9",
|
||||
@@ -51,6 +53,7 @@
|
||||
"focus-trap-react": "^10.1.1",
|
||||
"format-graphql": "^1.4.0",
|
||||
"framer-motion": "^9.0.4",
|
||||
"jotai": "^2.9.3",
|
||||
"lucide-react": "^0.309.0",
|
||||
"mime": "^4.0.1",
|
||||
"papaparse": "^5.4.1",
|
||||
@@ -64,14 +67,13 @@
|
||||
"react-router-dom": "^6.8.1",
|
||||
"react-use": "^17.4.0",
|
||||
"slugify": "^1.6.6",
|
||||
"tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log#v2",
|
||||
"uuid": "^9.0.0",
|
||||
"xml-formatter": "^3.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
|
||||
"@tanstack/react-query-devtools": "^5.45.1",
|
||||
"@tauri-apps/cli": ">=2.0.0-beta.0",
|
||||
"@tauri-apps/cli": "^2.0.0-rc.2",
|
||||
"@types/node": "^18.7.10",
|
||||
"@types/papaparse": "^5.3.7",
|
||||
"@types/parse-color": "^1.0.1",
|
||||
@@ -83,6 +85,7 @@
|
||||
"@typescript-eslint/parser": "^7.0.2",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"decompress": "^4.2.1",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
@@ -92,18 +95,17 @@
|
||||
"husky": "^8.0.3",
|
||||
"internal-ip": "^8.0.0",
|
||||
"lint-staged": "^15.0.2",
|
||||
"nodejs-file-downloader": "^4.13.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss-nesting": "^11.2.1",
|
||||
"prettier": "^2.8.4",
|
||||
"react-devtools": "^4.27.2",
|
||||
"rimraf": "^5.0.7",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-static-copy": "^1.0.5",
|
||||
"decompress": "^4.2.1",
|
||||
"nodejs-file-downloader": "^4.13.0",
|
||||
"rimraf": "^5.0.7",
|
||||
"vite-plugin-svgr": "^4.2.0",
|
||||
"vite-plugin-top-level-await": "^1.4.1"
|
||||
},
|
||||
|
||||
2
plugin-runtime-types/.gitignore
vendored
Normal file
2
plugin-runtime-types/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
lib
|
||||
node_modules
|
||||
44
plugin-runtime-types/package-lock.json
generated
Normal file
44
plugin-runtime-types/package-lock.json
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@yaakapp/api",
|
||||
"version": "0.1.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@yaakapp/api",
|
||||
"version": "0.1.11",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
|
||||
"integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.11.1"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.11.1",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
|
||||
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
19
plugin-runtime-types/package.json
Normal file
19
plugin-runtime-types/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@yaakapp/api",
|
||||
"version": "0.1.13",
|
||||
"main": "lib/index.js",
|
||||
"typings": "./lib/index.d.ts",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^22.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
3
plugin-runtime-types/src/gen/BootRequest.ts
Normal file
3
plugin-runtime-types/src/gen/BootRequest.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 BootRequest = { dir: string, };
|
||||
3
plugin-runtime-types/src/gen/BootResponse.ts
Normal file
3
plugin-runtime-types/src/gen/BootResponse.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 BootResponse = { name: string, version: string, capabilities: Array<string>, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
|
||||
export type CallHttpRequestActionArgs = { httpRequest: HttpRequest, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { CallHttpRequestActionArgs } from "./CallHttpRequestActionArgs";
|
||||
|
||||
export type CallHttpRequestActionRequest = { key: string, pluginRefId: string, args: CallHttpRequestActionArgs, };
|
||||
4
plugin-runtime-types/src/gen/CallTemplateFunctionArgs.ts
Normal file
4
plugin-runtime-types/src/gen/CallTemplateFunctionArgs.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { RenderPurpose } from "./RenderPurpose";
|
||||
|
||||
export type CallTemplateFunctionArgs = { purpose: RenderPurpose, values: { [key: string]: string }, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { CallTemplateFunctionArgs } from "./CallTemplateFunctionArgs";
|
||||
|
||||
export type CallTemplateFunctionRequest = { name: string, args: CallTemplateFunctionArgs, };
|
||||
@@ -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 CallTemplateFunctionResponse = { value: string | null, };
|
||||
5
plugin-runtime-types/src/gen/Cookie.ts
Normal file
5
plugin-runtime-types/src/gen/Cookie.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.
|
||||
import type { CookieDomain } from "./CookieDomain";
|
||||
import type { CookieExpires } from "./CookieExpires";
|
||||
|
||||
export type Cookie = { raw_cookie: string, domain: CookieDomain, expires: CookieExpires, path: [string, boolean], };
|
||||
3
plugin-runtime-types/src/gen/CookieDomain.ts
Normal file
3
plugin-runtime-types/src/gen/CookieDomain.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 CookieDomain = { "HostOnly": string } | { "Suffix": string } | "NotPresent" | "Empty";
|
||||
3
plugin-runtime-types/src/gen/CookieExpires.ts
Normal file
3
plugin-runtime-types/src/gen/CookieExpires.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 CookieExpires = { "AtUtc": string } | "SessionEnd";
|
||||
4
plugin-runtime-types/src/gen/CookieJar.ts
Normal file
4
plugin-runtime-types/src/gen/CookieJar.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { Cookie } from "./Cookie";
|
||||
|
||||
export type CookieJar = { id: string, model: "cookie_jar", createdAt: string, updatedAt: string, workspaceId: string, name: string, cookies: Array<Cookie>, };
|
||||
3
plugin-runtime-types/src/gen/CopyTextRequest.ts
Normal file
3
plugin-runtime-types/src/gen/CopyTextRequest.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 CopyTextRequest = { text: string, };
|
||||
3
plugin-runtime-types/src/gen/EmptyResponse.ts
Normal file
3
plugin-runtime-types/src/gen/EmptyResponse.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 EmptyResponse = {};
|
||||
4
plugin-runtime-types/src/gen/Environment.ts
Normal file
4
plugin-runtime-types/src/gen/Environment.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { EnvironmentVariable } from "./EnvironmentVariable";
|
||||
|
||||
export type Environment = { id: string, workspaceId: string, model: "environment", createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||
3
plugin-runtime-types/src/gen/EnvironmentVariable.ts
Normal file
3
plugin-runtime-types/src/gen/EnvironmentVariable.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 EnvironmentVariable = { enabled?: boolean, name: string, value: string, };
|
||||
4
plugin-runtime-types/src/gen/ExportHttpRequestRequest.ts
Normal file
4
plugin-runtime-types/src/gen/ExportHttpRequestRequest.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
|
||||
export type ExportHttpRequestRequest = { httpRequest: HttpRequest, };
|
||||
@@ -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 ExportHttpRequestResponse = { content: string, };
|
||||
3
plugin-runtime-types/src/gen/FilterRequest.ts
Normal file
3
plugin-runtime-types/src/gen/FilterRequest.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 FilterRequest = { content: string, filter: string, };
|
||||
3
plugin-runtime-types/src/gen/FilterResponse.ts
Normal file
3
plugin-runtime-types/src/gen/FilterResponse.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 FilterResponse = { content: string, };
|
||||
3
plugin-runtime-types/src/gen/FindHttpResponsesRequest.ts
Normal file
3
plugin-runtime-types/src/gen/FindHttpResponsesRequest.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 FindHttpResponsesRequest = { requestId: string, limit: number | null, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpResponse } from "./HttpResponse";
|
||||
|
||||
export type FindHttpResponsesResponse = { httpResponses: Array<HttpResponse>, };
|
||||
3
plugin-runtime-types/src/gen/Folder.ts
Normal file
3
plugin-runtime-types/src/gen/Folder.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 Folder = { createdAt: string, updatedAt: string, id: string, workspaceId: string, folderId: string | null, model: "folder", name: string, sortPriority: number, };
|
||||
@@ -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 GetHttpRequestActionsRequest = Record<string, never>;
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequestAction } from "./HttpRequestAction";
|
||||
|
||||
export type GetHttpRequestActionsResponse = { actions: Array<HttpRequestAction>, pluginRefId: string, };
|
||||
@@ -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 GetHttpRequestByIdRequest = { id: string, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
|
||||
export type GetHttpRequestByIdResponse = { httpRequest: HttpRequest | null, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { TemplateFunction } from "./TemplateFunction";
|
||||
|
||||
export type GetTemplateFunctionsResponse = { functions: Array<TemplateFunction>, pluginRefId: string, };
|
||||
3
plugin-runtime-types/src/gen/GrpcConnection.ts
Normal file
3
plugin-runtime-types/src/gen/GrpcConnection.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 GrpcConnection = { id: string, model: "grpc_connection", workspaceId: string, requestId: string, createdAt: string, updatedAt: string, service: string, method: string, elapsed: number, status: number, url: string, error: string | null, trailers: { [key: string]: string }, };
|
||||
4
plugin-runtime-types/src/gen/GrpcEvent.ts
Normal file
4
plugin-runtime-types/src/gen/GrpcEvent.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { GrpcEventType } from "./GrpcEventType";
|
||||
|
||||
export type GrpcEvent = { id: string, model: "grpc_event", workspaceId: string, requestId: string, connectionId: string, createdAt: string, content: string, eventType: GrpcEventType, metadata: { [key: string]: string }, status: number | null, error: string | null, };
|
||||
3
plugin-runtime-types/src/gen/GrpcEventType.ts
Normal file
3
plugin-runtime-types/src/gen/GrpcEventType.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 GrpcEventType = "info" | "error" | "client_message" | "server_message" | "connection_start" | "connection_end";
|
||||
3
plugin-runtime-types/src/gen/GrpcMetadataEntry.ts
Normal file
3
plugin-runtime-types/src/gen/GrpcMetadataEntry.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 GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, };
|
||||
4
plugin-runtime-types/src/gen/GrpcRequest.ts
Normal file
4
plugin-runtime-types/src/gen/GrpcRequest.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { GrpcMetadataEntry } from "./GrpcMetadataEntry";
|
||||
|
||||
export type GrpcRequest = { id: string, model: "grpc_request", workspaceId: string, createdAt: string, updatedAt: string, folderId: string | null, name: string, sortPriority: number, url: string, service: string | null, method: string | null, message: string, authenticationType: string | null, authentication: Record<string, any>, metadata: Array<GrpcMetadataEntry>, };
|
||||
5
plugin-runtime-types/src/gen/HttpRequest.ts
Normal file
5
plugin-runtime-types/src/gen/HttpRequest.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.
|
||||
import type { HttpRequestHeader } from "./HttpRequestHeader";
|
||||
import type { HttpUrlParameter } from "./HttpUrlParameter";
|
||||
|
||||
export type HttpRequest = { createdAt: string, updatedAt: string, id: string, workspaceId: string, folderId: string | null, model: "http_request", sortPriority: number, name: string, url: string, urlParameters: Array<HttpUrlParameter>, method: string, body: Record<string, any>, bodyType: string | null, authentication: Record<string, any>, authenticationType: string | null, headers: Array<HttpRequestHeader>, };
|
||||
3
plugin-runtime-types/src/gen/HttpRequestAction.ts
Normal file
3
plugin-runtime-types/src/gen/HttpRequestAction.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 HttpRequestAction = { key: string, label: string, icon: string | null, };
|
||||
3
plugin-runtime-types/src/gen/HttpRequestHeader.ts
Normal file
3
plugin-runtime-types/src/gen/HttpRequestHeader.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 HttpRequestHeader = { enabled?: boolean, name: string, value: string, };
|
||||
4
plugin-runtime-types/src/gen/HttpResponse.ts
Normal file
4
plugin-runtime-types/src/gen/HttpResponse.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpResponseHeader } from "./HttpResponseHeader";
|
||||
|
||||
export type HttpResponse = { id: string, model: "http_response", workspaceId: string, requestId: string, createdAt: string, updatedAt: string, error: string | null, url: string, contentLength: number | null, version: string | null, elapsed: number, elapsedHeaders: number, remoteAddr: string | null, status: number, statusReason: string | null, bodyPath: string | null, headers: Array<HttpResponseHeader>, };
|
||||
3
plugin-runtime-types/src/gen/HttpResponseHeader.ts
Normal file
3
plugin-runtime-types/src/gen/HttpResponseHeader.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 HttpResponseHeader = { name: string, value: string, };
|
||||
3
plugin-runtime-types/src/gen/HttpUrlParameter.ts
Normal file
3
plugin-runtime-types/src/gen/HttpUrlParameter.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 HttpUrlParameter = { enabled?: boolean, name: string, value: string, };
|
||||
3
plugin-runtime-types/src/gen/ImportRequest.ts
Normal file
3
plugin-runtime-types/src/gen/ImportRequest.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 ImportRequest = { content: string, };
|
||||
8
plugin-runtime-types/src/gen/ImportResources.ts
Normal file
8
plugin-runtime-types/src/gen/ImportResources.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { Environment } from "./Environment";
|
||||
import type { Folder } from "./Folder";
|
||||
import type { GrpcRequest } from "./GrpcRequest";
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
import type { Workspace } from "./Workspace";
|
||||
|
||||
export type ImportResources = { workspaces: Array<Workspace>, environments: Array<Environment>, folders: Array<Folder>, httpRequests: Array<HttpRequest>, grpcRequests: Array<GrpcRequest>, };
|
||||
4
plugin-runtime-types/src/gen/ImportResponse.ts
Normal file
4
plugin-runtime-types/src/gen/ImportResponse.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ImportResources } from "./ImportResources";
|
||||
|
||||
export type ImportResponse = { resources: ImportResources, };
|
||||
4
plugin-runtime-types/src/gen/InternalEvent.ts
Normal file
4
plugin-runtime-types/src/gen/InternalEvent.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { InternalEventPayload } from "./InternalEventPayload";
|
||||
|
||||
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, };
|
||||
28
plugin-runtime-types/src/gen/InternalEventPayload.ts
Normal file
28
plugin-runtime-types/src/gen/InternalEventPayload.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BootRequest } from "./BootRequest";
|
||||
import type { BootResponse } from "./BootResponse";
|
||||
import type { CallHttpRequestActionRequest } from "./CallHttpRequestActionRequest";
|
||||
import type { CallTemplateFunctionRequest } from "./CallTemplateFunctionRequest";
|
||||
import type { CallTemplateFunctionResponse } from "./CallTemplateFunctionResponse";
|
||||
import type { CopyTextRequest } from "./CopyTextRequest";
|
||||
import type { EmptyResponse } from "./EmptyResponse";
|
||||
import type { ExportHttpRequestRequest } from "./ExportHttpRequestRequest";
|
||||
import type { ExportHttpRequestResponse } from "./ExportHttpRequestResponse";
|
||||
import type { FilterRequest } from "./FilterRequest";
|
||||
import type { FilterResponse } from "./FilterResponse";
|
||||
import type { FindHttpResponsesRequest } from "./FindHttpResponsesRequest";
|
||||
import type { FindHttpResponsesResponse } from "./FindHttpResponsesResponse";
|
||||
import type { GetHttpRequestActionsRequest } from "./GetHttpRequestActionsRequest";
|
||||
import type { GetHttpRequestActionsResponse } from "./GetHttpRequestActionsResponse";
|
||||
import type { GetHttpRequestByIdRequest } from "./GetHttpRequestByIdRequest";
|
||||
import type { GetHttpRequestByIdResponse } from "./GetHttpRequestByIdResponse";
|
||||
import type { GetTemplateFunctionsResponse } from "./GetTemplateFunctionsResponse";
|
||||
import type { ImportRequest } from "./ImportRequest";
|
||||
import type { ImportResponse } from "./ImportResponse";
|
||||
import type { RenderHttpRequestRequest } from "./RenderHttpRequestRequest";
|
||||
import type { RenderHttpRequestResponse } from "./RenderHttpRequestResponse";
|
||||
import type { SendHttpRequestRequest } from "./SendHttpRequestRequest";
|
||||
import type { SendHttpRequestResponse } from "./SendHttpRequestResponse";
|
||||
import type { ShowToastRequest } from "./ShowToastRequest";
|
||||
|
||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "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" } & EmptyResponse;
|
||||
3
plugin-runtime-types/src/gen/KeyValue.ts
Normal file
3
plugin-runtime-types/src/gen/KeyValue.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 KeyValue = { model: "key_value", createdAt: string, updatedAt: string, namespace: string, key: string, value: string, };
|
||||
14
plugin-runtime-types/src/gen/Model.ts
Normal file
14
plugin-runtime-types/src/gen/Model.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { CookieJar } from "./CookieJar";
|
||||
import type { Environment } from "./Environment";
|
||||
import type { Folder } from "./Folder";
|
||||
import type { GrpcConnection } from "./GrpcConnection";
|
||||
import type { GrpcEvent } from "./GrpcEvent";
|
||||
import type { GrpcRequest } from "./GrpcRequest";
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
import type { HttpResponse } from "./HttpResponse";
|
||||
import type { KeyValue } from "./KeyValue";
|
||||
import type { Settings } from "./Settings";
|
||||
import type { Workspace } from "./Workspace";
|
||||
|
||||
export type Model = Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | KeyValue | Workspace | CookieJar | Settings;
|
||||
5
plugin-runtime-types/src/gen/RenderHttpRequestRequest.ts
Normal file
5
plugin-runtime-types/src/gen/RenderHttpRequestRequest.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.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
import type { RenderPurpose } from "./RenderPurpose";
|
||||
|
||||
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, purpose: RenderPurpose, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
|
||||
export type RenderHttpRequestResponse = { httpRequest: HttpRequest, };
|
||||
3
plugin-runtime-types/src/gen/RenderPurpose.ts
Normal file
3
plugin-runtime-types/src/gen/RenderPurpose.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 RenderPurpose = "send" | "preview";
|
||||
3
plugin-runtime-types/src/gen/RenderRequest.ts
Normal file
3
plugin-runtime-types/src/gen/RenderRequest.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 RenderRequest = { template: string, };
|
||||
3
plugin-runtime-types/src/gen/RenderResponse.ts
Normal file
3
plugin-runtime-types/src/gen/RenderResponse.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 RenderResponse = { rendered: string, };
|
||||
4
plugin-runtime-types/src/gen/SendHttpRequestRequest.ts
Normal file
4
plugin-runtime-types/src/gen/SendHttpRequestRequest.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpRequest } from "./HttpRequest";
|
||||
|
||||
export type SendHttpRequestRequest = { httpRequest: HttpRequest, };
|
||||
4
plugin-runtime-types/src/gen/SendHttpRequestResponse.ts
Normal file
4
plugin-runtime-types/src/gen/SendHttpRequestResponse.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HttpResponse } from "./HttpResponse";
|
||||
|
||||
export type SendHttpRequestResponse = { httpResponse: HttpResponse, };
|
||||
3
plugin-runtime-types/src/gen/Settings.ts
Normal file
3
plugin-runtime-types/src/gen/Settings.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 Settings = { id: string, model: "settings", createdAt: string, updatedAt: string, theme: string, appearance: string, themeDark: string, themeLight: string, updateChannel: string, interfaceFontSize: number, interfaceScale: number, editorFontSize: number, editorSoftWrap: boolean, telemetry: boolean, openWorkspaceNewWindow: boolean | null, };
|
||||
4
plugin-runtime-types/src/gen/ShowToastRequest.ts
Normal file
4
plugin-runtime-types/src/gen/ShowToastRequest.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ToastVariant } from "./ToastVariant";
|
||||
|
||||
export type ShowToastRequest = { message: string, variant: ToastVariant, };
|
||||
4
plugin-runtime-types/src/gen/TemplateFunction.ts
Normal file
4
plugin-runtime-types/src/gen/TemplateFunction.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { TemplateFunctionArg } from "./TemplateFunctionArg";
|
||||
|
||||
export type TemplateFunction = { name: string, args: Array<TemplateFunctionArg>, };
|
||||
7
plugin-runtime-types/src/gen/TemplateFunctionArg.ts
Normal file
7
plugin-runtime-types/src/gen/TemplateFunctionArg.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { TemplateFunctionCheckboxArg } from "./TemplateFunctionCheckboxArg";
|
||||
import type { TemplateFunctionHttpRequestArg } from "./TemplateFunctionHttpRequestArg";
|
||||
import type { TemplateFunctionSelectArg } from "./TemplateFunctionSelectArg";
|
||||
import type { TemplateFunctionTextArg } from "./TemplateFunctionTextArg";
|
||||
|
||||
export type TemplateFunctionArg = { "type": "text" } & TemplateFunctionTextArg | { "type": "select" } & TemplateFunctionSelectArg | { "type": "checkbox" } & TemplateFunctionCheckboxArg | { "type": "http_request" } & TemplateFunctionHttpRequestArg;
|
||||
3
plugin-runtime-types/src/gen/TemplateFunctionBaseArg.ts
Normal file
3
plugin-runtime-types/src/gen/TemplateFunctionBaseArg.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 TemplateFunctionBaseArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||
@@ -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 TemplateFunctionCheckboxArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||
@@ -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 TemplateFunctionHttpRequestArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { TemplateFunctionSelectOption } from "./TemplateFunctionSelectOption";
|
||||
|
||||
export type TemplateFunctionSelectArg = { options: Array<TemplateFunctionSelectOption>, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||
@@ -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 TemplateFunctionSelectOption = { name: string, value: string, };
|
||||
3
plugin-runtime-types/src/gen/TemplateFunctionTextArg.ts
Normal file
3
plugin-runtime-types/src/gen/TemplateFunctionTextArg.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 TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||
3
plugin-runtime-types/src/gen/ToastVariant.ts
Normal file
3
plugin-runtime-types/src/gen/ToastVariant.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 ToastVariant = "custom" | "copied" | "success" | "info" | "warning" | "error";
|
||||
4
plugin-runtime-types/src/gen/Workspace.ts
Normal file
4
plugin-runtime-types/src/gen/Workspace.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { EnvironmentVariable } from "./EnvironmentVariable";
|
||||
|
||||
export type Workspace = { id: string, model: "workspace", createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
2
plugin-runtime-types/src/helpers.ts
Normal file
2
plugin-runtime-types/src/helpers.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
||||
export type OneOrMany<T> = T[] | T;
|
||||
65
plugin-runtime-types/src/index.ts
Normal file
65
plugin-runtime-types/src/index.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
export type * from './plugins';
|
||||
export type * from './themes';
|
||||
|
||||
// TODO: The next ts-rs release includes the ability to put everything in 1 file!
|
||||
export * from './gen/BootRequest';
|
||||
export * from './gen/BootResponse';
|
||||
export * from './gen/CallHttpRequestActionArgs';
|
||||
export * from './gen/CallHttpRequestActionRequest';
|
||||
export * from './gen/CallTemplateFunctionRequest';
|
||||
export * from './gen/CallTemplateFunctionResponse';
|
||||
export * from './gen/CallTemplateFunctionArgs';
|
||||
export * from './gen/Cookie';
|
||||
export * from './gen/CookieDomain';
|
||||
export * from './gen/CookieExpires';
|
||||
export * from './gen/CookieJar';
|
||||
export * from './gen/CopyTextRequest';
|
||||
export * from './gen/EmptyResponse';
|
||||
export * from './gen/Environment';
|
||||
export * from './gen/EnvironmentVariable';
|
||||
export * from './gen/ExportHttpRequestRequest';
|
||||
export * from './gen/ExportHttpRequestResponse';
|
||||
export * from './gen/FilterRequest';
|
||||
export * from './gen/FilterResponse';
|
||||
export * from './gen/Folder';
|
||||
export * from './gen/FindHttpResponsesRequest';
|
||||
export * from './gen/FindHttpResponsesResponse';
|
||||
export * from './gen/GetHttpRequestActionsResponse';
|
||||
export * from './gen/GetHttpRequestByIdRequest';
|
||||
export * from './gen/GetHttpRequestByIdResponse';
|
||||
export * from './gen/GetTemplateFunctionsResponse';
|
||||
export * from './gen/GrpcConnection';
|
||||
export * from './gen/GrpcEvent';
|
||||
export * from './gen/GrpcMetadataEntry';
|
||||
export * from './gen/GrpcRequest';
|
||||
export * from './gen/HttpRequest';
|
||||
export * from './gen/HttpRequestAction';
|
||||
export * from './gen/HttpRequestHeader';
|
||||
export * from './gen/HttpResponse';
|
||||
export * from './gen/HttpResponseHeader';
|
||||
export * from './gen/HttpUrlParameter';
|
||||
export * from './gen/ImportRequest';
|
||||
export * from './gen/ImportResources';
|
||||
export * from './gen/ImportResponse';
|
||||
export * from './gen/InternalEvent';
|
||||
export * from './gen/InternalEventPayload';
|
||||
export * from './gen/KeyValue';
|
||||
export * from './gen/Model';
|
||||
export * from './gen/RenderHttpRequestRequest';
|
||||
export * from './gen/RenderHttpRequestResponse';
|
||||
export * from './gen/RenderPurpose';
|
||||
export * from './gen/SendHttpRequestRequest';
|
||||
export * from './gen/SendHttpRequestResponse';
|
||||
export * from './gen/SendHttpRequestResponse';
|
||||
export * from './gen/Settings';
|
||||
export * from './gen/ShowToastRequest';
|
||||
export * from './gen/TemplateFunction';
|
||||
export * from './gen/TemplateFunctionArg';
|
||||
export * from './gen/TemplateFunctionBaseArg';
|
||||
export * from './gen/TemplateFunctionCheckboxArg';
|
||||
export * from './gen/TemplateFunctionHttpRequestArg';
|
||||
export * from './gen/TemplateFunctionSelectArg';
|
||||
export * from './gen/TemplateFunctionSelectOption';
|
||||
export * from './gen/TemplateFunctionTextArg';
|
||||
export * from './gen/ToastVariant';
|
||||
export * from './gen/Workspace';
|
||||
26
plugin-runtime-types/src/plugins/Context.ts
Normal file
26
plugin-runtime-types/src/plugins/Context.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { FindHttpResponsesRequest } from '../gen/FindHttpResponsesRequest';
|
||||
import { FindHttpResponsesResponse } from '../gen/FindHttpResponsesResponse';
|
||||
import { GetHttpRequestByIdRequest } from '../gen/GetHttpRequestByIdRequest';
|
||||
import { GetHttpRequestByIdResponse } from '../gen/GetHttpRequestByIdResponse';
|
||||
import { RenderHttpRequestRequest } from '../gen/RenderHttpRequestRequest';
|
||||
import { RenderHttpRequestResponse } from '../gen/RenderHttpRequestResponse';
|
||||
import { SendHttpRequestRequest } from '../gen/SendHttpRequestRequest';
|
||||
import { SendHttpRequestResponse } from '../gen/SendHttpRequestResponse';
|
||||
import { ShowToastRequest } from '../gen/ShowToastRequest';
|
||||
|
||||
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']>;
|
||||
};
|
||||
};
|
||||
13
plugin-runtime-types/src/plugins/FilterPlugin.ts
Normal file
13
plugin-runtime-types/src/plugins/FilterPlugin.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
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>;
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { CallHttpRequestActionArgs } from '../gen/CallHttpRequestActionArgs';
|
||||
import { HttpRequestAction } from '../gen/HttpRequestAction';
|
||||
import { Context } from './Context';
|
||||
|
||||
export type HttpRequestActionPlugin = HttpRequestAction & {
|
||||
onSelect(ctx: Context, args: CallHttpRequestActionArgs): Promise<void> | void;
|
||||
};
|
||||
19
plugin-runtime-types/src/plugins/ImporterPlugin.ts
Normal file
19
plugin-runtime-types/src/plugins/ImporterPlugin.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Environment } from '../gen/Environment';
|
||||
import { Folder } from '../gen/Folder';
|
||||
import { HttpRequest } from '../gen/HttpRequest';
|
||||
import { Workspace } from '../gen/Workspace';
|
||||
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>;
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { CallTemplateFunctionArgs } from '../gen/CallTemplateFunctionArgs';
|
||||
import { TemplateFunction } from '../gen/TemplateFunction';
|
||||
import { Context } from './Context';
|
||||
|
||||
export type TemplateFunctionPlugin = TemplateFunction & {
|
||||
onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise<string | null>;
|
||||
};
|
||||
8
plugin-runtime-types/src/plugins/ThemePlugin.ts
Normal file
8
plugin-runtime-types/src/plugins/ThemePlugin.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Theme } from '../themes';
|
||||
import { Context } from './Context';
|
||||
|
||||
export type ThemePlugin = {
|
||||
name: string;
|
||||
description?: string;
|
||||
getTheme(ctx: Context, fileContents: string): Promise<Theme>;
|
||||
};
|
||||
18
plugin-runtime-types/src/plugins/index.ts
Normal file
18
plugin-runtime-types/src/plugins/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
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 Plugin = {
|
||||
importer?: ImporterPlugin;
|
||||
theme?: ThemePlugin;
|
||||
filter?: FilterPlugin;
|
||||
httpRequestActions?: HttpRequestActionPlugin[];
|
||||
templateFunctions?: TemplateFunctionPlugin[];
|
||||
};
|
||||
44
plugin-runtime-types/src/themes/index.ts
Normal file
44
plugin-runtime-types/src/themes/index.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
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
plugin-runtime-types/tsconfig.json
Normal file
15
plugin-runtime-types/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "node16",
|
||||
"target": "es6",
|
||||
"lib": ["es2021"],
|
||||
"declaration": true,
|
||||
"declarationDir": "./lib",
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"src/index.ts"
|
||||
]
|
||||
}
|
||||
61
plugin-runtime/package-lock.json
generated
61
plugin-runtime/package-lock.json
generated
@@ -6,11 +6,13 @@
|
||||
"": {
|
||||
"name": "@yaak/plugin-runtime",
|
||||
"dependencies": {
|
||||
"intercept-stdout": "^0.1.2",
|
||||
"long": "^5.2.3",
|
||||
"nice-grpc": "^2.1.9",
|
||||
"protobufjs": "^7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/intercept-stdout": "^0.1.3",
|
||||
"grpc-tools": "^1.12.4",
|
||||
"nodemon": "^3.1.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@@ -192,6 +194,12 @@
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/intercept-stdout": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/intercept-stdout/-/intercept-stdout-0.1.3.tgz",
|
||||
"integrity": "sha512-5qWSvqohM5rRKsF58LBWJeyu+lUlZwYKSnTcnXGfvFyMYIjvhpfniQRJNiyE/Gcru3jwVr2pHedsKTGLtzZqNA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz",
|
||||
@@ -1304,6 +1312,14 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/intercept-stdout": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz",
|
||||
"integrity": "sha512-Umb41Ryp5FzLurfCRAWx+jjNAk8jsw2RTk2XPIwus+86h/Y2Eb4DfOWof/mZ6FBww8SoO45rJSlg25054/Di9w==",
|
||||
"dependencies": {
|
||||
"lodash.toarray": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
|
||||
@@ -1644,11 +1660,56 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash._arraycopy": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz",
|
||||
"integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A=="
|
||||
},
|
||||
"node_modules/lodash._basevalues": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
|
||||
"integrity": "sha512-H94wl5P13uEqlCg7OcNNhMQ8KvWSIyqXzOPusRgHC9DK3o54P6P3xtbXlVbRABG4q5gSmp7EDdJ0MSuW9HX6Mg=="
|
||||
},
|
||||
"node_modules/lodash._getnative": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
|
||||
"integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA=="
|
||||
},
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||
},
|
||||
"node_modules/lodash.isarguments": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
|
||||
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
|
||||
},
|
||||
"node_modules/lodash.isarray": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
|
||||
"integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ=="
|
||||
},
|
||||
"node_modules/lodash.keys": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
|
||||
"integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==",
|
||||
"dependencies": {
|
||||
"lodash._getnative": "^3.0.0",
|
||||
"lodash.isarguments": "^3.0.0",
|
||||
"lodash.isarray": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.toarray": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz",
|
||||
"integrity": "sha512-ptkjUqvuHjTuMJJxiktJpZhxM5l60bEkfntJx+NFzdQd1bZVxfpTF1bhFYFqBrT4F0wZ1qx9KbVmHJV3Rfc7Tw==",
|
||||
"dependencies": {
|
||||
"lodash._arraycopy": "^3.0.0",
|
||||
"lodash._basevalues": "^3.0.0",
|
||||
"lodash.keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
"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.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/intercept-stdout": "^0.1.3",
|
||||
"grpc-tools": "^1.12.4",
|
||||
"nodemon": "^3.1.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
||||
21
plugin-runtime/src/EventChannel.ts
Normal file
21
plugin-runtime/src/EventChannel.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,31 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { InternalEvent } from '@yaakapp/api';
|
||||
import path from 'node:path';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
import { PluginInfo } from './plugins';
|
||||
|
||||
export interface ParentToWorkerEvent<T = any> {
|
||||
callbackId: string;
|
||||
name: string;
|
||||
payload: T;
|
||||
}
|
||||
|
||||
export type WorkerToParentSuccessEvent<T> = {
|
||||
callbackId: string;
|
||||
payload: T;
|
||||
};
|
||||
|
||||
export type WorkerToParentErrorEvent = {
|
||||
callbackId: string;
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type WorkerToParentEvent<T = any> = WorkerToParentErrorEvent | WorkerToParentSuccessEvent<T>;
|
||||
import { EventChannel } from './EventChannel';
|
||||
|
||||
export class PluginHandle {
|
||||
readonly pluginDir: string;
|
||||
readonly #worker: Worker;
|
||||
|
||||
constructor(pluginDir: string) {
|
||||
this.pluginDir = pluginDir;
|
||||
|
||||
const workerPath = path.join(__dirname, 'index.worker.cjs');
|
||||
constructor(
|
||||
readonly pluginDir: string,
|
||||
readonly pluginRefId: string,
|
||||
readonly events: EventChannel,
|
||||
) {
|
||||
const workerPath = process.env.YAAK_WORKER_PATH ?? path.join(__dirname, 'index.worker.cjs');
|
||||
this.#worker = new Worker(workerPath, {
|
||||
workerData: {
|
||||
pluginDir: this.pluginDir,
|
||||
pluginDir,
|
||||
pluginRefId,
|
||||
},
|
||||
});
|
||||
|
||||
this.#worker.on('message', (e) => this.events.emit(e));
|
||||
this.#worker.on('error', this.#handleError.bind(this));
|
||||
this.#worker.on('exit', this.#handleExit.bind(this));
|
||||
}
|
||||
|
||||
async getInfo(): Promise<PluginInfo> {
|
||||
return this.#callPlugin('info', null);
|
||||
}
|
||||
|
||||
async runResponseFilter({ filter, body }: { filter: string; body: string }): Promise<string> {
|
||||
return this.#callPlugin('run-filter', { filter, body });
|
||||
}
|
||||
|
||||
async runExport(request: any): Promise<string> {
|
||||
return this.#callPlugin('run-export', request);
|
||||
}
|
||||
|
||||
async runImport(data: string): Promise<string> {
|
||||
const result = await this.#callPlugin('run-import', data);
|
||||
|
||||
// Plugin returns object, but we convert to string
|
||||
return JSON.stringify(result, null, 2);
|
||||
}
|
||||
|
||||
#callPlugin<P, R>(name: string, payload: P): Promise<R> {
|
||||
const callbackId = `cb_${randomUUID().replaceAll('-', '')}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
const cb = (e: WorkerToParentEvent<R>) => {
|
||||
if (e.callbackId !== callbackId) return;
|
||||
|
||||
if ('error' in e) {
|
||||
reject(e.error);
|
||||
} else {
|
||||
resolve(e.payload as R);
|
||||
}
|
||||
|
||||
this.#worker.removeListener('message', cb);
|
||||
};
|
||||
|
||||
this.#worker.addListener('message', cb);
|
||||
this.#worker.postMessage({ callbackId, name, payload });
|
||||
});
|
||||
sendToWorker(event: InternalEvent) {
|
||||
this.#worker.postMessage(event);
|
||||
}
|
||||
|
||||
async #handleError(err: Error) {
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { PluginHandle } from './PluginHandle';
|
||||
import { loadPlugins, PluginInfo } from './plugins';
|
||||
|
||||
export class PluginManager {
|
||||
#handles: PluginHandle[] | null = null;
|
||||
static #instance: PluginManager | null = null;
|
||||
|
||||
public static instance(): PluginManager {
|
||||
if (PluginManager.#instance == null) {
|
||||
PluginManager.#instance = new PluginManager();
|
||||
PluginManager.#instance.plugins(); // Trigger workers to boot, as it takes a few seconds
|
||||
}
|
||||
return PluginManager.#instance;
|
||||
}
|
||||
|
||||
async plugins(): Promise<PluginHandle[]> {
|
||||
this.#handles = this.#handles ?? loadPlugins();
|
||||
return this.#handles;
|
||||
}
|
||||
|
||||
async #pluginsWithInfo(): Promise<{ plugin: PluginHandle; info: PluginInfo }[]> {
|
||||
const plugins = await this.plugins();
|
||||
return Promise.all(plugins.map(async (plugin) => ({ plugin, info: await plugin.getInfo() })));
|
||||
}
|
||||
|
||||
async pluginsWith(capability: PluginInfo['capabilities'][0]): Promise<PluginHandle[]> {
|
||||
return (await this.#pluginsWithInfo())
|
||||
.filter((v) => v.info.capabilities.includes(capability))
|
||||
.map((v) => v.plugin);
|
||||
}
|
||||
|
||||
async plugin(name: string): Promise<PluginHandle | null> {
|
||||
return (await this.#pluginsWithInfo()).find((v) => v.info.name === name)?.plugin ?? null;
|
||||
}
|
||||
|
||||
async pluginOrThrow(name: string): Promise<PluginHandle> {
|
||||
const plugin = await this.plugin(name);
|
||||
if (plugin == null) {
|
||||
throw new Error(`Failed to find plugin by ${name}`);
|
||||
}
|
||||
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
@@ -10,45 +10,26 @@ import * as _m0 from "protobufjs/minimal";
|
||||
|
||||
export const protobufPackage = "yaak.plugins.runtime";
|
||||
|
||||
export interface PluginInfo {
|
||||
plugin: string;
|
||||
export interface EventStreamEvent {
|
||||
event: string;
|
||||
}
|
||||
|
||||
export interface HookResponse {
|
||||
info: PluginInfo | undefined;
|
||||
data: string;
|
||||
function createBaseEventStreamEvent(): EventStreamEvent {
|
||||
return { event: "" };
|
||||
}
|
||||
|
||||
export interface HookImportRequest {
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface HookResponseFilterRequest {
|
||||
filter: string;
|
||||
body: string;
|
||||
contentType: string;
|
||||
}
|
||||
|
||||
export interface HookExportRequest {
|
||||
request: string;
|
||||
}
|
||||
|
||||
function createBasePluginInfo(): PluginInfo {
|
||||
return { plugin: "" };
|
||||
}
|
||||
|
||||
export const PluginInfo = {
|
||||
encode(message: PluginInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.plugin !== "") {
|
||||
writer.uint32(10).string(message.plugin);
|
||||
export const EventStreamEvent = {
|
||||
encode(message: EventStreamEvent, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.event !== "") {
|
||||
writer.uint32(10).string(message.event);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): PluginInfo {
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): EventStreamEvent {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePluginInfo();
|
||||
const message = createBaseEventStreamEvent();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
@@ -57,7 +38,7 @@ export const PluginInfo = {
|
||||
break;
|
||||
}
|
||||
|
||||
message.plugin = reader.string();
|
||||
message.event = reader.string();
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
@@ -68,303 +49,24 @@ export const PluginInfo = {
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): PluginInfo {
|
||||
return { plugin: isSet(object.plugin) ? globalThis.String(object.plugin) : "" };
|
||||
fromJSON(object: any): EventStreamEvent {
|
||||
return { event: isSet(object.event) ? globalThis.String(object.event) : "" };
|
||||
},
|
||||
|
||||
toJSON(message: PluginInfo): unknown {
|
||||
toJSON(message: EventStreamEvent): unknown {
|
||||
const obj: any = {};
|
||||
if (message.plugin !== "") {
|
||||
obj.plugin = message.plugin;
|
||||
if (message.event !== "") {
|
||||
obj.event = message.event;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<PluginInfo>): PluginInfo {
|
||||
return PluginInfo.fromPartial(base ?? {});
|
||||
create(base?: DeepPartial<EventStreamEvent>): EventStreamEvent {
|
||||
return EventStreamEvent.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<PluginInfo>): PluginInfo {
|
||||
const message = createBasePluginInfo();
|
||||
message.plugin = object.plugin ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseHookResponse(): HookResponse {
|
||||
return { info: undefined, data: "" };
|
||||
}
|
||||
|
||||
export const HookResponse = {
|
||||
encode(message: HookResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.info !== undefined) {
|
||||
PluginInfo.encode(message.info, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
if (message.data !== "") {
|
||||
writer.uint32(18).string(message.data);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): HookResponse {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseHookResponse();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.info = PluginInfo.decode(reader, reader.uint32());
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.data = reader.string();
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): HookResponse {
|
||||
return {
|
||||
info: isSet(object.info) ? PluginInfo.fromJSON(object.info) : undefined,
|
||||
data: isSet(object.data) ? globalThis.String(object.data) : "",
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: HookResponse): unknown {
|
||||
const obj: any = {};
|
||||
if (message.info !== undefined) {
|
||||
obj.info = PluginInfo.toJSON(message.info);
|
||||
}
|
||||
if (message.data !== "") {
|
||||
obj.data = message.data;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<HookResponse>): HookResponse {
|
||||
return HookResponse.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<HookResponse>): HookResponse {
|
||||
const message = createBaseHookResponse();
|
||||
message.info = (object.info !== undefined && object.info !== null)
|
||||
? PluginInfo.fromPartial(object.info)
|
||||
: undefined;
|
||||
message.data = object.data ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseHookImportRequest(): HookImportRequest {
|
||||
return { data: "" };
|
||||
}
|
||||
|
||||
export const HookImportRequest = {
|
||||
encode(message: HookImportRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.data !== "") {
|
||||
writer.uint32(10).string(message.data);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): HookImportRequest {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseHookImportRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.data = reader.string();
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): HookImportRequest {
|
||||
return { data: isSet(object.data) ? globalThis.String(object.data) : "" };
|
||||
},
|
||||
|
||||
toJSON(message: HookImportRequest): unknown {
|
||||
const obj: any = {};
|
||||
if (message.data !== "") {
|
||||
obj.data = message.data;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<HookImportRequest>): HookImportRequest {
|
||||
return HookImportRequest.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<HookImportRequest>): HookImportRequest {
|
||||
const message = createBaseHookImportRequest();
|
||||
message.data = object.data ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseHookResponseFilterRequest(): HookResponseFilterRequest {
|
||||
return { filter: "", body: "", contentType: "" };
|
||||
}
|
||||
|
||||
export const HookResponseFilterRequest = {
|
||||
encode(message: HookResponseFilterRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.filter !== "") {
|
||||
writer.uint32(10).string(message.filter);
|
||||
}
|
||||
if (message.body !== "") {
|
||||
writer.uint32(18).string(message.body);
|
||||
}
|
||||
if (message.contentType !== "") {
|
||||
writer.uint32(26).string(message.contentType);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): HookResponseFilterRequest {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseHookResponseFilterRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.filter = reader.string();
|
||||
continue;
|
||||
case 2:
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.body = reader.string();
|
||||
continue;
|
||||
case 3:
|
||||
if (tag !== 26) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.contentType = reader.string();
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): HookResponseFilterRequest {
|
||||
return {
|
||||
filter: isSet(object.filter) ? globalThis.String(object.filter) : "",
|
||||
body: isSet(object.body) ? globalThis.String(object.body) : "",
|
||||
contentType: isSet(object.contentType) ? globalThis.String(object.contentType) : "",
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: HookResponseFilterRequest): unknown {
|
||||
const obj: any = {};
|
||||
if (message.filter !== "") {
|
||||
obj.filter = message.filter;
|
||||
}
|
||||
if (message.body !== "") {
|
||||
obj.body = message.body;
|
||||
}
|
||||
if (message.contentType !== "") {
|
||||
obj.contentType = message.contentType;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<HookResponseFilterRequest>): HookResponseFilterRequest {
|
||||
return HookResponseFilterRequest.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<HookResponseFilterRequest>): HookResponseFilterRequest {
|
||||
const message = createBaseHookResponseFilterRequest();
|
||||
message.filter = object.filter ?? "";
|
||||
message.body = object.body ?? "";
|
||||
message.contentType = object.contentType ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseHookExportRequest(): HookExportRequest {
|
||||
return { request: "" };
|
||||
}
|
||||
|
||||
export const HookExportRequest = {
|
||||
encode(message: HookExportRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.request !== "") {
|
||||
writer.uint32(10).string(message.request);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: _m0.Reader | Uint8Array, length?: number): HookExportRequest {
|
||||
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseHookExportRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1:
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.request = reader.string();
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skipType(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): HookExportRequest {
|
||||
return { request: isSet(object.request) ? globalThis.String(object.request) : "" };
|
||||
},
|
||||
|
||||
toJSON(message: HookExportRequest): unknown {
|
||||
const obj: any = {};
|
||||
if (message.request !== "") {
|
||||
obj.request = message.request;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<HookExportRequest>): HookExportRequest {
|
||||
return HookExportRequest.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<HookExportRequest>): HookExportRequest {
|
||||
const message = createBaseHookExportRequest();
|
||||
message.request = object.request ?? "";
|
||||
fromPartial(object: DeepPartial<EventStreamEvent>): EventStreamEvent {
|
||||
const message = createBaseEventStreamEvent();
|
||||
message.event = object.event ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -374,49 +76,29 @@ export const PluginRuntimeDefinition = {
|
||||
name: "PluginRuntime",
|
||||
fullName: "yaak.plugins.runtime.PluginRuntime",
|
||||
methods: {
|
||||
hookImport: {
|
||||
name: "hookImport",
|
||||
requestType: HookImportRequest,
|
||||
requestStream: false,
|
||||
responseType: HookResponse,
|
||||
responseStream: false,
|
||||
options: {},
|
||||
},
|
||||
hookResponseFilter: {
|
||||
name: "hookResponseFilter",
|
||||
requestType: HookResponseFilterRequest,
|
||||
requestStream: false,
|
||||
responseType: HookResponse,
|
||||
responseStream: false,
|
||||
options: {},
|
||||
},
|
||||
hookExport: {
|
||||
name: "hookExport",
|
||||
requestType: HookExportRequest,
|
||||
requestStream: false,
|
||||
responseType: HookResponse,
|
||||
responseStream: false,
|
||||
eventStream: {
|
||||
name: "EventStream",
|
||||
requestType: EventStreamEvent,
|
||||
requestStream: true,
|
||||
responseType: EventStreamEvent,
|
||||
responseStream: true,
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export interface PluginRuntimeServiceImplementation<CallContextExt = {}> {
|
||||
hookImport(request: HookImportRequest, context: CallContext & CallContextExt): Promise<DeepPartial<HookResponse>>;
|
||||
hookResponseFilter(
|
||||
request: HookResponseFilterRequest,
|
||||
eventStream(
|
||||
request: AsyncIterable<EventStreamEvent>,
|
||||
context: CallContext & CallContextExt,
|
||||
): Promise<DeepPartial<HookResponse>>;
|
||||
hookExport(request: HookExportRequest, context: CallContext & CallContextExt): Promise<DeepPartial<HookResponse>>;
|
||||
): ServerStreamingMethodResult<DeepPartial<EventStreamEvent>>;
|
||||
}
|
||||
|
||||
export interface PluginRuntimeClient<CallOptionsExt = {}> {
|
||||
hookImport(request: DeepPartial<HookImportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
|
||||
hookResponseFilter(
|
||||
request: DeepPartial<HookResponseFilterRequest>,
|
||||
eventStream(
|
||||
request: AsyncIterable<DeepPartial<EventStreamEvent>>,
|
||||
options?: CallOptions & CallOptionsExt,
|
||||
): Promise<HookResponse>;
|
||||
hookExport(request: DeepPartial<HookExportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
|
||||
): AsyncIterable<EventStreamEvent>;
|
||||
}
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||
@@ -430,3 +112,5 @@ export type DeepPartial<T> = T extends Builtin ? T
|
||||
function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
export type ServerStreamingMethodResult<Response> = { [Symbol.asyncIterator](): AsyncIterator<Response, void> };
|
||||
|
||||
@@ -1,87 +1,42 @@
|
||||
import { isAbortError } from 'abort-controller-x';
|
||||
import { createServer, ServerError, ServerMiddlewareCall, Status } from 'nice-grpc';
|
||||
import { CallContext } from 'nice-grpc-common';
|
||||
import * as fs from 'node:fs';
|
||||
import {
|
||||
DeepPartial,
|
||||
HookExportRequest,
|
||||
HookImportRequest,
|
||||
HookResponse,
|
||||
HookResponseFilterRequest,
|
||||
PluginRuntimeDefinition,
|
||||
PluginRuntimeServiceImplementation,
|
||||
} from './gen/plugins/runtime';
|
||||
import { PluginManager } from './PluginManager';
|
||||
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';
|
||||
|
||||
class PluginRuntimeService implements PluginRuntimeServiceImplementation {
|
||||
#manager: PluginManager;
|
||||
const port = process.env.PORT || '50051';
|
||||
|
||||
constructor() {
|
||||
this.#manager = PluginManager.instance();
|
||||
}
|
||||
const channel = createChannel(`localhost:${port}`);
|
||||
const client: PluginRuntimeClient = createClient(PluginRuntimeDefinition, channel);
|
||||
|
||||
async hookExport(request: HookExportRequest): Promise<DeepPartial<HookResponse>> {
|
||||
const plugin = await this.#manager.pluginOrThrow('exporter-curl');
|
||||
const data = await plugin.runExport(JSON.parse(request.request));
|
||||
const info = { plugin: (await plugin.getInfo()).name };
|
||||
return { info, data };
|
||||
}
|
||||
const events = new EventChannel();
|
||||
const plugins: Record<string, PluginHandle> = {};
|
||||
|
||||
async hookImport(request: HookImportRequest): Promise<DeepPartial<HookResponse>> {
|
||||
const plugins = await this.#manager.pluginsWith('import');
|
||||
for (const p of plugins) {
|
||||
const data = await p.runImport(request.data);
|
||||
if (data != null && data !== 'null') {
|
||||
const info = { plugin: (await p.getInfo()).name };
|
||||
return { info, data };
|
||||
}
|
||||
}
|
||||
|
||||
throw new ServerError(Status.UNKNOWN, 'No importers found for data');
|
||||
}
|
||||
|
||||
async hookResponseFilter(request: HookResponseFilterRequest): Promise<DeepPartial<HookResponse>> {
|
||||
const pluginName = request.contentType.includes('json') ? 'filter-jsonpath' : 'filter-xpath';
|
||||
const plugin = await this.#manager.pluginOrThrow(pluginName);
|
||||
const data = await plugin.runResponseFilter(request);
|
||||
const info = { plugin: (await plugin.getInfo()).name };
|
||||
return { info, data };
|
||||
}
|
||||
}
|
||||
|
||||
let server = createServer();
|
||||
|
||||
async function* errorHandlingMiddleware<Request, Response>(
|
||||
call: ServerMiddlewareCall<Request, Response>,
|
||||
context: CallContext,
|
||||
) {
|
||||
(async () => {
|
||||
try {
|
||||
return yield* call.next(call.request, context);
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof ServerError || isAbortError(error)) {
|
||||
throw error;
|
||||
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 plugin's worker
|
||||
const plugin = plugins[pluginEvent.pluginRefId];
|
||||
if (!plugin) {
|
||||
console.warn('Failed to get plugin for event by', pluginEvent.pluginRefId);
|
||||
continue;
|
||||
}
|
||||
|
||||
plugin.sendToWorker(pluginEvent);
|
||||
}
|
||||
|
||||
let details = String(error);
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// @ts-ignore
|
||||
details += `: ${error.stack}`;
|
||||
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);
|
||||
}
|
||||
|
||||
throw new ServerError(Status.UNKNOWN, details);
|
||||
}
|
||||
}
|
||||
|
||||
server = server.use(errorHandlingMiddleware);
|
||||
server.add(PluginRuntimeDefinition, new PluginRuntimeService());
|
||||
|
||||
// Start on random port if YAAK_GRPC_PORT_FILE_PATH is set, or :4000
|
||||
const addr = process.env.YAAK_GRPC_PORT_FILE_PATH ? 'localhost:0' : 'localhost:4000';
|
||||
server.listen(addr).then((port) => {
|
||||
console.log('gRPC server listening on', `http://localhost:${port}`);
|
||||
if (process.env.YAAK_GRPC_PORT_FILE_PATH) {
|
||||
console.log('Wrote port file to', process.env.YAAK_GRPC_PORT_FILE_PATH);
|
||||
fs.writeFileSync(process.env.YAAK_GRPC_PORT_FILE_PATH, JSON.stringify({ port }, null, 2));
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
import {
|
||||
Context,
|
||||
FindHttpResponsesResponse,
|
||||
GetHttpRequestByIdResponse,
|
||||
HttpRequestAction,
|
||||
ImportResponse,
|
||||
InternalEvent,
|
||||
InternalEventPayload,
|
||||
RenderHttpRequestResponse,
|
||||
SendHttpRequestResponse,
|
||||
TemplateFunction,
|
||||
} from '@yaakapp/api';
|
||||
import { HttpRequestActionPlugin } from '@yaakapp/api/lib/plugins/httpRequestAction';
|
||||
import { TemplateFunctionPlugin } from '@yaakapp/api/lib/plugins/TemplateFunctionPlugin';
|
||||
import interceptStdout from 'intercept-stdout';
|
||||
import * as console from 'node:console';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import * as util from 'node:util';
|
||||
import { parentPort, workerData } from 'node:worker_threads';
|
||||
import { ParentToWorkerEvent } from './PluginHandle';
|
||||
import { PluginInfo } from './plugins';
|
||||
|
||||
new Promise<void>(async (resolve, reject) => {
|
||||
const { pluginDir } = workerData;
|
||||
const pathMod = path.join(pluginDir, 'build/index.js');
|
||||
const { pluginDir, pluginRefId } = workerData;
|
||||
const pathPkg = path.join(pluginDir, 'package.json');
|
||||
|
||||
// NOTE: Use POSIX join because require() needs forward slash
|
||||
const pathMod = path.posix.join(pluginDir, 'build', 'index.js');
|
||||
|
||||
let pkg: { [x: string]: any };
|
||||
try {
|
||||
pkg = JSON.parse(readFileSync(pathPkg, 'utf8'));
|
||||
@@ -18,59 +35,253 @@ new Promise<void>(async (resolve, reject) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const mod = (await import(`file://${pathMod}`)).default ?? {};
|
||||
prefixStdout(`[plugin][${pkg.name}] %s`);
|
||||
|
||||
const info: PluginInfo = {
|
||||
capabilities: [],
|
||||
name: pkg['name'] ?? 'n/a',
|
||||
dir: pluginDir,
|
||||
const mod = (await import(pathMod)).default ?? {};
|
||||
|
||||
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>;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof mod['pluginHookImport'] === 'function') {
|
||||
info.capabilities.push('import');
|
||||
}
|
||||
|
||||
if (typeof mod['pluginHookExport'] === 'function') {
|
||||
info.capabilities.push('export');
|
||||
}
|
||||
|
||||
if (typeof mod['pluginHookResponseFilter'] === 'function') {
|
||||
info.capabilities.push('filter');
|
||||
}
|
||||
|
||||
console.log('Loaded plugin', info.name, info.capabilities, info.dir);
|
||||
|
||||
function reply<T>(originalMsg: ParentToWorkerEvent, payload: T) {
|
||||
parentPort!.postMessage({ payload, callbackId: originalMsg.callbackId });
|
||||
}
|
||||
|
||||
function replyErr(originalMsg: ParentToWorkerEvent, error: unknown) {
|
||||
parentPort!.postMessage({
|
||||
error: String(error),
|
||||
callbackId: originalMsg.callbackId,
|
||||
});
|
||||
}
|
||||
|
||||
parentPort!.on('message', async (msg: ParentToWorkerEvent) => {
|
||||
// Message comes into the plugin to be processed
|
||||
parentPort!.on('message', async ({ payload, id: replyId }: InternalEvent) => {
|
||||
try {
|
||||
const ctx = { todo: 'implement me' };
|
||||
if (msg.name === 'run-import') {
|
||||
reply(msg, await mod.pluginHookImport(ctx, msg.payload));
|
||||
} else if (msg.name === 'run-filter') {
|
||||
reply(msg, await mod.pluginHookResponseFilter(ctx, msg.payload));
|
||||
} else if (msg.name === 'run-export') {
|
||||
reply(msg, await mod.pluginHookExport(ctx, msg.payload));
|
||||
} else if (msg.name === 'info') {
|
||||
reply(msg, info);
|
||||
} else {
|
||||
console.log('Unknown message', msg);
|
||||
if (payload.type === 'boot_request') {
|
||||
const payload: InternalEventPayload = {
|
||||
type: 'boot_response',
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
capabilities,
|
||||
};
|
||||
sendPayload(payload, replyId);
|
||||
return;
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
replyErr(msg, err);
|
||||
|
||||
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) => 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) => 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;
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
});
|
||||
|
||||
resolve();
|
||||
}).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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import * as fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { PluginHandle } from './PluginHandle';
|
||||
|
||||
export interface PluginInfo {
|
||||
name: string;
|
||||
dir: string;
|
||||
capabilities: ('import' | 'export' | 'filter')[];
|
||||
}
|
||||
|
||||
export function loadPlugins(): PluginHandle[] {
|
||||
const pluginsDir = process.env.YAAK_PLUGINS_DIR;
|
||||
if (!pluginsDir) throw new Error('YAAK_PLUGINS_DIR is not set');
|
||||
console.log('Loading plugins from', pluginsDir);
|
||||
|
||||
const pluginDirs = fs.readdirSync(pluginsDir).map((p) => path.join(pluginsDir, p));
|
||||
return pluginDirs.map((pluginDir) => new PluginHandle(pluginDir));
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
"sourceMap": true,
|
||||
"outDir": "dist",
|
||||
"baseUrl": ".",
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"*": [
|
||||
"node_modules/*",
|
||||
|
||||
@@ -3,30 +3,9 @@ syntax = "proto3";
|
||||
package yaak.plugins.runtime;
|
||||
|
||||
service PluginRuntime {
|
||||
rpc hookImport (HookImportRequest) returns (HookResponse);
|
||||
rpc hookResponseFilter (HookResponseFilterRequest) returns (HookResponse);
|
||||
rpc hookExport (HookExportRequest) returns (HookResponse);
|
||||
rpc EventStream (stream EventStreamEvent) returns (stream EventStreamEvent);
|
||||
}
|
||||
|
||||
message PluginInfo {
|
||||
string plugin = 1;
|
||||
}
|
||||
|
||||
message HookResponse {
|
||||
PluginInfo info = 1;
|
||||
string data = 2;
|
||||
}
|
||||
|
||||
message HookImportRequest {
|
||||
string data = 1;
|
||||
}
|
||||
|
||||
message HookResponseFilterRequest {
|
||||
string filter = 1;
|
||||
string body = 2;
|
||||
string contentType = 3;
|
||||
}
|
||||
|
||||
message HookExportRequest {
|
||||
string request = 1;
|
||||
message EventStreamEvent {
|
||||
string event = 1;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
const path = require('node:path');
|
||||
const decompress = require('decompress');
|
||||
const Downloader = require("nodejs-file-downloader");
|
||||
const {rmSync, unlinkSync, cpSync, mkdirSync} = require("node:fs");
|
||||
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';
|
||||
@@ -10,52 +13,56 @@ const LNX_X64 = 'linux_x64';
|
||||
const WIN_X64 = 'win32_x64';
|
||||
|
||||
const URL_MAP = {
|
||||
[MAC_ARM]: 'https://nodejs.org/download/release/v22.5.1/node-v22.5.1-darwin-arm64.tar.gz',
|
||||
[MAC_X64]: 'https://nodejs.org/download/release/v22.5.1/node-v22.5.1-darwin-x64.tar.gz',
|
||||
[LNX_X64]: 'https://nodejs.org/download/release/v22.5.1/node-v22.5.1-linux-x64.tar.gz',
|
||||
[WIN_X64]: 'https://nodejs.org/download/release/v22.5.1/node-v22.5.1-win-x64.zip',
|
||||
};
|
||||
|
||||
const DST_BIN_MAP = {
|
||||
darwin_arm64: 'node-aarch64-apple-darwin',
|
||||
darwin_x64: 'node-x86_64-apple-darwin',
|
||||
linux_x64: 'node-x86_64-unknown-linux-gnu',
|
||||
win32_x64: 'node-x86_64-pc-windows-msvc.exe',
|
||||
[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-v22.5.1-darwin-arm64/bin/node',
|
||||
[MAC_X64]: 'node-v22.5.1-darwin-x64/bin/node',
|
||||
[LNX_X64]: 'node-v22.5.1-linux-x64/bin/node',
|
||||
[WIN_X64]: 'node-v22.5.1-win-x64/node.exe',
|
||||
[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 dstDir = path.join(__dirname, `..`, 'src-tauri', 'vendored', 'node');
|
||||
rmSync(dstDir, {recursive: true, force: true});
|
||||
mkdirSync(dstDir, {recursive: true});
|
||||
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) && execSync(`${binDest} --version`).toString('utf-8').trim() === NODE_VERSION) {
|
||||
console.log("NodeJS already vendored");
|
||||
return;
|
||||
}
|
||||
|
||||
rmSync(destDir, {recursive: true, force: true});
|
||||
mkdirSync(destDir, {recursive: true});
|
||||
|
||||
(async function () {
|
||||
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
|
||||
console.log('Vendoring NodeJS binary for', key);
|
||||
const url = URL_MAP[key];
|
||||
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());
|
||||
|
||||
// Download GitHub release artifact
|
||||
const {filePath} = await new Downloader({url, directory: tmpDir,}).download();
|
||||
const {filePath} = await new Downloader({url, directory: tmpDir}).download();
|
||||
|
||||
// Decompress to the same directory
|
||||
await decompress(filePath, tmpDir, {});
|
||||
|
||||
// Remove the original archive
|
||||
unlinkSync(filePath);
|
||||
|
||||
// Copy binary
|
||||
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
|
||||
const binDst = path.join(dstDir, DST_BIN_MAP[key]);
|
||||
cpSync(binSrc, binDst);
|
||||
cpSync(binSrc, binDest);
|
||||
rmSync(tmpDir, {recursive: true, force: true});
|
||||
|
||||
console.log("Downloaded NodeJS to", binDst);
|
||||
console.log("Downloaded NodeJS to", binDest);
|
||||
})().catch(err => {
|
||||
console.log('Script failed:', err);
|
||||
process.exit(1);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
const {readdirSync, cpSync} = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const {execSync} = require("node:child_process");
|
||||
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");
|
||||
console.log('YAAK_PLUGINS_DIR is not set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Installing Yaak plugins dependencies', pluginsDir);
|
||||
execSync('npm ci', {cwd: pluginsDir});
|
||||
execSync('npm ci', { cwd: pluginsDir });
|
||||
console.log('Building Yaak plugins', pluginsDir);
|
||||
execSync('npm run build', {cwd: pluginsDir});
|
||||
execSync('npm run build', { cwd: pluginsDir });
|
||||
|
||||
console.log('Copying Yaak plugins to', pluginsDir);
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
const decompress = require('decompress');
|
||||
const Downloader = require("nodejs-file-downloader");
|
||||
const path = require("node:path");
|
||||
const fs = require("node:fs");
|
||||
const {rmSync, mkdirSync} = require("node:fs");
|
||||
const {rmSync, mkdirSync, cpSync} = require("node:fs");
|
||||
|
||||
const VERSION = '27.2';
|
||||
|
||||
// `${process.platform}_${process.arch}`
|
||||
const MAC_ARM = 'darwin_arm64';
|
||||
@@ -11,17 +12,10 @@ const LNX_X64 = 'linux_x64';
|
||||
const WIN_X64 = 'win32_x64';
|
||||
|
||||
const URL_MAP = {
|
||||
[MAC_ARM]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-osx-aarch_64.zip',
|
||||
[MAC_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-osx-x86_64.zip',
|
||||
[LNX_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-linux-x86_64.zip',
|
||||
[WIN_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-win64.zip',
|
||||
};
|
||||
|
||||
const DST_BIN_MAP = {
|
||||
[MAC_ARM]: 'protoc-aarch64-apple-darwin',
|
||||
[MAC_X64]: 'protoc-x86_64-apple-darwin',
|
||||
[LNX_X64]: 'protoc-x86_64-unknown-linux-gnu',
|
||||
[WIN_X64]: 'protoc-x86_64-pc-windows-msvc.exe',
|
||||
[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 = {
|
||||
@@ -31,13 +25,20 @@ const SRC_BIN_MAP = {
|
||||
[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');
|
||||
rmSync(dstDir, {recursive: true, force: true});
|
||||
mkdirSync(dstDir, {recursive: true});
|
||||
|
||||
(async function () {
|
||||
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
|
||||
console.log("Vendoring protoc binary for", key);
|
||||
console.log(`Vendoring protoc ${VERSION} for ${key}`);
|
||||
const url = URL_MAP[key];
|
||||
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());
|
||||
|
||||
@@ -47,18 +48,15 @@ mkdirSync(dstDir, {recursive: true});
|
||||
// Decompress to the same directory
|
||||
await decompress(filePath, tmpDir, {});
|
||||
|
||||
// Remove the original archive
|
||||
fs.unlinkSync(filePath);
|
||||
|
||||
// Copy binary
|
||||
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
|
||||
const binDst = path.join(dstDir, DST_BIN_MAP[key]);
|
||||
fs.cpSync(binSrc, binDst);
|
||||
cpSync(binSrc, binDst);
|
||||
|
||||
// Copy other files
|
||||
const includeSrc = path.join(tmpDir, 'include');
|
||||
const includeDst = path.join(dstDir, 'include');
|
||||
fs.cpSync(includeSrc, includeDst, {recursive: true});
|
||||
cpSync(includeSrc, includeDst, {recursive: true});
|
||||
|
||||
rmSync(tmpDir, {recursive: true, force: true});
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT model, created_at, updated_at, namespace, key, value\n FROM key_values\n WHERE namespace = ? AND key = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 1,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 2,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "namespace",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "06aaf8f4a17566f1d25da2a60f0baf4b5fc28c3cf0c001a84e25edf9eab3c7e3"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user