Compare commits

...

102 Commits

Author SHA1 Message Date
Gregory Schier
1e90e672d2 Update workflow 2024-09-06 11:09:03 -07:00
Gregory Schier
d73b692edc Fix lint issues 2024-09-06 10:59:14 -07:00
Gregory Schier
b3adbc1860 Dynamic plugins (#68) 2024-09-06 10:43:25 -07:00
Gregory Schier
f7949c9909 Don't introspect schema on interval 2024-09-06 10:37:10 -07:00
Gregory Schier
baa4577601 Bump plugin-runtime-types version 2024-09-06 06:32:35 -07:00
Gregory Schier
db935f0130 re-gen plugin-runtime-types 2024-09-06 06:26:05 -07:00
Gregory Schier
d47de9a999 Remove prints 2024-09-06 06:21:21 -07:00
Gregory Schier
82252f920f Fix import order for nested folders to prevent foreign key constraint error 2024-09-06 06:20:27 -07:00
Gregory Schier
fedf356576 Support non-utf8 charsets 2024-09-05 13:58:06 -07:00
Gregory Schier
3601410fb8 Fix banner overflow 2024-09-04 07:33:21 -07:00
Gregory Schier
f67cecf1b4 Fix interface zoom 2024-09-03 14:37:44 -07:00
Gregory Schier
8619c66ea4 Create request/folder with proper folderId 2024-09-03 08:06:30 -07:00
Gregory Schier
230e1f55c2 Separate active tabs per request 2024-09-03 07:52:35 -07:00
Gregory Schier
d4ab8897e2 Separate active tabs per request 2024-09-03 07:33:48 -07:00
Gregory Schier
184feaa22b Print plugin dir on failure to read 2024-09-03 07:18:00 -07:00
Gregory Schier
428aaad877 Clean up 2024-09-03 06:44:51 -07:00
Gregory Schier
33f1aa29e4 Request pane context (#70) 2024-09-03 06:18:25 -07:00
Gregory Schier
002acd05ee Request pane context (#69) 2024-09-02 14:36:55 -07:00
Gregory Schier
e6d7f4a928 Fix white screen 2024-09-02 12:52:42 -07:00
Gregory Schier
0bfafb284a Placeholder CM tags working 2024-09-02 12:35:05 -07:00
Gregory Schier
f8b317e94b Rename var 2024-08-30 05:39:58 -07:00
Gregory Schier
ef0fdb4b16 Check for updates less often on stable 2024-08-30 05:39:29 -07:00
Gregory Schier
f2f1d9affa Only check for updates once per day 2024-08-30 05:36:30 -07:00
Gregory Schier
c73262b037 URL path placeholders 2024-08-30 05:24:07 -07:00
Gregory Schier
f8936e7b76 Detect JSON APIs returning HTML content-type 2024-08-29 10:52:41 -07:00
Gregory Schier
0d20e0fe29 Better content-type detection for editor 2024-08-29 06:07:31 -07:00
Gregory Schier
ba626a6b3e Fix Windows/linux close icon color 2024-08-28 09:46:35 -07:00
Gregory Schier
1e18933178 Kill plugin manager before NSIS update on Windows 2024-08-28 09:14:39 -07:00
Gregory Schier
97a4770464 Remove tauri "unstable" feature to fix Codemirror selection 2024-08-28 06:48:02 -07:00
Gregory Schier
db02dbcaa4 Hotfix for window focusing 2024-08-27 16:56:04 -07:00
Gregory Schier
badcbc7aef Special case Response()->response() 2024-08-26 15:26:43 -07:00
Gregory Schier
4b91601b98 Clean up code 2024-08-26 15:10:29 -07:00
Gregory Schier
93e0202b86 Default template fn args 2024-08-26 13:10:22 -07:00
Gregory Schier
e75d6abe33 Option to disable telemetry 2024-08-26 12:06:56 -07:00
Gregory Schier
24a4e3494e Node syntaxTree to parse template tags 2024-08-26 11:30:10 -07:00
Gregory Schier
124fb35dcd Force codemirror to parse more to be able to show code folding 2024-08-23 14:09:28 -07:00
Gregory Schier
1aa2839c51 Publish plugin-runtime-types 2024-08-23 13:37:47 -07:00
Gregory Schier
8d3260f394 Fix recursive plugin call locking 2024-08-23 13:20:48 -07:00
Gregory Schier
7e194b9148 Surface plugin error on import 2024-08-23 11:53:40 -07:00
Gregory Schier
f4abc1c7cb Fix initial apply text 2024-08-22 12:49:42 -07:00
Gregory Schier
6766bc8f59 Switch to single quotes for template strings 2024-08-22 12:48:14 -07:00
Gregory Schier
adda44e861 Pass render purpose to render 2024-08-22 11:27:55 -07:00
Gregory Schier
6aab017d3b Move to workspace crate 2024-08-22 10:49:51 -07:00
Gregory Schier
68c1dca9d1 Fix compile 2024-08-22 06:30:19 -07:00
Gregory Schier
066b7ea4f4 Fix deadlock on getting the focused window 2024-08-22 05:46:09 -07:00
Gregory Schier
0763c1b9b8 Some tweaks for beta 2024-08-19 19:10:08 -07:00
Gregory Schier
323e27a047 A bit more chaining cleanup 2024-08-19 16:38:28 -07:00
Gregory Schier
bd02206df2 A bunch of improvements to chaining 2024-08-19 14:10:44 -07:00
Gregory Schier
3411575ecc Actually call template functions 2024-08-19 10:34:22 -07:00
Gregory Schier
1193e1d7aa Async template functions working 2024-08-19 06:21:03 -07:00
Gregory Schier
1b63f33d43 Colored autocompletion icons 2024-08-17 05:47:05 -07:00
Gregory Schier
9f04cfb673 Template Tag Function Editor (#67)
![CleanShot 2024-08-15 at 16 53
09@2x](https://github.com/user-attachments/assets/8c0eb655-1daf-4dc8-811f-f606c770f7dc)
2024-08-16 08:31:19 -07:00
Gregory Schier
1fd1a901f8 Fix sidebar scroll into view 2024-08-15 09:09:18 -07:00
Gregory Schier
06517417b7 Fix some more styles 2024-08-15 05:58:09 -07:00
Gregory Schier
d924709b0c Keep sidebar and cmd+p items in view 2024-08-15 05:50:38 -07:00
Gregory Schier
6d274cea56 Request actions in command palette 2024-08-15 05:37:10 -07:00
Gregory Schier
b95fa25898 Request actions (#65) 2024-08-14 15:31:52 -07:00
Gregory Schier
12f4c2c668 Start on plugin ctx API (#64) 2024-08-14 06:42:54 -07:00
Gregory Schier
e47a2c5fab Variable value as title attr 2024-08-13 10:19:21 -07:00
Gregory Schier
fc279f67a1 Fix dollar sign in Twig grammar 2024-08-13 10:12:09 -07:00
Gregory Schier
6ed6e3e0e0 Fix rose pine themes 2024-08-13 07:51:26 -07:00
Gregory Schier
b5242b9a3f Use new theme vars (#63)
This PR swaps the theme to use the new stuff from the Theme Studio
2024-08-13 07:44:28 -07:00
Gregory Schier
a0950ce5b8 Don't persist settings tab 2024-08-10 08:10:14 -07:00
Gregory Schier
1dd8034cf9 Better curl import 2024-08-10 07:53:26 -07:00
Gregory Schier
7e73b680e6 Catch clipboard errors 2024-08-10 07:33:10 -07:00
Gregory Schier
352ffe9415 Don't show unnamed variables in autocomplete 2024-08-10 07:09:23 -07:00
Gregory Schier
e461851f6f Append [DEV] to window title in dev 2024-08-09 15:35:21 -07:00
Gregory Schier
673f2920a1 Fix gRPC request creation 2024-08-09 14:37:43 -07:00
Gregory Schier
e4ba408534 Correctly wrap small dialog text 2024-08-09 14:28:20 -07:00
Gregory Schier
96ae1d467b GraphQL variables now reset if entire thing deleted 2024-08-09 14:05:38 -07:00
Gregory Schier
48c239b7dc Fix Windows paths for new plugin runtime 2024-08-09 12:43:56 -07:00
Gregory Schier
331f1eb9b9 Better Windows pathing 2024-08-09 11:52:18 -07:00
Gregory Schier
1e9f10a99f UNC paths for plugins 2024-08-09 11:33:54 -07:00
Gregory Schier
6eb2cbd582 Fix up DB creation and migration 2024-08-09 11:20:04 -07:00
Gregory Schier
d9a7dba2e2 Vendor in build script 2024-08-09 08:51:21 -07:00
Gregory Schier
d885e6cb0a Fix body change setting headers/method 2024-08-09 08:33:49 -07:00
Gregory Schier
4cafc30f21 Remove problematic tests from release.yml 2024-08-09 08:33:01 -07:00
Gregory Schier
598a051bf8 Fix release script 2024-08-09 07:53:33 -07:00
Gregory Schier
965b579eb7 Switch to proper log plugin 2024-08-09 07:49:48 -07:00
Gregory Schier
d3a6125488 Fix release script 2024-08-09 07:42:39 -07:00
Gregory Schier
7f3492a1f0 Fix variable regex 2024-08-09 07:41:52 -07:00
Gregory Schier
c3970ba756 Run build before test as well 2024-08-09 07:29:48 -07:00
Gregory Schier
6f0a0a55a4 Fix 2024-08-09 07:12:32 -07:00
Gregory Schier
30fe3ee5cb Fix lint errors 2024-08-09 06:58:36 -07:00
Gregory Schier
1f637c583a Run vendor as separate script 2024-08-09 06:49:18 -07:00
Gregory Schier
3050995fed Fix xpath filtering 2024-08-08 22:54:15 -07:00
Gregory Schier
8081c86ec6 Better TS type generation 2024-08-08 22:07:05 -07:00
Gregory Schier
ed300dd320 Plugin runtime v2 (#62) 2024-08-08 21:30:59 -07:00
Gregory Schier
989b5a8058 Model and DB refactor (#61)
- [x] Move from `sqlx` to `rusqlite`
- [x] Generate TS types from Rust models
2024-08-05 07:58:20 -07:00
Gregory Schier
71013fd701 Use @yaakapp/api in models 2024-08-01 15:14:33 -07:00
Gregory Schier
76dd4380ce Updated plugin APIs 2024-08-01 07:01:57 -07:00
Gregory Schier
a643713139 Start of plugin types refactor 2024-07-31 14:56:55 -07:00
Gregory Schier
1cb86bc1b7 More flexible placeholder match 2024-07-31 07:42:18 -07:00
Gregory Schier
cc9bd2bc70 Template function return Result 2024-07-31 07:32:37 -07:00
Gregory Schier
90bf96c7c1 Apply forceUpdateKey to bulk pair editor 2024-07-30 15:50:29 -07:00
Gregory Schier
4e4c93c34e Always enable pairs from bulk editor 2024-07-30 15:35:06 -07:00
Gregory Schier
c2ce446692 Add rename/delete/send to cmd+k 2024-07-30 15:10:24 -07:00
Gregory Schier
d1a2c9622d Fix hotkey state messing up on Enter->submit 2024-07-30 15:10:08 -07:00
Gregory Schier
ecd8b93bd1 Add timestamp() to template fns 2024-07-30 14:04:33 -07:00
Gregory Schier
dd032a9e4d Fix fold gutter icon direction 2024-07-30 13:58:30 -07:00
Gregory Schier
f350f3b5f4 Named arguments in templating 2024-07-30 08:02:10 -07:00
Gregory Schier
45cb1ef0fe Tweak release things 2024-07-29 14:38:57 -07:00
446 changed files with 17490 additions and 14548 deletions

View File

@@ -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',
},
],
},
};

View File

@@ -81,7 +81,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install yaak CLI
run: go install github.com/yaakapp/yaakcli@latest
run: go install github.com/yaakapp/cli/cmd/yaakcli@latest
- name: Run lint
run: npm run lint
@@ -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 }}

View File

@@ -7,7 +7,8 @@
</scripts>
<node-interpreter value="project" />
<envs>
<env name="RUST_BACKTRACE" value="1" />
</envs>
<method v="2" />
</configuration>
</component>
</component>

View File

@@ -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`

View File

@@ -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-->

231
package-lock.json generated
View File

@@ -20,22 +20,26 @@
"@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.15",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.5",
"@tauri-apps/plugin-dialog": "^2.0.0-beta.7",
"@tauri-apps/plugin-fs": "^2.0.0-beta.7",
"@tauri-apps/plugin-os": "^2.0.0-beta.7",
"@tauri-apps/plugin-shell": "^2.0.0-beta.8",
"@tauri-apps/api": "^2.0.0-rc.4",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0-rc.1",
"@tauri-apps/plugin-dialog": "^2.0.0-rc.1",
"@tauri-apps/plugin-fs": "^2.0.0-rc.2",
"@tauri-apps/plugin-log": "^2.0.0-rc.1",
"@tauri-apps/plugin-os": "^2.0.0-rc.1",
"@tauri-apps/plugin-shell": "^2.0.0-rc.1",
"@yaakapp/api": "^0.1.17",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"cm6-graphql": "^0.0.9",
"codemirror": "^6.0.1",
"codemirror-json-schema": "^0.6.1",
"date-fns": "^3.3.1",
"eventemitter3": "^5.0.1",
"fast-fuzzy": "^1.12.0",
"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",
@@ -49,14 +53,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.22",
"@tauri-apps/cli": "^2.0.0-rc.12",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",
@@ -2342,23 +2345,18 @@
}
},
"node_modules/@tauri-apps/api": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.15.tgz",
"integrity": "sha512-H9w6iISmR+NvH4XuyCZB4zDN10tf9RFt6i/9JHEjaRhAowdAaJ+oiXq/3kedizNClHMtbTQ5j0oqDVPkZDAI8g==",
"engines": {
"node": ">= 18.18",
"npm": ">= 6.6.0",
"yarn": ">= 1.19.1"
},
"version": "2.0.0-rc.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz",
"integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.22.tgz",
"integrity": "sha512-OAuiDdSRKxNmr/dseQKKMoZZxIhQ6aAxmXJctGYJxCnkd62tQ8xeq87roVXGNS5Qkuv7WpySAyR0ntiMjvNLUA==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-rc.12.tgz",
"integrity": "sha512-rNcVSyGHGz8vNk542isYKPk5fEMAsgmzER+1s9YYbGZCH7m4e0rH89p/P9W40I/Z4AZk4ZqjpEeajeS5izDI4g==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -2371,22 +2369,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.22",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.22",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.22",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.22",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.22",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.22",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.22"
"@tauri-apps/cli-darwin-arm64": "2.0.0-rc.12",
"@tauri-apps/cli-darwin-x64": "2.0.0-rc.12",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-rc.12",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-rc.12",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-rc.12",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-rc.12",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-rc.12",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-rc.12",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-rc.12",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-rc.12"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.22.tgz",
"integrity": "sha512-Ofhythvg1Ks2IM87WUYNtgFzm21aU1Zn+8QP81lJy9Y7ZGMxP8FYfqeHz6GIWKI+CYf6I77HA8LHkT9pyE5PYg==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-rc.12.tgz",
"integrity": "sha512-zYxcAH4reyqKkqCAybggszFWkBvC+ZyZPTWFKXXVQ20MZc1q+e/0UJYC8UKsaumrbi1uptgamvnM8yql56x5QQ==",
"cpu": [
"arm64"
],
@@ -2400,9 +2398,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.22.tgz",
"integrity": "sha512-/lWIixo7WgmMUqcxlPT7Ojlkl6qbVlNDwUZ+9DtTpoWnaaBxv/YpSe1k62vDWEC7l0apFY+Fz7cRONN2wglFyQ==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-rc.12.tgz",
"integrity": "sha512-eme7pQzEzeGCk13V3uxUNRnkVZJukqwHotqEb2RdovXqJWSyESrighBy4PBG5Xn6wNYTOyoquY9+In4TOfJAzw==",
"cpu": [
"x64"
],
@@ -2416,9 +2414,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.22.tgz",
"integrity": "sha512-9nJCSStoxu4BKaKVJhu/uBJ8IsIofwAdsX0TWFxqo0obaZbeQSEpPhVsCy+uk3u/28dF+qyUtMCYawO2Uljnag==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-rc.12.tgz",
"integrity": "sha512-113T2NsLeoy6GXsqc0yjMoozt+KXzkAtUB7DL9Kcvx9IMfA87cUVaTNjnb2GFsoQqpCWGfHei3nr9n1PGEbwMg==",
"cpu": [
"arm"
],
@@ -2432,9 +2430,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.22.tgz",
"integrity": "sha512-TF9q9zHFBx9LaG2fJJC+BcpIokOmX1UIniBapndvx3dJmdDiK4F6w2QYKDkrBQVzDzcIducmdo2zNBv17O9tFQ==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-rc.12.tgz",
"integrity": "sha512-9TrUyNg0vmsYF7IbG+/sybEeiz6ikA1Kjd6JjC4iwfXjRff8fuTR7CIOb06imabxbLzGP79qSAnGAeTXz8E7qA==",
"cpu": [
"arm64"
],
@@ -2448,9 +2446,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.22.tgz",
"integrity": "sha512-ak/RdmaV7sATQmNOxlpHVlbKlrdquH7WH8nOv82X+iK+1HgAOGGqLqBUMzzhkGqo9SHQ9zJ6A2yOo7Z6TJXMmQ==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-rc.12.tgz",
"integrity": "sha512-YvE40+wdkNcXhwUAJNPyhNzJ8YS3saJoxGj7mtNQeNeNrKhxyj6hA5T6gw9KtMkwBOp+HGtqn+eDXiu0X7BBHQ==",
"cpu": [
"arm64"
],
@@ -2464,9 +2462,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.22.tgz",
"integrity": "sha512-9t+jQeMqBdXz51ikTh1PQFG/gs9PBzXmtMcIzUxE0juvH/ynjw0Vf+yZbNmwqVS9g7cj8XiBXoc6/N41SZE2cA==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-rc.12.tgz",
"integrity": "sha512-q+MJp/lSA5WINs78dCFMlU0/jQeUkGr9GHbKeppcVcpkcY/1vog70b4KhneyvbuklKBn/V8kd0FtIKCn8VP+KQ==",
"cpu": [
"x64"
],
@@ -2480,9 +2478,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.22.tgz",
"integrity": "sha512-PemcztfHG3HAuuo7HcnhfDrtN9NT7kueyNg8ipxJNPMa+s4K7kfieViyEiMW5pTr2F5WG/UuBSNcuwY+DVCcPA==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-rc.12.tgz",
"integrity": "sha512-5zodtleH2GFsB9lszDYrzPTLcr+MMqtpQpJWHATC1K03bLEA8ia8zSdBqRwm7u8NraMLl8TE7hc7hwq0uxGEcg==",
"cpu": [
"x64"
],
@@ -2496,9 +2494,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-EgKoG/jGEtTzhOp7ISjMdQsfd8IOG/5yZhO9Z4L/u7oB9mprKAJohYs24+ZxJtq2bOz4f/ZIysZ19nbkpxUzrg==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-rc.12.tgz",
"integrity": "sha512-nSu6VHpuq61DYM2YowLDLDwkK8im7dzYxIHXs+h8/rhkmadTujGhbyUhHPI1STA6hNyITUtSFpo6P2mEbfpAIg==",
"cpu": [
"arm64"
],
@@ -2512,9 +2510,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-67OrM2m4FB3KujPbjd/i+9lqcLDO3/ixqL1GMc3BoHhcjF+7QY08OxqWeitdsP/8ihnMIIdir2xEjNUKc6Zelw==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-rc.12.tgz",
"integrity": "sha512-d/4y57OisMuB+MUkTpZsryQRi9ZQXQ8SsMhrvEgu8sbX8/WRm0iZyGuIZ01RlZZHLIasXbKTkPX+hPQC5Juk8Q==",
"cpu": [
"ia32"
],
@@ -2528,9 +2526,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-BsO5xMUxliTZTImXnOC73sKT2U9VUeqR8AtklSObBcAg5LaZKpYOdF2pZzU6rIMAZwzROTAT1hYsr4r/nx2UZg==",
"version": "2.0.0-rc.12",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-rc.12.tgz",
"integrity": "sha512-RsPUvsbFza03ysh0nU2nM3P2CVWz9cu7CRHwOEdtXjWWNREHUYCaVpqQKz0tn2sG19yXiNIB40iqrIBUmb/IoA==",
"cpu": [
"x64"
],
@@ -2544,43 +2542,51 @@
}
},
"node_modules/@tauri-apps/plugin-clipboard-manager": {
"version": "2.1.0-beta.5",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.1.0-beta.5.tgz",
"integrity": "sha512-7YQEXRHXn5dIr/YcE7RtkoAhc6XwpqI7Qz0I3FcHn5vMbVvQ5OxKnGqEa8ZGRud6R3G9pNdnEKglLXLgUXK8tA==",
"version": "2.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz",
"integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@tauri-apps/plugin-dialog": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-beta.7.tgz",
"integrity": "sha512-myywwpsKbquDDzl5zaOmmLLv5O8EJ/GgHDAoVSPwO97R4iWzkDvj3HFF91tNh7i25Tu/bP6jYPAdZA1NCRxxtg==",
"version": "2.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz",
"integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@tauri-apps/plugin-fs": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-beta.7.tgz",
"integrity": "sha512-hsZyhzvy+xtRfbrKI2rmU1ZfmgbSs7Zu/6a12MFlJKVzqXmUwJvggcjYdm1cEFdLbnOOsszENXbwMnkzmxtirA==",
"version": "2.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-rc.2.tgz",
"integrity": "sha512-TFjCfso3tN4b5s2EBjqP8N2gYrPh93Ds3VNKj8pCXv4wbvnItyfG0aHO0haUsedBOHQryDwv9vDAdPX6/T0a+g==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@tauri-apps/plugin-log": {
"version": "2.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.0.0-rc.1.tgz",
"integrity": "sha512-+Tz0zo4FDtC/5j7neeIq5ievgKbUXBV2+X5HtbaR8ZZ2bcksCp8UqeHd6cyyN+FSk4qaU01LIGkuExtxk1h/FA==",
"dependencies": {
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@tauri-apps/plugin-os": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-beta.7.tgz",
"integrity": "sha512-CHo09ecxUU0NFkAqctXeQzdaXw02EXulqcaZnbjrBfRJ2ulmGq7zaUCsHihfcqWcdnmNwmP9Wh/gyznMc1JF9Q==",
"version": "2.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz",
"integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@tauri-apps/plugin-shell": {
"version": "2.0.0-beta.8",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-beta.8.tgz",
"integrity": "sha512-rFXI6MvsCdSGbuKbDu/NaOePREb9YTVTdeugHdvvljnKWW3dvmThBb2h/8Hxj+Z7Cd8MUoRxPeJWUZbPbJ2Imw==",
"version": "2.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz",
"integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.4"
}
},
"node_modules/@types/babel__core": {
@@ -2979,6 +2985,27 @@
"resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz",
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
},
"node_modules/@yaakapp/api": {
"version": "0.1.17",
"resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.17.tgz",
"integrity": "sha512-VE9A0FDZwczZkTAbMOYjQOKzbW1KmaItq/mPSuTgU87Lf570JUepcHVtL7QFLV1U/R5q+n7I6xQg9Q2mDj/OWQ==",
"dependencies": {
"@types/node": "^22.0.0"
}
},
"node_modules/@yaakapp/api/node_modules/@types/node": {
"version": "22.0.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz",
"integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==",
"dependencies": {
"undici-types": "~6.11.1"
}
},
"node_modules/@yaakapp/api/node_modules/undici-types": {
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ=="
},
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -5719,8 +5746,7 @@
"node_modules/eventemitter3": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"dev": true
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
},
"node_modules/execa": {
"version": "7.2.0",
@@ -7393,6 +7419,26 @@
"jiti": "bin/jiti.js"
}
},
"node_modules/jotai": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.9.3.tgz",
"integrity": "sha512-IqMWKoXuEzWSShjd9UhalNsRGbdju5G2FrqNLQJT+Ih6p41VNYe2sav5hnwQx4HJr25jq9wRqvGSWGviGG6Gjw==",
"engines": {
"node": ">=12.20.0"
},
"peerDependencies": {
"@types/react": ">=17.0.0",
"react": ">=17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"react": {
"optional": true
}
}
},
"node_modules/js-base64": {
"version": "3.7.7",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz",
@@ -11081,29 +11127,6 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"optional": true
},
"node_modules/tauri-plugin-log-api": {
"name": "@tauri-apps/plugin-log",
"version": "2.0.0-beta.4",
"resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-log.git#1dc096891b697dc9af1241450c4608cbc33695da",
"license": "MIT or APACHE-2.0",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.11"
}
},
"node_modules/tauri-plugin-log-api/node_modules/@tauri-apps/api": {
"version": "2.0.0-beta.11",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.11.tgz",
"integrity": "sha512-wJRY+fBUm3KpqZDHMIz5HRv+1vlnvRJ/dFxiyY3NlINTx2qXqDou5qWYcP1CuZXsd39InWVPV3FAZvno/kGCkA==",
"engines": {
"node": ">= 18",
"npm": ">= 6.6.0",
"yarn": ">= 1.19.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/term-size": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",

View File

@@ -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,22 +35,26 @@
"@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.15",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.5",
"@tauri-apps/plugin-dialog": "^2.0.0-beta.7",
"@tauri-apps/plugin-fs": "^2.0.0-beta.7",
"@tauri-apps/plugin-os": "^2.0.0-beta.7",
"@tauri-apps/plugin-shell": "^2.0.0-beta.8",
"@tauri-apps/api": "^2.0.0-rc.4",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0-rc.1",
"@tauri-apps/plugin-dialog": "^2.0.0-rc.1",
"@tauri-apps/plugin-fs": "^2.0.0-rc.2",
"@tauri-apps/plugin-log": "^2.0.0-rc.1",
"@tauri-apps/plugin-os": "^2.0.0-rc.1",
"@tauri-apps/plugin-shell": "^2.0.0-rc.1",
"@yaakapp/api": "^0.1.17",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"cm6-graphql": "^0.0.9",
"codemirror": "^6.0.1",
"codemirror-json-schema": "^0.6.1",
"date-fns": "^3.3.1",
"eventemitter3": "^5.0.1",
"fast-fuzzy": "^1.12.0",
"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 +68,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.22",
"@tauri-apps/cli": "^2.0.0-rc.12",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",

2
plugin-runtime-types/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
lib
node_modules

44
plugin-runtime-types/package-lock.json generated Normal file
View 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=="
}
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "@yaakapp/api",
"version": "0.1.17",
"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"
}
}

View 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 CallHttpRequestActionArgs = { httpRequest: HttpRequest, };

View 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 { CallHttpRequestActionArgs } from "./CallHttpRequestActionArgs";
export type CallHttpRequestActionRequest = { key: string, pluginRefId: string, args: CallHttpRequestActionArgs, };

View 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 }, };

View 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 { CallTemplateFunctionArgs } from "./CallTemplateFunctionArgs";
export type CallTemplateFunctionRequest = { name: string, args: CallTemplateFunctionArgs, };

View 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 CallTemplateFunctionResponse = { value: string | null, };

View 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], };

View 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";

View 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";

View 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>, };

View 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, };

View 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 = {};

View 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>, };

View 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, };

View 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, };

View 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 ExportHttpRequestResponse = { content: string, };

View 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, };

View 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, };

View 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, };

View 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 FindHttpResponsesResponse = { httpResponses: Array<HttpResponse>, };

View 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, };

View 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 GetHttpRequestActionsRequest = Record<string, never>;

View 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 { HttpRequestAction } from "./HttpRequestAction";
export type GetHttpRequestActionsResponse = { actions: Array<HttpRequestAction>, pluginRefId: string, };

View 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 GetHttpRequestByIdRequest = { id: string, };

View 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 GetHttpRequestByIdResponse = { httpRequest: HttpRequest | null, };

View 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 { TemplateFunction } from "./TemplateFunction";
export type GetTemplateFunctionsResponse = { functions: Array<TemplateFunction>, pluginRefId: string, };

View 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 }, };

View 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, updatedAt: string, content: string, eventType: GrpcEventType, metadata: { [key: string]: string }, status: number | null, error: string | null, };

View 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";

View 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, };

View 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>, };

View 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>, };

View 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, };

View 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, };

View 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>, };

View 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, };

View 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, };

View 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, };

View 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>, };

View 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, };

View 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, };

View 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 { 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 { PluginBootRequest } from "./PluginBootRequest";
import type { PluginBootResponse } from "./PluginBootResponse";
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" } & PluginBootRequest | { "type": "boot_response" } & PluginBootResponse | { "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;

View 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, };

View File

@@ -0,0 +1,15 @@
// 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 { Plugin } from "./Plugin";
import type { Settings } from "./Settings";
import type { Workspace } from "./Workspace";
export type Model = Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | KeyValue | Workspace | CookieJar | Settings | Plugin;

View 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 Plugin = { id: string, model: "plugin", createdAt: string, updatedAt: string, checkedAt: string | null, name: string, version: string, uri: string, enabled: boolean, };

View 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 PluginBootRequest = { dir: string, };

View 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 PluginBootResponse = { name: string, version: string, capabilities: Array<string>, };

View 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, };

View 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 RenderHttpRequestResponse = { httpRequest: HttpRequest, };

View 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";

View 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, };

View 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, };

View 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, };

View 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, };

View 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>, };

View 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;

View 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, };

View 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 TemplateFunctionCheckboxArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };

View 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 TemplateFunctionHttpRequestArg = { name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };

View 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 { TemplateFunctionSelectOption } from "./TemplateFunctionSelectOption";
export type TemplateFunctionSelectArg = { options: Array<TemplateFunctionSelectOption>, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };

View 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 TemplateFunctionSelectOption = { name: string, value: string, };

View 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, };

View 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";

View 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, };

View File

@@ -0,0 +1,2 @@
export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
export type OneOrMany<T> = T[] | T;

View File

@@ -0,0 +1,66 @@
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/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/PluginBootRequest';
export * from './gen/PluginBootResponse';
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';
export * from './gen/Plugin';

View 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']>;
};
};

View 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>;
};

View File

@@ -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;
};

View 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>;
};

View File

@@ -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>;
};

View 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>;
};

View 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 PluginDefinition = {
importer?: ImporterPlugin;
theme?: ThemePlugin;
filter?: FilterPlugin;
httpRequestActions?: HttpRequestActionPlugin[];
templateFunctions?: TemplateFunctionPlugin[];
};

View 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>;
}>;
};

View 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"
]
}

View File

@@ -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",

View File

@@ -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",

View 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);
});
});
}
}
}

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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: {},
},
hookExport: {
name: "hookExport",
requestType: HookExportRequest,
requestStream: false,
responseType: HookResponse,
responseStream: false,
options: {},
},
hookResponseFilter: {
name: "hookResponseFilter",
requestType: HookResponseFilterRequest,
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>>;
hookExport(request: HookExportRequest, context: CallContext & CallContextExt): Promise<DeepPartial<HookResponse>>;
hookResponseFilter(
request: HookResponseFilterRequest,
eventStream(
request: AsyncIterable<EventStreamEvent>,
context: CallContext & CallContextExt,
): Promise<DeepPartial<HookResponse>>;
): ServerStreamingMethodResult<DeepPartial<EventStreamEvent>>;
}
export interface PluginRuntimeClient<CallOptionsExt = {}> {
hookImport(request: DeepPartial<HookImportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
hookExport(request: DeepPartial<HookExportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
hookResponseFilter(
request: DeepPartial<HookResponseFilterRequest>,
eventStream(
request: AsyncIterable<DeepPartial<EventStreamEvent>>,
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> };

View File

@@ -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));
}
});
})();

View File

@@ -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();
});
}

View File

@@ -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));
}

View File

@@ -11,7 +11,6 @@
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"skipLibCheck": true,
"paths": {
"*": [
"node_modules/*",

View File

@@ -3,30 +3,9 @@ syntax = "proto3";
package yaak.plugins.runtime;
service PluginRuntime {
rpc hookImport (HookImportRequest) returns (HookResponse);
rpc hookExport (HookExportRequest) returns (HookResponse);
rpc hookResponseFilter (HookResponseFilterRequest) 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;
}

View File

@@ -52,7 +52,7 @@ mkdirSync(destDir, {recursive: true});
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, {});

View File

@@ -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);

View File

@@ -3,6 +3,8 @@ const Downloader = require("nodejs-file-downloader");
const path = require("node:path");
const {rmSync, mkdirSync, cpSync} = require("node:fs");
const VERSION = '27.2';
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
@@ -10,10 +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',
[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 = {
@@ -36,7 +38,7 @@ 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());

View File

@@ -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"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM http_responses\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "07d1a1c7b4f3d9625a766e60fd57bb779b71dae30e5bbce34885a911a5a42428"
}

Some files were not shown because too many files have changed in this diff Show More