mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-17 06:29:38 +02:00
4
.github/workflows/ci-js.yml
vendored
4
.github/workflows/ci-js.yml
vendored
@@ -1,10 +1,10 @@
|
|||||||
on: [push, pull_request]
|
on: [push]
|
||||||
|
|
||||||
name: CI (JS)
|
name: CI (JS)
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: Check
|
name: Lint/Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
41
.github/workflows/ci-rust.yml
vendored
41
.github/workflows/ci-rust.yml
vendored
@@ -2,6 +2,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- src-tauri/**
|
- src-tauri/**
|
||||||
|
- .github/workflows/**
|
||||||
|
|
||||||
name: CI (Rust)
|
name: CI (Rust)
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: Test
|
name: Check/Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -21,10 +22,42 @@ jobs:
|
|||||||
- run: |
|
- run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libwebkit2gtk-4.1-dev
|
sudo apt-get install -y libwebkit2gtk-4.1-dev
|
||||||
- uses: actions-rs/toolchain@v1
|
- name: Install Rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: stable
|
toolchain: ${{ inputs.rust-version }}
|
||||||
override: true
|
override: true
|
||||||
- run: cargo check
|
components: rustfmt, clippy
|
||||||
|
- name: Set up cargo cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
continue-on-error: false
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-cargo-
|
||||||
|
- name: Lint
|
||||||
|
run: |
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo clippy -- -D warnings
|
||||||
|
- name: Install cargo check tools
|
||||||
|
run: |
|
||||||
|
cargo install --locked cargo-deny || true
|
||||||
|
cargo install --locked cargo-outdated || true
|
||||||
|
cargo install --locked cargo-udeps || true
|
||||||
|
cargo install --locked cargo-audit || true
|
||||||
|
cargo install --locked cargo-pants || true
|
||||||
|
- name: Check
|
||||||
|
run: |
|
||||||
|
cargo deny check
|
||||||
|
cargo outdated --exit-code 1
|
||||||
|
cargo udeps
|
||||||
|
rm -rf ~/.cargo/advisory-db
|
||||||
|
cargo audit
|
||||||
|
cargo pants
|
||||||
- run: cargo test --all
|
- run: cargo test --all
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,4 +27,5 @@ dist-ssr
|
|||||||
*.sqlite
|
*.sqlite
|
||||||
*.sqlite-*
|
*.sqlite-*
|
||||||
|
|
||||||
.cargo
|
.cargo
|
||||||
|
plugins/**/build
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/exporter-curl'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import jp from 'jsonpath';
|
import jp from 'jsonpath';
|
||||||
|
|
||||||
export function pluginHookResponseFilter(filter, text) {
|
export function pluginHookResponseFilter(ctx, filter, text) {
|
||||||
let parsed;
|
let parsed;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(text);
|
parsed = JSON.parse(text);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/filter-jsonpath'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import xpath from 'xpath';
|
import xpath from 'xpath';
|
||||||
import { DOMParser } from '@xmldom/xmldom';
|
import { DOMParser } from '@xmldom/xmldom';
|
||||||
|
|
||||||
export function pluginHookResponseFilter(filter, text) {
|
export function pluginHookResponseFilter(ctx, filter, text) {
|
||||||
const doc = new DOMParser().parseFromString(text, 'text/xml');
|
const doc = new DOMParser().parseFromString(text, 'text/xml');
|
||||||
const filtered = `${xpath.select(filter, doc)}`;
|
const filtered = `${xpath.select(filter, doc)}`;
|
||||||
return { filtered };
|
return { filtered };
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/filter-xpath'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type Pair = string | boolean;
|
|||||||
|
|
||||||
type PairsByName = Record<string, Pair[]>;
|
type PairsByName = Record<string, Pair[]>;
|
||||||
|
|
||||||
export function pluginHookImport(rawData: string) {
|
export function pluginHookImport(ctx: any, rawData: string) {
|
||||||
if (!rawData.match(/^\s*curl /)) {
|
if (!rawData.match(/^\s*curl /)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/importer-curl'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
HttpRequest,
|
HttpRequest,
|
||||||
Workspace,
|
Workspace,
|
||||||
} from '../../../src-web/lib/models';
|
} from '../../../src-web/lib/models';
|
||||||
import { parse as parseYaml } from 'yaml';
|
import '../../../src-web/plugin/runtime.d.ts';
|
||||||
|
|
||||||
type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export interface ExportResources {
|
|||||||
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pluginHookImport(contents: string) {
|
export function pluginHookImport(ctx: YaakContext, contents: string) {
|
||||||
let parsed: any;
|
let parsed: any;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -25,8 +25,10 @@ export function pluginHookImport(contents: string) {
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parsed = parseYaml(contents);
|
parsed = parsed ?? YAML.parse(contents);
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
console.log('FAILED', e);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isJSObject(parsed)) return;
|
if (!isJSObject(parsed)) return;
|
||||||
if (!Array.isArray(parsed.resources)) return;
|
if (!Array.isArray(parsed.resources)) return;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/importer-insomnia'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ interface ExportResources {
|
|||||||
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pluginHookImport(contents: string): { resources: ExportResources } | undefined {
|
export function pluginHookImport(
|
||||||
|
ctx: any,
|
||||||
|
contents: string,
|
||||||
|
): { resources: ExportResources } | undefined {
|
||||||
|
console.log('CTX', ctx);
|
||||||
const root = parseJSONToRecord(contents);
|
const root = parseJSONToRecord(contents);
|
||||||
if (root == null) return;
|
if (root == null) return;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ describe('importer-postman', () => {
|
|||||||
for (const fixture of fixtures) {
|
for (const fixture of fixtures) {
|
||||||
test('Imports ' + fixture, () => {
|
test('Imports ' + fixture, () => {
|
||||||
const contents = fs.readFileSync(path.join(p, fixture), 'utf-8');
|
const contents = fs.readFileSync(path.join(p, fixture), 'utf-8');
|
||||||
const imported = pluginHookImport(contents);
|
const imported = pluginHookImport({}, contents);
|
||||||
const folder0 = newId('folder');
|
const folder0 = newId('folder');
|
||||||
const folder1 = newId('folder');
|
const folder1 = newId('folder');
|
||||||
expect(imported).toEqual({
|
expect(imported).toEqual({
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/importer-postman'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export function pluginHookImport(contents: string) {
|
export function pluginHookImport(ctx: any, contents: string) {
|
||||||
let parsed;
|
let parsed;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(contents);
|
parsed = JSON.parse(contents);
|
||||||
@@ -18,7 +18,7 @@ export function pluginHookImport(contents: string) {
|
|||||||
// Migrate v1 to v2 -- changes requests to httpRequests
|
// Migrate v1 to v2 -- changes requests to httpRequests
|
||||||
if ('requests' in parsed.resources) {
|
if ('requests' in parsed.resources) {
|
||||||
parsed.resources.httpRequests = parsed.resources.requests;
|
parsed.resources.httpRequests = parsed.resources.requests;
|
||||||
delete parsed.resources.requests;
|
delete parsed.resources['requests'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return { resources: parsed.resources }; // Should already be in the correct format
|
return { resources: parsed.resources }; // Should already be in the correct format
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export default defineConfig({
|
|||||||
fileName: 'index',
|
fileName: 'index',
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
},
|
},
|
||||||
outDir: resolve(__dirname, '../../src-tauri/plugins/importer-yaak'),
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
outDir: resolve(__dirname, 'build'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
1395
src-tauri/Cargo.lock
generated
1395
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -26,11 +26,13 @@ openssl-sys = { version = "0.9", features = ["vendored"] } # For Ubuntu installa
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
grpc = { path = "./grpc" }
|
grpc = { path = "./grpc" }
|
||||||
templates = { path = "./templates" }
|
templates = { path = "./templates" }
|
||||||
|
anyhow = "1.0.86"
|
||||||
base64 = "0.22.0"
|
base64 = "0.22.0"
|
||||||
boa_engine = { version = "0.18.0", features = ["annex-b"] }
|
|
||||||
boa_runtime = { version = "0.18.0" }
|
|
||||||
chrono = { version = "0.4.31", features = ["serde"] }
|
chrono = { version = "0.4.31", features = ["serde"] }
|
||||||
datetime = "0.5.2"
|
datetime = "0.5.2"
|
||||||
|
deno_ast = { version = "0.39.0", features = ["transpiling"] }
|
||||||
|
deno_console = "0.155.0"
|
||||||
|
deno_core = { version = "0.284.0" }
|
||||||
hex_color = "3.0.0"
|
hex_color = "3.0.0"
|
||||||
http = "0.2.10"
|
http = "0.2.10"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
@@ -40,8 +42,9 @@ reqwest = { version = "0.11.23", features = ["multipart", "cookies", "gzip", "br
|
|||||||
reqwest_cookie_store = "0.6.0"
|
reqwest_cookie_store = "0.6.0"
|
||||||
serde = { version = "1.0.198", features = ["derive"] }
|
serde = { version = "1.0.198", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.116", features = ["raw_value"] }
|
serde_json = { version = "1.0.116", features = ["raw_value"] }
|
||||||
|
serde_yaml = "0.9.34+deprecated"
|
||||||
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
|
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
|
||||||
tauri = { version = "2.0.0-beta", features = ["config-toml", "devtools", "protocol-asset"] }
|
tauri = { version = "2.0.0-beta", features = ["devtools", "protocol-asset"] }
|
||||||
tauri-plugin-clipboard-manager = "2.1.0-beta"
|
tauri-plugin-clipboard-manager = "2.1.0-beta"
|
||||||
tauri-plugin-deep-link = "2.0.0-beta"
|
tauri-plugin-deep-link = "2.0.0-beta"
|
||||||
tauri-plugin-dialog = "2.0.0-beta"
|
tauri-plugin-dialog = "2.0.0-beta"
|
||||||
|
|||||||
@@ -1,297 +0,0 @@
|
|||||||
var j = "(?:" + [
|
|
||||||
"\\|\\|",
|
|
||||||
"\\&\\&",
|
|
||||||
";;",
|
|
||||||
"\\|\\&",
|
|
||||||
"\\<\\(",
|
|
||||||
"\\<\\<\\<",
|
|
||||||
">>",
|
|
||||||
">\\&",
|
|
||||||
"<\\&",
|
|
||||||
"[&;()|<>]"
|
|
||||||
].join("|") + ")", D = new RegExp("^" + j + "$"), q = "|&;()<> \\t", M = '"((\\\\"|[^"])*?)"', Q = "'((\\\\'|[^'])*?)'", V = /^#$/, _ = "'", G = '"', U = "$", $ = "", z = 4294967296;
|
|
||||||
for (var L = 0; L < 4; L++)
|
|
||||||
$ += (z * Math.random()).toString(16);
|
|
||||||
var J = new RegExp("^" + $);
|
|
||||||
function X(n, s) {
|
|
||||||
for (var e = s.lastIndex, t = [], c; c = s.exec(n); )
|
|
||||||
t.push(c), s.lastIndex === c.index && (s.lastIndex += 1);
|
|
||||||
return s.lastIndex = e, t;
|
|
||||||
}
|
|
||||||
function F(n, s, e) {
|
|
||||||
var t = typeof n == "function" ? n(e) : n[e];
|
|
||||||
return typeof t > "u" && e != "" ? t = "" : typeof t > "u" && (t = "$"), typeof t == "object" ? s + $ + JSON.stringify(t) + $ : s + t;
|
|
||||||
}
|
|
||||||
function K(n, s, e) {
|
|
||||||
e || (e = {});
|
|
||||||
var t = e.escape || "\\", c = "(\\" + t + `['"` + q + `]|[^\\s'"` + q + "])+", m = new RegExp([
|
|
||||||
"(" + j + ")",
|
|
||||||
// control chars
|
|
||||||
"(" + c + "|" + M + "|" + Q + ")+"
|
|
||||||
].join("|"), "g"), f = X(n, m);
|
|
||||||
if (f.length === 0)
|
|
||||||
return [];
|
|
||||||
s || (s = {});
|
|
||||||
var w = !1;
|
|
||||||
return f.map(function(r) {
|
|
||||||
var a = r[0];
|
|
||||||
if (!a || w)
|
|
||||||
return;
|
|
||||||
if (D.test(a))
|
|
||||||
return { op: a };
|
|
||||||
var x = !1, C = !1, d = "", O = !1, i;
|
|
||||||
function T() {
|
|
||||||
i += 1;
|
|
||||||
var v, p, R = a.charAt(i);
|
|
||||||
if (R === "{") {
|
|
||||||
if (i += 1, a.charAt(i) === "}")
|
|
||||||
throw new Error("Bad substitution: " + a.slice(i - 2, i + 1));
|
|
||||||
if (v = a.indexOf("}", i), v < 0)
|
|
||||||
throw new Error("Bad substitution: " + a.slice(i));
|
|
||||||
p = a.slice(i, v), i = v;
|
|
||||||
} else if (/[*@#?$!_-]/.test(R))
|
|
||||||
p = R, i += 1;
|
|
||||||
else {
|
|
||||||
var g = a.slice(i);
|
|
||||||
v = g.match(/[^\w\d_]/), v ? (p = g.slice(0, v.index), i += v.index - 1) : (p = g, i = a.length);
|
|
||||||
}
|
|
||||||
return F(s, "", p);
|
|
||||||
}
|
|
||||||
for (i = 0; i < a.length; i++) {
|
|
||||||
var u = a.charAt(i);
|
|
||||||
if (O = O || !x && (u === "*" || u === "?"), C)
|
|
||||||
d += u, C = !1;
|
|
||||||
else if (x)
|
|
||||||
u === x ? x = !1 : x == _ ? d += u : u === t ? (i += 1, u = a.charAt(i), u === G || u === t || u === U ? d += u : d += t + u) : u === U ? d += T() : d += u;
|
|
||||||
else if (u === G || u === _)
|
|
||||||
x = u;
|
|
||||||
else {
|
|
||||||
if (D.test(u))
|
|
||||||
return { op: a };
|
|
||||||
if (V.test(u)) {
|
|
||||||
w = !0;
|
|
||||||
var b = { comment: n.slice(r.index + i + 1) };
|
|
||||||
return d.length ? [d, b] : [b];
|
|
||||||
} else
|
|
||||||
u === t ? C = !0 : u === U ? d += T() : d += u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return O ? { op: "glob", pattern: d } : d;
|
|
||||||
}).reduce(function(r, a) {
|
|
||||||
return typeof a > "u" ? r : r.concat(a);
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
var Y = function(s, e, t) {
|
|
||||||
var c = K(s, e, t);
|
|
||||||
return typeof e != "function" ? c : c.reduce(function(m, f) {
|
|
||||||
if (typeof f == "object")
|
|
||||||
return m.concat(f);
|
|
||||||
var w = f.split(RegExp("(" + $ + ".*?" + $ + ")", "g"));
|
|
||||||
return w.length === 1 ? m.concat(w[0]) : m.concat(w.filter(Boolean).map(function(r) {
|
|
||||||
return J.test(r) ? JSON.parse(r.split($)[1]) : r;
|
|
||||||
}));
|
|
||||||
}, []);
|
|
||||||
}, Z = Y;
|
|
||||||
const ae = "curl", se = "cURL", ie = "cURL command line tool", H = ["d", "data", "data-raw", "data-urlencode", "data-binary", "data-ascii"], ee = [
|
|
||||||
["url"],
|
|
||||||
// Specify the URL explicitly
|
|
||||||
["user", "u"],
|
|
||||||
// Authentication
|
|
||||||
["digest"],
|
|
||||||
// Apply auth as digest
|
|
||||||
["header", "H"],
|
|
||||||
["cookie", "b"],
|
|
||||||
["get", "G"],
|
|
||||||
// Put the post data in the URL
|
|
||||||
["d", "data"],
|
|
||||||
// Add url encoded data
|
|
||||||
["data-raw"],
|
|
||||||
["data-urlencode"],
|
|
||||||
["data-binary"],
|
|
||||||
["data-ascii"],
|
|
||||||
["form", "F"],
|
|
||||||
// Add multipart data
|
|
||||||
["request", "X"],
|
|
||||||
// Request method
|
|
||||||
H
|
|
||||||
].flatMap((n) => n);
|
|
||||||
function oe(n) {
|
|
||||||
if (!n.match(/^\s*curl /))
|
|
||||||
return null;
|
|
||||||
const s = [], e = n.replace(/\ncurl/g, "; curl");
|
|
||||||
let t = [];
|
|
||||||
const m = Z(e).flatMap((r) => typeof r == "string" && r.startsWith("-") && !r.startsWith("--") && r.length > 2 ? [r.slice(0, 2), r.slice(2)] : r);
|
|
||||||
for (const r of m) {
|
|
||||||
if (typeof r == "string") {
|
|
||||||
r.startsWith("$") ? t.push(r.slice(1)) : t.push(r);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ("comment" in r)
|
|
||||||
continue;
|
|
||||||
const { op: a } = r;
|
|
||||||
if (a === ";") {
|
|
||||||
s.push(t), t = [];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (a != null && a.startsWith("$")) {
|
|
||||||
const x = a.slice(2, a.length - 1).replace(/\\'/g, "'");
|
|
||||||
t.push(x);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
a === "glob" && t.push(r.pattern);
|
|
||||||
}
|
|
||||||
s.push(t);
|
|
||||||
const f = {
|
|
||||||
model: "workspace",
|
|
||||||
id: N("workspace"),
|
|
||||||
name: "Curl Import"
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
resources: {
|
|
||||||
httpRequests: s.filter((r) => r[0] === "curl").map((r) => te(r, f.id)),
|
|
||||||
workspaces: [f]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function te(n, s) {
|
|
||||||
const e = {}, t = [];
|
|
||||||
for (let o = 1; o < n.length; o++) {
|
|
||||||
let l = n[o];
|
|
||||||
if (typeof l == "string" && (l = l.trim()), typeof l == "string" && l.match(/^-{1,2}[\w-]+/)) {
|
|
||||||
const E = l[0] === "-" && l[1] !== "-";
|
|
||||||
let h = l.replace(/^-{1,2}/, "");
|
|
||||||
if (!ee.includes(h))
|
|
||||||
continue;
|
|
||||||
let y;
|
|
||||||
const S = n[o + 1];
|
|
||||||
E && h.length > 1 ? (y = h.slice(1), h = h.slice(0, 1)) : typeof S == "string" && !S.startsWith("-") ? (y = S, o++) : y = !0, e[h] = e[h] || [], e[h].push(y);
|
|
||||||
} else
|
|
||||||
l && t.push(l);
|
|
||||||
}
|
|
||||||
let c, m;
|
|
||||||
const f = A(e, t[0] || "", ["url"]), [w, r] = W(f, "?");
|
|
||||||
c = (r == null ? void 0 : r.split("&").map((o) => {
|
|
||||||
const l = W(o, "=");
|
|
||||||
return { name: l[0] ?? "", value: l[1] ?? "", enabled: !0 };
|
|
||||||
})) ?? [], m = w ?? f;
|
|
||||||
const [a, x] = A(e, "", ["u", "user"]).split(/:(.*)$/), C = A(e, !1, ["digest"]), d = a ? C ? "digest" : "basic" : null, O = a ? {
|
|
||||||
username: a.trim(),
|
|
||||||
password: (x ?? "").trim()
|
|
||||||
} : {}, i = [
|
|
||||||
...e.header || [],
|
|
||||||
...e.H || []
|
|
||||||
].map((o) => {
|
|
||||||
const [l, E] = o.split(/:(.*)$/);
|
|
||||||
return E ? {
|
|
||||||
name: (l ?? "").trim(),
|
|
||||||
value: E.trim(),
|
|
||||||
enabled: !0
|
|
||||||
} : {
|
|
||||||
name: (l ?? "").trim().replace(/;$/, ""),
|
|
||||||
value: "",
|
|
||||||
enabled: !0
|
|
||||||
};
|
|
||||||
}), T = [
|
|
||||||
...e.cookie || [],
|
|
||||||
...e.b || []
|
|
||||||
].map((o) => {
|
|
||||||
const l = o.split("=", 1)[0], E = o.replace(`${l}=`, "");
|
|
||||||
return `${l}=${E}`;
|
|
||||||
}).join("; "), u = i.find((o) => o.name.toLowerCase() === "cookie");
|
|
||||||
T && u ? u.value += `; ${T}` : T && i.push({
|
|
||||||
name: "Cookie",
|
|
||||||
value: T,
|
|
||||||
enabled: !0
|
|
||||||
});
|
|
||||||
const b = ne(e), v = i.find((o) => o.name.toLowerCase() === "content-type"), p = v ? v.value.split(";")[0] : null, R = [
|
|
||||||
...e.form || [],
|
|
||||||
...e.F || []
|
|
||||||
].map((o) => {
|
|
||||||
const l = o.split("="), E = l[0] ?? "", h = l[1] ?? "", y = {
|
|
||||||
name: E,
|
|
||||||
enabled: !0
|
|
||||||
};
|
|
||||||
return h.indexOf("@") === 0 ? y.file = h.slice(1) : y.value = h, y;
|
|
||||||
});
|
|
||||||
let g = {}, I = null;
|
|
||||||
const B = A(e, !1, ["G", "get"]);
|
|
||||||
b.length > 0 && B ? c.push(...b) : b.length > 0 && (p == null || p === "application/x-www-form-urlencoded") ? (I = p ?? "application/x-www-form-urlencoded", g = {
|
|
||||||
form: b.map((o) => ({
|
|
||||||
...o,
|
|
||||||
name: decodeURIComponent(o.name || ""),
|
|
||||||
value: decodeURIComponent(o.value || "")
|
|
||||||
}))
|
|
||||||
}, i.push({
|
|
||||||
name: "Content-Type",
|
|
||||||
value: "application/x-www-form-urlencoded",
|
|
||||||
enabled: !0
|
|
||||||
})) : b.length > 0 ? (I = p === "application/json" || p === "text/xml" || p === "text/plain" ? p : "other", g = {
|
|
||||||
text: b.map(({ name: o, value: l }) => o && l ? `${o}=${l}` : o || l).join("&")
|
|
||||||
}) : R.length && (I = p ?? "multipart/form-data", g = {
|
|
||||||
form: R
|
|
||||||
}, p == null && i.push({
|
|
||||||
name: "Content-Type",
|
|
||||||
value: "multipart/form-data",
|
|
||||||
enabled: !0
|
|
||||||
}));
|
|
||||||
let P = A(e, "", ["X", "request"]).toUpperCase();
|
|
||||||
return P === "" && g && (P = "text" in g || "form" in g ? "POST" : "GET"), {
|
|
||||||
id: N("http_request"),
|
|
||||||
model: "http_request",
|
|
||||||
workspaceId: s,
|
|
||||||
name: "",
|
|
||||||
urlParameters: c,
|
|
||||||
url: m,
|
|
||||||
method: P,
|
|
||||||
headers: i,
|
|
||||||
authentication: O,
|
|
||||||
authenticationType: d,
|
|
||||||
body: g,
|
|
||||||
bodyType: I,
|
|
||||||
folderId: null,
|
|
||||||
sortPriority: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const ne = (n) => {
|
|
||||||
let s = [];
|
|
||||||
for (const e of H) {
|
|
||||||
const t = n[e];
|
|
||||||
if (!(!t || t.length === 0))
|
|
||||||
for (const c of t) {
|
|
||||||
if (typeof c != "string")
|
|
||||||
continue;
|
|
||||||
const [m, f] = c.split("=");
|
|
||||||
c.startsWith("@") ? s.push({
|
|
||||||
name: m ?? "",
|
|
||||||
value: "",
|
|
||||||
filePath: c.slice(1),
|
|
||||||
enabled: !0
|
|
||||||
}) : s.push({
|
|
||||||
name: m ?? "",
|
|
||||||
value: e === "data-urlencode" ? encodeURIComponent(f ?? "") : f ?? "",
|
|
||||||
enabled: !0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}, A = (n, s, e) => {
|
|
||||||
for (const t of e)
|
|
||||||
if (n[t] && n[t].length)
|
|
||||||
return n[t][0];
|
|
||||||
return s;
|
|
||||||
};
|
|
||||||
function W(n, s) {
|
|
||||||
const e = n.indexOf(s);
|
|
||||||
return e > -1 ? [n.slice(0, e), n.slice(e + 1)] : [n];
|
|
||||||
}
|
|
||||||
const k = {};
|
|
||||||
function N(n) {
|
|
||||||
return k[n] = (k[n] ?? -1) + 1, `GENERATE_ID::${n.toUpperCase()}_${k[n]}`;
|
|
||||||
}
|
|
||||||
export {
|
|
||||||
ie as description,
|
|
||||||
ae as id,
|
|
||||||
te as importCommand,
|
|
||||||
se as name,
|
|
||||||
oe as pluginHookImport
|
|
||||||
};
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
|||||||
const S = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", _ = "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", O = [_, S];
|
|
||||||
function v(e) {
|
|
||||||
var g;
|
|
||||||
const t = k(e);
|
|
||||||
if (t == null)
|
|
||||||
return;
|
|
||||||
const o = i(t.info);
|
|
||||||
if (!O.includes(o.schema) || !Array.isArray(t.item))
|
|
||||||
return;
|
|
||||||
const u = A(t.auth), s = {
|
|
||||||
workspaces: [],
|
|
||||||
environments: [],
|
|
||||||
httpRequests: [],
|
|
||||||
folders: []
|
|
||||||
}, n = {
|
|
||||||
model: "workspace",
|
|
||||||
id: h("workspace"),
|
|
||||||
name: o.name || "Postman Import",
|
|
||||||
description: o.description || "",
|
|
||||||
variables: ((g = t.variable) == null ? void 0 : g.map((r) => ({
|
|
||||||
name: r.key,
|
|
||||||
value: r.value
|
|
||||||
}))) ?? []
|
|
||||||
};
|
|
||||||
s.workspaces.push(n);
|
|
||||||
const T = (r, p = null) => {
|
|
||||||
if (typeof r.name == "string" && Array.isArray(r.item)) {
|
|
||||||
const a = {
|
|
||||||
model: "folder",
|
|
||||||
workspaceId: n.id,
|
|
||||||
id: h("folder"),
|
|
||||||
name: r.name,
|
|
||||||
folderId: p
|
|
||||||
};
|
|
||||||
s.folders.push(a);
|
|
||||||
for (const l of r.item)
|
|
||||||
T(l, a.id);
|
|
||||||
} else if (typeof r.name == "string" && "request" in r) {
|
|
||||||
const a = i(r.request), l = j(a.body), w = A(a.auth), d = w.authenticationType == null ? u : w, q = {
|
|
||||||
model: "http_request",
|
|
||||||
id: h("http_request"),
|
|
||||||
workspaceId: n.id,
|
|
||||||
folderId: p,
|
|
||||||
name: r.name,
|
|
||||||
method: a.method || "GET",
|
|
||||||
url: typeof a.url == "string" ? a.url : i(a.url).raw,
|
|
||||||
body: l.body,
|
|
||||||
bodyType: l.bodyType,
|
|
||||||
authentication: d.authentication,
|
|
||||||
authenticationType: d.authenticationType,
|
|
||||||
headers: [
|
|
||||||
...l.headers,
|
|
||||||
...d.headers,
|
|
||||||
...b(a.header).map((m) => ({
|
|
||||||
name: m.key,
|
|
||||||
value: m.value,
|
|
||||||
enabled: !m.disabled
|
|
||||||
}))
|
|
||||||
]
|
|
||||||
};
|
|
||||||
s.httpRequests.push(q);
|
|
||||||
} else
|
|
||||||
console.log("Unknown item", r, p);
|
|
||||||
};
|
|
||||||
for (const r of t.item)
|
|
||||||
T(r);
|
|
||||||
return { resources: f(s) };
|
|
||||||
}
|
|
||||||
function A(e) {
|
|
||||||
const t = i(e);
|
|
||||||
return "basic" in t ? {
|
|
||||||
headers: [],
|
|
||||||
authenticationType: "basic",
|
|
||||||
authentication: {
|
|
||||||
username: t.basic.username || "",
|
|
||||||
password: t.basic.password || ""
|
|
||||||
}
|
|
||||||
} : "bearer" in t ? {
|
|
||||||
headers: [],
|
|
||||||
authenticationType: "bearer",
|
|
||||||
authentication: {
|
|
||||||
token: t.bearer.token || ""
|
|
||||||
}
|
|
||||||
} : { headers: [], authenticationType: null, authentication: {} };
|
|
||||||
}
|
|
||||||
function j(e) {
|
|
||||||
var o, c, u, s;
|
|
||||||
const t = i(e);
|
|
||||||
return "graphql" in t ? {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
name: "Content-Type",
|
|
||||||
value: "application/json",
|
|
||||||
enabled: !0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
bodyType: "graphql",
|
|
||||||
body: {
|
|
||||||
text: JSON.stringify(
|
|
||||||
{ query: t.graphql.query, variables: k(t.graphql.variables) },
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} : "urlencoded" in t ? {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
name: "Content-Type",
|
|
||||||
value: "application/x-www-form-urlencoded",
|
|
||||||
enabled: !0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
bodyType: "application/x-www-form-urlencoded",
|
|
||||||
body: {
|
|
||||||
form: b(t.urlencoded).map((n) => ({
|
|
||||||
enabled: !n.disabled,
|
|
||||||
name: n.key ?? "",
|
|
||||||
value: n.value ?? ""
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
} : "formdata" in t ? {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
name: "Content-Type",
|
|
||||||
value: "multipart/form-data",
|
|
||||||
enabled: !0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
bodyType: "multipart/form-data",
|
|
||||||
body: {
|
|
||||||
form: b(t.formdata).map(
|
|
||||||
(n) => n.src != null ? {
|
|
||||||
enabled: !n.disabled,
|
|
||||||
contentType: n.contentType ?? null,
|
|
||||||
name: n.key ?? "",
|
|
||||||
file: n.src ?? ""
|
|
||||||
} : {
|
|
||||||
enabled: !n.disabled,
|
|
||||||
name: n.key ?? "",
|
|
||||||
value: n.value ?? ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} : "raw" in t ? {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
name: "Content-Type",
|
|
||||||
value: ((c = (o = t.options) == null ? void 0 : o.raw) == null ? void 0 : c.language) === "json" ? "application/json" : "",
|
|
||||||
enabled: !0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
bodyType: ((s = (u = t.options) == null ? void 0 : u.raw) == null ? void 0 : s.language) === "json" ? "application/json" : "other",
|
|
||||||
body: {
|
|
||||||
text: t.raw ?? ""
|
|
||||||
}
|
|
||||||
} : { headers: [], bodyType: null, body: {} };
|
|
||||||
}
|
|
||||||
function k(e) {
|
|
||||||
try {
|
|
||||||
return i(JSON.parse(e));
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
function i(e) {
|
|
||||||
return Object.prototype.toString.call(e) === "[object Object]" ? e : {};
|
|
||||||
}
|
|
||||||
function b(e) {
|
|
||||||
return Object.prototype.toString.call(e) === "[object Array]" ? e : [];
|
|
||||||
}
|
|
||||||
function f(e) {
|
|
||||||
return typeof e == "string" ? e.replace(/{{\s*(_\.)?([^}]+)\s*}}/g, "${[$2]}") : Array.isArray(e) && e != null ? e.map(f) : typeof e == "object" && e != null ? Object.fromEntries(
|
|
||||||
Object.entries(e).map(([t, o]) => [t, f(o)])
|
|
||||||
) : e;
|
|
||||||
}
|
|
||||||
const y = {};
|
|
||||||
function h(e) {
|
|
||||||
return y[e] = (y[e] ?? -1) + 1, `GENERATE_ID::${e.toUpperCase()}_${y[e]}`;
|
|
||||||
}
|
|
||||||
export {
|
|
||||||
v as pluginHookImport
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
function u(r) {
|
|
||||||
let e;
|
|
||||||
try {
|
|
||||||
e = JSON.parse(r);
|
|
||||||
} catch {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(!t(e) || !("yaakSchema" in e)))
|
|
||||||
return "requests" in e.resources && (e.resources.httpRequests = e.resources.requests, delete e.resources.requests), { resources: e.resources };
|
|
||||||
}
|
|
||||||
function t(r) {
|
|
||||||
return Object.prototype.toString.call(r) === "[object Object]";
|
|
||||||
}
|
|
||||||
export {
|
|
||||||
t as isJSObject,
|
|
||||||
u as pluginHookImport
|
|
||||||
};
|
|
||||||
237
src-tauri/src/deno.rs
Normal file
237
src-tauri/src/deno.rs
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
//! This example shows how to use swc to transpile TypeScript and JSX/TSX
|
||||||
|
//! modules.
|
||||||
|
//!
|
||||||
|
//! It will only transpile, not typecheck (like Deno's `--no-check` flag).
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::deno_ops::op_yaml_parse;
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use anyhow::bail;
|
||||||
|
use anyhow::Context;
|
||||||
|
use anyhow::Error;
|
||||||
|
use deno_ast::ParseParams;
|
||||||
|
use deno_ast::{EmitOptions, MediaType, SourceMapOption, TranspileOptions};
|
||||||
|
use deno_core::error::{AnyError, JsError};
|
||||||
|
use deno_core::resolve_path;
|
||||||
|
use deno_core::JsRuntime;
|
||||||
|
use deno_core::ModuleLoadResponse;
|
||||||
|
use deno_core::ModuleLoader;
|
||||||
|
use deno_core::ModuleSource;
|
||||||
|
use deno_core::ModuleSourceCode;
|
||||||
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_core::ModuleType;
|
||||||
|
use deno_core::RequestedModuleType;
|
||||||
|
use deno_core::ResolutionKind;
|
||||||
|
use deno_core::RuntimeOptions;
|
||||||
|
use deno_core::SourceMapGetter;
|
||||||
|
use deno_core::{resolve_import, v8};
|
||||||
|
use tokio::task::block_in_place;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct SourceMapStore(Rc<RefCell<HashMap<String, Vec<u8>>>>);
|
||||||
|
|
||||||
|
impl SourceMapGetter for SourceMapStore {
|
||||||
|
fn get_source_map(&self, specifier: &str) -> Option<Vec<u8>> {
|
||||||
|
self.0.borrow().get(specifier).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_source_line(&self, _file_name: &str, _line_number: usize) -> Option<String> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TypescriptModuleLoader {
|
||||||
|
source_maps: SourceMapStore,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleLoader for TypescriptModuleLoader {
|
||||||
|
fn resolve(
|
||||||
|
&self,
|
||||||
|
specifier: &str,
|
||||||
|
referrer: &str,
|
||||||
|
_kind: ResolutionKind,
|
||||||
|
) -> Result<ModuleSpecifier, Error> {
|
||||||
|
Ok(resolve_import(specifier, referrer)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load(
|
||||||
|
&self,
|
||||||
|
module_specifier: &ModuleSpecifier,
|
||||||
|
_maybe_referrer: Option<&ModuleSpecifier>,
|
||||||
|
_is_dyn_import: bool,
|
||||||
|
_requested_module_type: RequestedModuleType,
|
||||||
|
) -> ModuleLoadResponse {
|
||||||
|
let source_maps = self.source_maps.clone();
|
||||||
|
fn load(
|
||||||
|
source_maps: SourceMapStore,
|
||||||
|
module_specifier: &ModuleSpecifier,
|
||||||
|
) -> Result<ModuleSource, AnyError> {
|
||||||
|
let path = module_specifier
|
||||||
|
.to_file_path()
|
||||||
|
.map_err(|_| anyhow!("Only file:// URLs are supported."))?;
|
||||||
|
|
||||||
|
let media_type = MediaType::from_path(&path);
|
||||||
|
let (module_type, should_transpile) = match MediaType::from_path(&path) {
|
||||||
|
MediaType::JavaScript | MediaType::Mjs | MediaType::Cjs => {
|
||||||
|
(ModuleType::JavaScript, false)
|
||||||
|
}
|
||||||
|
MediaType::Jsx => (ModuleType::JavaScript, true),
|
||||||
|
MediaType::TypeScript
|
||||||
|
| MediaType::Mts
|
||||||
|
| MediaType::Cts
|
||||||
|
| MediaType::Dts
|
||||||
|
| MediaType::Dmts
|
||||||
|
| MediaType::Dcts
|
||||||
|
| MediaType::Tsx => (ModuleType::JavaScript, true),
|
||||||
|
MediaType::Json => (ModuleType::Json, false),
|
||||||
|
_ => bail!("Unknown extension {:?}", path.extension()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let code = std::fs::read_to_string(&path)?;
|
||||||
|
let code = if should_transpile {
|
||||||
|
let parsed = deno_ast::parse_module(ParseParams {
|
||||||
|
specifier: module_specifier.clone(),
|
||||||
|
text: Arc::from(code),
|
||||||
|
media_type,
|
||||||
|
capture_tokens: false,
|
||||||
|
scope_analysis: false,
|
||||||
|
maybe_syntax: None,
|
||||||
|
})?;
|
||||||
|
let res = parsed.transpile(
|
||||||
|
&TranspileOptions::default(),
|
||||||
|
&EmitOptions {
|
||||||
|
source_map: SourceMapOption::Separate,
|
||||||
|
inline_sources: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
let src = res.into_source();
|
||||||
|
let source_map = src.source_map.unwrap();
|
||||||
|
let source = src.source;
|
||||||
|
source_maps
|
||||||
|
.0
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(module_specifier.to_string(), source_map);
|
||||||
|
String::from_utf8(source).unwrap()
|
||||||
|
} else {
|
||||||
|
code
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ModuleSource::new(
|
||||||
|
module_type,
|
||||||
|
ModuleSourceCode::String(code.into()),
|
||||||
|
module_specifier,
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleLoadResponse::Sync(load(source_maps, module_specifier))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_plugin_deno_block(
|
||||||
|
plugin_index_file: &str,
|
||||||
|
fn_name: &str,
|
||||||
|
fn_args: Vec<serde_json::Value>,
|
||||||
|
) -> Result<serde_json::Value, Error> {
|
||||||
|
block_in_place(|| {
|
||||||
|
tauri::async_runtime::block_on(run_plugin_deno_2(plugin_index_file, fn_name, fn_args))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deno_core::extension!(
|
||||||
|
yaak_runtime,
|
||||||
|
ops = [ op_yaml_parse ],
|
||||||
|
esm_entry_point = "ext:yaak_runtime/yaml.js",
|
||||||
|
esm = [dir "src/plugin-runtime", "yaml.js"]
|
||||||
|
);
|
||||||
|
|
||||||
|
async fn run_plugin_deno_2(
|
||||||
|
plugin_index_file: &str,
|
||||||
|
fn_name: &str,
|
||||||
|
fn_args: Vec<serde_json::Value>,
|
||||||
|
) -> Result<serde_json::Value, Error> {
|
||||||
|
let source_map_store = SourceMapStore(Rc::new(RefCell::new(HashMap::new())));
|
||||||
|
|
||||||
|
let mut ext_console = deno_console::deno_console::init_ops_and_esm();
|
||||||
|
ext_console.esm_entry_point = Some("ext:deno_console/01_console.js");
|
||||||
|
|
||||||
|
let ext_yaak = yaak_runtime::init_ops_and_esm();
|
||||||
|
|
||||||
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
|
module_loader: Some(Rc::new(TypescriptModuleLoader {
|
||||||
|
source_maps: source_map_store.clone(),
|
||||||
|
})),
|
||||||
|
source_map_getter: Some(Rc::new(source_map_store)),
|
||||||
|
extensions: vec![ext_console, ext_yaak],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
let main_module = resolve_path(
|
||||||
|
plugin_index_file,
|
||||||
|
&std::env::current_dir().context("Unable to get CWD")?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Load the main module so we can do stuff with it
|
||||||
|
let mod_id = js_runtime.load_main_es_module(&main_module).await?;
|
||||||
|
let result = js_runtime.mod_evaluate(mod_id);
|
||||||
|
js_runtime.run_event_loop(Default::default()).await?;
|
||||||
|
result.await?;
|
||||||
|
|
||||||
|
let module_namespace = js_runtime.get_module_namespace(mod_id).unwrap();
|
||||||
|
let scope = &mut js_runtime.handle_scope();
|
||||||
|
let module_namespace = v8::Local::<v8::Object>::new(scope, module_namespace);
|
||||||
|
|
||||||
|
// Get the exported function we're calling
|
||||||
|
let func_key = v8::String::new(scope, fn_name).unwrap();
|
||||||
|
let func = module_namespace.get(scope, func_key.into()).unwrap();
|
||||||
|
let func = v8::Local::<v8::Function>::try_from(func).unwrap();
|
||||||
|
let tc_scope = &mut v8::TryCatch::new(scope);
|
||||||
|
|
||||||
|
// Create Yaak context object
|
||||||
|
let null = v8::null(tc_scope).into();
|
||||||
|
let name = v8::String::new(tc_scope, "foo").unwrap().into();
|
||||||
|
let value = v8::String::new(tc_scope, "bar").unwrap().into();
|
||||||
|
let yaak_ctx: v8::Local<v8::Value> =
|
||||||
|
v8::Object::with_prototype_and_properties(tc_scope, null, &[name], &[value]).into();
|
||||||
|
|
||||||
|
// Create the function arguments
|
||||||
|
let passed_args = &mut fn_args
|
||||||
|
.iter()
|
||||||
|
.map(|a| {
|
||||||
|
let v: v8::Local<v8::Value> = deno_core::serde_v8::to_v8(tc_scope, a).unwrap();
|
||||||
|
v
|
||||||
|
})
|
||||||
|
.collect::<Vec<v8::Local<v8::Value>>>();
|
||||||
|
|
||||||
|
let all_args = &mut vec![yaak_ctx];
|
||||||
|
all_args.append(passed_args);
|
||||||
|
|
||||||
|
// Call the function
|
||||||
|
let func_res = func.call(tc_scope, module_namespace.into(), all_args);
|
||||||
|
|
||||||
|
// Catch and return any thrown errors
|
||||||
|
if tc_scope.has_caught() {
|
||||||
|
let e = tc_scope.exception().unwrap();
|
||||||
|
let js_error = JsError::from_v8_exception(tc_scope, e);
|
||||||
|
return Err(Error::msg(js_error.stack.unwrap_or_default()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the result
|
||||||
|
match func_res {
|
||||||
|
None => Ok(serde_json::Value::Null),
|
||||||
|
Some(res) => {
|
||||||
|
if res.is_null() || res.is_undefined() {
|
||||||
|
Ok(serde_json::Value::Null)
|
||||||
|
} else {
|
||||||
|
let value: serde_json::Value = deno_core::serde_v8::from_v8(tc_scope, res).unwrap();
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src-tauri/src/deno_ops.rs
Normal file
14
src-tauri/src/deno_ops.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::op2;
|
||||||
|
|
||||||
|
#[op2]
|
||||||
|
#[serde] pub fn op_yaml_parse(#[string] text: String) -> Result<serde_json::Value, AnyError> {
|
||||||
|
let value = serde_yaml::from_str(&text)?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2]
|
||||||
|
#[string] pub fn op_yaml_stringify(#[serde] value: serde_json::Value) -> Result<String, AnyError> {
|
||||||
|
let value = serde_yaml::to_string(&value)?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
@@ -71,6 +71,8 @@ mod render;
|
|||||||
mod tauri_plugin_mac_window;
|
mod tauri_plugin_mac_window;
|
||||||
mod updates;
|
mod updates;
|
||||||
mod window_menu;
|
mod window_menu;
|
||||||
|
mod deno;
|
||||||
|
mod deno_ops;
|
||||||
|
|
||||||
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
|
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
|
||||||
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
||||||
@@ -118,7 +120,6 @@ async fn cmd_dismiss_notification(
|
|||||||
notification_id: &str,
|
notification_id: &str,
|
||||||
yaak_notifier: State<'_, Mutex<YaakNotifier>>,
|
yaak_notifier: State<'_, Mutex<YaakNotifier>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
info!("SEEN? {notification_id}");
|
|
||||||
yaak_notifier.lock().await.seen(&app, notification_id).await
|
yaak_notifier.lock().await.seen(&app, notification_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,7 +737,7 @@ async fn cmd_filter_response(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let body = read_to_string(response.body_path.unwrap()).unwrap();
|
let body = read_to_string(response.body_path.unwrap()).unwrap();
|
||||||
let filter_result = plugin::run_plugin_filter(&w.app_handle(), plugin_name, filter, &body)
|
let filter_result = plugin::run_plugin_filter(plugin_name, filter, &body)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to run filter");
|
.expect("Failed to run filter");
|
||||||
Ok(filter_result.filtered)
|
Ok(filter_result.filtered)
|
||||||
@@ -759,7 +760,7 @@ async fn cmd_import_data(
|
|||||||
read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
|
read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
|
||||||
let file_contents = file.as_str();
|
let file_contents = file.as_str();
|
||||||
for plugin_name in plugins {
|
for plugin_name in plugins {
|
||||||
let v = run_plugin_import(&w.app_handle(), plugin_name, file_contents)
|
let v = run_plugin_import(plugin_name, file_contents)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
if let Some(r) = v {
|
if let Some(r) = v {
|
||||||
@@ -808,13 +809,12 @@ async fn cmd_import_data(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Importing resources");
|
|
||||||
for mut v in r.resources.workspaces {
|
for mut v in r.resources.workspaces {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
|
||||||
let x = upsert_workspace(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_workspace(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
imported_resources.workspaces.push(x.clone());
|
imported_resources.workspaces.push(x.clone());
|
||||||
info!("Imported workspace: {}", x.name);
|
|
||||||
}
|
}
|
||||||
|
info!("Imported {} workspaces", imported_resources.workspaces.len());
|
||||||
|
|
||||||
for mut v in r.resources.environments {
|
for mut v in r.resources.environments {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeEnvironment, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeEnvironment, &mut id_map);
|
||||||
@@ -825,8 +825,8 @@ async fn cmd_import_data(
|
|||||||
);
|
);
|
||||||
let x = upsert_environment(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_environment(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
imported_resources.environments.push(x.clone());
|
imported_resources.environments.push(x.clone());
|
||||||
info!("Imported environment: {}", x.name);
|
|
||||||
}
|
}
|
||||||
|
info!("Imported {} environments", imported_resources.environments.len());
|
||||||
|
|
||||||
for mut v in r.resources.folders {
|
for mut v in r.resources.folders {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeFolder, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeFolder, &mut id_map);
|
||||||
@@ -838,8 +838,8 @@ async fn cmd_import_data(
|
|||||||
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
||||||
let x = upsert_folder(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_folder(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
imported_resources.folders.push(x.clone());
|
imported_resources.folders.push(x.clone());
|
||||||
info!("Imported folder: {}", x.name);
|
|
||||||
}
|
}
|
||||||
|
info!("Imported {} folders", imported_resources.folders.len());
|
||||||
|
|
||||||
for mut v in r.resources.http_requests {
|
for mut v in r.resources.http_requests {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeHttpRequest, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeHttpRequest, &mut id_map);
|
||||||
@@ -853,8 +853,8 @@ async fn cmd_import_data(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.http_requests.push(x.clone());
|
imported_resources.http_requests.push(x.clone());
|
||||||
info!("Imported request: {}", x.name);
|
|
||||||
}
|
}
|
||||||
|
info!("Imported {} http_requests", imported_resources.http_requests.len());
|
||||||
|
|
||||||
for mut v in r.resources.grpc_requests {
|
for mut v in r.resources.grpc_requests {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeGrpcRequest, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeGrpcRequest, &mut id_map);
|
||||||
@@ -868,8 +868,8 @@ async fn cmd_import_data(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.grpc_requests.push(x.clone());
|
imported_resources.grpc_requests.push(x.clone());
|
||||||
info!("Imported request: {}", x.name);
|
|
||||||
}
|
}
|
||||||
|
info!("Imported {} grpc_requests", imported_resources.grpc_requests.len());
|
||||||
|
|
||||||
Ok(imported_resources)
|
Ok(imported_resources)
|
||||||
}
|
}
|
||||||
@@ -893,16 +893,15 @@ async fn cmd_request_to_curl(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let rendered = render_request(&request, &workspace, environment.as_ref());
|
let rendered = render_request(&request, &workspace, environment.as_ref());
|
||||||
Ok(run_plugin_export_curl(&app, &rendered)?)
|
Ok(run_plugin_export_curl(&rendered)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_curl_to_request(
|
async fn cmd_curl_to_request(
|
||||||
app: AppHandle,
|
|
||||||
command: &str,
|
command: &str,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
) -> Result<HttpRequest, String> {
|
) -> Result<HttpRequest, String> {
|
||||||
let v = run_plugin_import(&app, "importer-curl", command)
|
let v = run_plugin_import("importer-curl", command)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string());
|
.map_err(|e| e.to_string());
|
||||||
match v {
|
match v {
|
||||||
@@ -1581,7 +1580,9 @@ pub fn run() {
|
|||||||
.level_for("tokio_util", log::LevelFilter::Info)
|
.level_for("tokio_util", log::LevelFilter::Info)
|
||||||
.level_for("tonic", log::LevelFilter::Info)
|
.level_for("tonic", log::LevelFilter::Info)
|
||||||
.level_for("tower", log::LevelFilter::Info)
|
.level_for("tower", log::LevelFilter::Info)
|
||||||
.level_for("tracing", log::LevelFilter::Info)
|
.level_for("tracing", log::LevelFilter::Warn)
|
||||||
|
.level_for("swc_ecma_codegen", log::LevelFilter::Off)
|
||||||
|
.level_for("swc_ecma_transforms_base", log::LevelFilter::Off)
|
||||||
.with_colors(ColoredLevelConfig::default())
|
.with_colors(ColoredLevelConfig::default())
|
||||||
.level(if is_dev() {
|
.level(if is_dev() {
|
||||||
log::LevelFilter::Trace
|
log::LevelFilter::Trace
|
||||||
|
|||||||
7
src-tauri/src/plugin-runtime/yaml.js
Normal file
7
src-tauri/src/plugin-runtime/yaml.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
((globalThis) => {
|
||||||
|
const core = Deno.core;
|
||||||
|
globalThis.YAML = {
|
||||||
|
parse: core.ops.op_yaml_parse,
|
||||||
|
stringify: core.ops.op_yaml_stringify,
|
||||||
|
};
|
||||||
|
})(globalThis);
|
||||||
@@ -1,17 +1,9 @@
|
|||||||
use std::rc::Rc;
|
use std::path;
|
||||||
|
|
||||||
use boa_engine::builtins::promise::PromiseState;
|
use log::error;
|
||||||
use boa_engine::{
|
|
||||||
js_string, module::SimpleModuleLoader, property::Attribute, Context, JsNativeError, JsValue,
|
|
||||||
Module, Source,
|
|
||||||
};
|
|
||||||
use boa_runtime::Console;
|
|
||||||
use log::{debug, error};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
|
||||||
use tauri::path::BaseDirectory;
|
|
||||||
use tauri::{AppHandle, Manager};
|
|
||||||
|
|
||||||
|
use crate::deno::run_plugin_deno_block;
|
||||||
use crate::models::{HttpRequest, WorkspaceExportResources};
|
use crate::models::{HttpRequest, WorkspaceExportResources};
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
@@ -25,140 +17,68 @@ pub struct ImportResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_plugin_filter(
|
pub async fn run_plugin_filter(
|
||||||
app_handle: &AppHandle,
|
|
||||||
plugin_name: &str,
|
plugin_name: &str,
|
||||||
response_body: &str,
|
response_body: &str,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Option<FilterResult> {
|
) -> Option<FilterResult> {
|
||||||
let result_json = run_plugin(
|
let plugin_dir = path::Path::new("/Users/gschier/Workspace/yaak/plugins");
|
||||||
app_handle,
|
let plugin_index_file = plugin_dir.join(plugin_name).join("build/index.mjs");
|
||||||
plugin_name,
|
|
||||||
"pluginHookResponseFilter",
|
|
||||||
&[js_string!(response_body).into(), js_string!(filter).into()],
|
|
||||||
);
|
|
||||||
|
|
||||||
if result_json.is_null() {
|
let result = run_plugin_deno_block(
|
||||||
|
plugin_index_file.to_str().unwrap(),
|
||||||
|
"pluginHookResponseFilter",
|
||||||
|
vec![
|
||||||
|
serde_json::to_value(response_body).unwrap(),
|
||||||
|
serde_json::to_value(filter).unwrap(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
.expect("Failed to run plugin");
|
||||||
|
|
||||||
|
if result.is_null() {
|
||||||
error!("Plugin {} failed to run", plugin_name);
|
error!("Plugin {} failed to run", plugin_name);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let resources: FilterResult =
|
let resources: FilterResult =
|
||||||
serde_json::from_value(result_json).expect("failed to parse filter plugin result json");
|
serde_json::from_value(result).expect("failed to parse filter plugin result json");
|
||||||
Some(resources)
|
Some(resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_plugin_export_curl(
|
pub fn run_plugin_export_curl(request: &HttpRequest) -> Result<String, String> {
|
||||||
app_handle: &AppHandle,
|
let plugin_dir = path::Path::new("/Users/gschier/Workspace/yaak/plugins");
|
||||||
request: &HttpRequest,
|
let plugin_index_file = plugin_dir.join("exporter-curl").join("build/index.mjs");
|
||||||
) -> Result<String, String> {
|
|
||||||
let mut context = Context::default();
|
|
||||||
let request_json = serde_json::to_value(request).map_err(|e| e.to_string())?;
|
|
||||||
let result_json = run_plugin(
|
|
||||||
app_handle,
|
|
||||||
"exporter-curl",
|
|
||||||
"pluginHookExport",
|
|
||||||
&[JsValue::from_json(&request_json, &mut context).map_err(|e| e.to_string())?],
|
|
||||||
);
|
|
||||||
|
|
||||||
let resources: String = serde_json::from_value(result_json).map_err(|e| e.to_string())?;
|
let request_json = serde_json::to_value(request).map_err(|e| e.to_string())?;
|
||||||
Ok(resources)
|
let result = run_plugin_deno_block(
|
||||||
|
plugin_index_file.to_str().unwrap(),
|
||||||
|
"pluginHookExport",
|
||||||
|
vec![request_json],
|
||||||
|
)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let export_str: String = serde_json::from_value(result).map_err(|e| e.to_string())?;
|
||||||
|
Ok(export_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_plugin_import(
|
pub async fn run_plugin_import(
|
||||||
app_handle: &AppHandle,
|
|
||||||
plugin_name: &str,
|
plugin_name: &str,
|
||||||
file_contents: &str,
|
file_contents: &str,
|
||||||
) -> Result<Option<ImportResult>, String> {
|
) -> Result<Option<ImportResult>, String> {
|
||||||
let result_json = run_plugin(
|
let plugin_dir = path::Path::new("/Users/gschier/Workspace/yaak/plugins");
|
||||||
app_handle,
|
let plugin_index_file = plugin_dir.join(plugin_name).join("build/index.mjs");
|
||||||
plugin_name,
|
|
||||||
"pluginHookImport",
|
|
||||||
&[js_string!(file_contents).into()],
|
|
||||||
);
|
|
||||||
|
|
||||||
if result_json.is_null() {
|
let result = run_plugin_deno_block(
|
||||||
|
plugin_index_file.to_str().unwrap(),
|
||||||
|
"pluginHookImport",
|
||||||
|
vec![serde_json::to_value(file_contents).map_err(|e| e.to_string())?],
|
||||||
|
)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
if result.is_null() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let resources: ImportResult = serde_json::from_value(result_json).map_err(|e| e.to_string())?;
|
let resources: ImportResult = serde_json::from_value(result).map_err(|e| e.to_string())?;
|
||||||
Ok(Some(resources))
|
Ok(Some(resources))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_plugin(
|
|
||||||
app_handle: &AppHandle,
|
|
||||||
plugin_name: &str,
|
|
||||||
entrypoint: &str,
|
|
||||||
js_args: &[JsValue],
|
|
||||||
) -> serde_json::Value {
|
|
||||||
let plugin_dir = app_handle
|
|
||||||
.path()
|
|
||||||
.resolve("plugins", BaseDirectory::Resource)
|
|
||||||
.expect("failed to resolve plugin directory resource")
|
|
||||||
.join(plugin_name);
|
|
||||||
let plugin_index_file = plugin_dir.join("index.mjs");
|
|
||||||
|
|
||||||
debug!(
|
|
||||||
"Running plugin dir={:?} file={:?}",
|
|
||||||
plugin_dir, plugin_index_file
|
|
||||||
);
|
|
||||||
|
|
||||||
let loader = Rc::new(SimpleModuleLoader::new(plugin_dir).unwrap());
|
|
||||||
let context = &mut Context::builder()
|
|
||||||
.module_loader(loader.clone())
|
|
||||||
.build()
|
|
||||||
.expect("failed to create context");
|
|
||||||
|
|
||||||
add_runtime(context);
|
|
||||||
|
|
||||||
let source = Source::from_filepath(&plugin_index_file).expect("Error opening file");
|
|
||||||
|
|
||||||
// Can also pass a `Some(realm)` if you need to execute the module in another realm.
|
|
||||||
let module = Module::parse(source, None, context).expect("failed to parse module");
|
|
||||||
|
|
||||||
// Insert parsed entrypoint into the module loader
|
|
||||||
loader.insert(plugin_index_file, module.clone());
|
|
||||||
|
|
||||||
let promise_result = module.load_link_evaluate(context);
|
|
||||||
|
|
||||||
// Very important to push forward the job queue after queueing promises.
|
|
||||||
context.run_jobs();
|
|
||||||
|
|
||||||
// Checking if the final promise didn't return an error.
|
|
||||||
match promise_result.state() {
|
|
||||||
PromiseState::Pending => {
|
|
||||||
panic!("Promise was pending");
|
|
||||||
}
|
|
||||||
PromiseState::Fulfilled(v) => {
|
|
||||||
assert_eq!(v, JsValue::undefined())
|
|
||||||
}
|
|
||||||
PromiseState::Rejected(err) => {
|
|
||||||
panic!("Failed to link: {}", err.display());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let namespace = module.namespace(context);
|
|
||||||
|
|
||||||
let result = namespace
|
|
||||||
.get(js_string!(entrypoint), context)
|
|
||||||
.expect("failed to get entrypoint")
|
|
||||||
.as_callable()
|
|
||||||
.cloned()
|
|
||||||
.ok_or_else(|| JsNativeError::typ().with_message("export wasn't a function!"))
|
|
||||||
.expect("Failed to get entrypoint")
|
|
||||||
.call(&JsValue::undefined(), js_args, context)
|
|
||||||
.expect("Failed to call entrypoint");
|
|
||||||
|
|
||||||
match result.is_undefined() {
|
|
||||||
true => json!(null), // to_json doesn't work with undefined (yet)
|
|
||||||
false => result
|
|
||||||
.to_json(context)
|
|
||||||
.expect("failed to convert result to json"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_runtime(context: &mut Context) {
|
|
||||||
let console = Console::init(context);
|
|
||||||
context
|
|
||||||
.register_global_property(js_string!(Console::NAME), console, Attribute::all())
|
|
||||||
.expect("the console builtin shouldn't exist");
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export function FormattedError({ children }: Props) {
|
|||||||
return (
|
return (
|
||||||
<pre
|
<pre
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-full select-auto cursor-text bg-background-highlight-secondary p-3 rounded',
|
'font-mono text-sm w-full select-auto cursor-text bg-background-highlight-secondary p-3 rounded',
|
||||||
'whitespace-pre-wrap border border-fg-danger border-dashed overflow-x-auto',
|
'whitespace-pre-wrap border border-fg-danger border-dashed overflow-x-auto',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -7,12 +7,22 @@ import { Alert } from './Alert';
|
|||||||
export function useAlert() {
|
export function useAlert() {
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
return useCallback(
|
return useCallback(
|
||||||
({ id, title, body }: { id: string; title: DialogProps['title']; body: AlertProps['body'] }) =>
|
({
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
size = 'sm',
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
title: DialogProps['title'];
|
||||||
|
body: AlertProps['body'];
|
||||||
|
size?: DialogProps['size'];
|
||||||
|
}) =>
|
||||||
dialog.show({
|
dialog.show({
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
hideX: true,
|
hideX: true,
|
||||||
size: 'sm',
|
size,
|
||||||
render: ({ hide }) => Alert({ onHide: hide, body }),
|
render: ({ hide }) => Alert({ onHide: hide, body }),
|
||||||
}),
|
}),
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useMutation } from '@tanstack/react-query';
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { open } from '@tauri-apps/plugin-dialog';
|
import { open } from '@tauri-apps/plugin-dialog';
|
||||||
import { Button } from '../components/core/Button';
|
import { Button } from '../components/core/Button';
|
||||||
|
import { FormattedError } from '../components/core/FormattedError';
|
||||||
import { VStack } from '../components/core/Stacks';
|
import { VStack } from '../components/core/Stacks';
|
||||||
import { useDialog } from '../components/DialogContext';
|
import { useDialog } from '../components/DialogContext';
|
||||||
import type { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
|
import type { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
|
||||||
@@ -77,7 +78,12 @@ export function useImportData() {
|
|||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
onError: (err: string) => {
|
onError: (err: string) => {
|
||||||
alert({ id: 'import-failed', title: 'Import Failed', body: err });
|
alert({
|
||||||
|
id: 'import-failed',
|
||||||
|
title: 'Import Failed',
|
||||||
|
size: 'md',
|
||||||
|
body: <FormattedError>{err}</FormattedError>,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
|||||||
10
src-web/plugin/runtime.d.ts
vendored
Normal file
10
src-web/plugin/runtime.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
declare global {
|
||||||
|
const YAML: {
|
||||||
|
parse: (yml: string) => unknown;
|
||||||
|
};
|
||||||
|
interface YaakContext {
|
||||||
|
foo: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
||||||
Reference in New Issue
Block a user