mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-18 06:49:50 +02:00
Migrate to Vite+ unified toolchain (#428)
This commit is contained in:
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@@ -14,17 +14,20 @@ jobs:
|
|||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: voidzero-dev/setup-vp@v1
|
||||||
|
with:
|
||||||
|
node-version: '24'
|
||||||
|
cache: true
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
shared-key: ci
|
shared-key: ci
|
||||||
cache-on-failure: true
|
cache-on-failure: true
|
||||||
|
|
||||||
- run: npm ci
|
- run: vp install
|
||||||
- run: npm run bootstrap
|
- run: npm run bootstrap
|
||||||
- run: npm run lint
|
- run: npm run lint
|
||||||
- name: Run JS Tests
|
- name: Run JS Tests
|
||||||
run: npm test
|
run: vp test
|
||||||
- name: Run Rust Tests
|
- name: Run Rust Tests
|
||||||
run: cargo test --all
|
run: cargo test --all
|
||||||
|
|||||||
11
.github/workflows/release-app.yml
vendored
11
.github/workflows/release-app.yml
vendored
@@ -50,8 +50,11 @@ jobs:
|
|||||||
- name: Checkout yaakapp/app
|
- name: Checkout yaakapp/app
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Vite+
|
||||||
uses: actions/setup-node@v4
|
uses: voidzero-dev/setup-vp@v1
|
||||||
|
with:
|
||||||
|
node-version: '24'
|
||||||
|
cache: true
|
||||||
|
|
||||||
- name: install Rust stable
|
- name: install Rust stable
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
@@ -87,13 +90,13 @@ jobs:
|
|||||||
echo $dir >> $env:GITHUB_PATH
|
echo $dir >> $env:GITHUB_PATH
|
||||||
& $exe --version
|
& $exe --version
|
||||||
|
|
||||||
- run: npm ci
|
- run: vp install
|
||||||
- run: npm run bootstrap
|
- run: npm run bootstrap
|
||||||
env:
|
env:
|
||||||
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
|
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
|
||||||
- run: npm run lint
|
- run: npm run lint
|
||||||
- name: Run JS Tests
|
- name: Run JS Tests
|
||||||
run: npm test
|
run: vp test
|
||||||
- name: Run Rust Tests
|
- name: Run Rust Tests
|
||||||
run: cargo test --all --exclude yaak-cli
|
run: cargo test --all --exclude yaak-cli
|
||||||
|
|
||||||
|
|||||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
24.14.0
|
||||||
1
.vite-hooks/pre-commit
Normal file
1
.vite-hooks/pre-commit
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vp lint
|
||||||
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"recommendations": ["biomejs.biome", "rust-lang.rust-analyzer", "bradlc.vscode-tailwindcss"]
|
"recommendations": ["rust-lang.rust-analyzer", "bradlc.vscode-tailwindcss", "VoidZero.vite-plus-extension-pack"]
|
||||||
}
|
}
|
||||||
|
|||||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"editor.defaultFormatter": "biomejs.biome",
|
"editor.defaultFormatter": "oxc.oxc-vscode",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"biome.enabled": true,
|
"editor.formatOnSaveMode": "file",
|
||||||
"biome.lint.format.enable": true
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.oxc": "explicit"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
biome.json
55
biome.json
@@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true,
|
|
||||||
"a11y": {
|
|
||||||
"useKeyWithClickEvents": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2,
|
|
||||||
"lineWidth": 100,
|
|
||||||
"bracketSpacing": true
|
|
||||||
},
|
|
||||||
"css": {
|
|
||||||
"parser": {
|
|
||||||
"tailwindDirectives": true
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"quoteStyle": "single",
|
|
||||||
"jsxQuoteStyle": "double",
|
|
||||||
"trailingCommas": "all",
|
|
||||||
"semicolons": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"includes": [
|
|
||||||
"**",
|
|
||||||
"!**/node_modules",
|
|
||||||
"!**/dist",
|
|
||||||
"!**/build",
|
|
||||||
"!target",
|
|
||||||
"!scripts",
|
|
||||||
"!crates",
|
|
||||||
"!crates-tauri",
|
|
||||||
"!src-web/tailwind.config.cjs",
|
|
||||||
"!src-web/postcss.config.cjs",
|
|
||||||
"!src-web/vite.config.ts",
|
|
||||||
"!src-web/routeTree.gen.ts",
|
|
||||||
"!packages/plugin-runtime-types/lib",
|
|
||||||
"!**/bindings",
|
|
||||||
"!flatpak",
|
|
||||||
"!npm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,7 @@ export function useLicense() {
|
|||||||
await queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY });
|
await queryClient.invalidateQueries({ queryKey: CHECK_QUERY_KEY });
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
unlisten.then((fn) => fn());
|
void unlisten.then((fn) => fn());
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
|||||||
|
|
||||||
const handleError = (err: unknown) => {
|
const handleError = (err: unknown) => {
|
||||||
showToast({
|
showToast({
|
||||||
id: `${err}`,
|
id: err instanceof Error ? err.message : String(err),
|
||||||
message: `${err}`,
|
message: err instanceof Error ? err.message : String(err),
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
});
|
});
|
||||||
@@ -186,16 +186,16 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.type === 'uncommitted_changes') {
|
if (result.type === 'uncommitted_changes') {
|
||||||
callbacks.promptUncommittedChanges().then(async (strategy) => {
|
void callbacks.promptUncommittedChanges().then(async (strategy) => {
|
||||||
if (strategy === 'cancel') return;
|
if (strategy === 'cancel') return;
|
||||||
|
|
||||||
await invoke('cmd_git_reset_changes', { dir });
|
await invoke('cmd_git_reset_changes', { dir });
|
||||||
return invoke<PullResult>('cmd_git_pull', { dir });
|
return invoke<PullResult>('cmd_git_pull', { dir });
|
||||||
}).then(async () => { onSuccess(); await callbacks.forceSync(); }, handleError);
|
}).then(async () => { await onSuccess(); await callbacks.forceSync(); }, handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.type === 'diverged') {
|
if (result.type === 'diverged') {
|
||||||
callbacks.promptDiverged(result).then((strategy) => {
|
void callbacks.promptDiverged(result).then((strategy) => {
|
||||||
if (strategy === 'cancel') return;
|
if (strategy === 'cancel') return;
|
||||||
|
|
||||||
if (strategy === 'force_reset') {
|
if (strategy === 'force_reset') {
|
||||||
@@ -211,7 +211,7 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
|
|||||||
remote: result.remote,
|
remote: result.remote,
|
||||||
branch: result.branch,
|
branch: result.branch,
|
||||||
});
|
});
|
||||||
}).then(async () => { onSuccess(); await callbacks.forceSync(); }, handleError);
|
}).then(async () => { await onSuccess(); await callbacks.forceSync(); }, handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ export function getAnyModel(
|
|||||||
): AnyModel | null {
|
): AnyModel | null {
|
||||||
let data = mustStore().get(modelStoreDataAtom);
|
let data = mustStore().get(modelStoreDataAtom);
|
||||||
for (const t of Object.keys(data)) {
|
for (const t of Object.keys(data)) {
|
||||||
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let v = (data as any)[t]?.[id];
|
let v = (data as any)[t]?.[id];
|
||||||
if (v?.model === t) return v;
|
if (v?.model === t) return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function watchWorkspaceFiles(
|
|||||||
channel,
|
channel,
|
||||||
});
|
});
|
||||||
|
|
||||||
unlistenPromise.then(({ unlistenEvent }) => {
|
void unlistenPromise.then(({ unlistenEvent }) => {
|
||||||
addWatchKey(unlistenEvent);
|
addWatchKey(unlistenEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ export function watchWorkspaceFiles(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function unlistenToWatcher(unlistenEvent: string) {
|
function unlistenToWatcher(unlistenEvent: string) {
|
||||||
emit(unlistenEvent).then(() => {
|
void emit(unlistenEvent).then(() => {
|
||||||
removeWatchKey(unlistenEvent);
|
removeWatchKey(unlistenEvent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const { execSync } = require('node:child_process');
|
const { execSync } = require('node:child_process');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
if (process.env.SKIP_WASM_BUILD === '1') {
|
if (process.env.SKIP_WASM_BUILD === '1') {
|
||||||
console.log('Skipping wasm-pack build (SKIP_WASM_BUILD=1)');
|
console.log('Skipping wasm-pack build (SKIP_WASM_BUILD=1)');
|
||||||
@@ -6,3 +8,20 @@ if (process.env.SKIP_WASM_BUILD === '1') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execSync('wasm-pack build --target bundler', { stdio: 'inherit' });
|
execSync('wasm-pack build --target bundler', { stdio: 'inherit' });
|
||||||
|
|
||||||
|
// Rewrite the generated entry to use Vite's ?init import style instead of
|
||||||
|
// the ES Module Integration style that wasm-pack generates, which Vite/rolldown
|
||||||
|
// does not support in production builds.
|
||||||
|
const entry = path.join(__dirname, 'pkg', 'yaak_templates.js');
|
||||||
|
fs.writeFileSync(
|
||||||
|
entry,
|
||||||
|
[
|
||||||
|
'import init from "./yaak_templates_bg.wasm?init";',
|
||||||
|
'export * from "./yaak_templates_bg.js";',
|
||||||
|
'import * as bg from "./yaak_templates_bg.js";',
|
||||||
|
'const instance = await init({ "./yaak_templates_bg.js": bg });',
|
||||||
|
'bg.__wbg_set_wasm(instance.exports);',
|
||||||
|
'instance.exports.__wbindgen_start();',
|
||||||
|
'',
|
||||||
|
].join('\n'),
|
||||||
|
);
|
||||||
|
|||||||
9
crates/yaak-templates/pkg/yaak_templates.js
generated
9
crates/yaak-templates/pkg/yaak_templates.js
generated
@@ -1,5 +1,6 @@
|
|||||||
import * as wasm from "./yaak_templates_bg.wasm";
|
import init from "./yaak_templates_bg.wasm?init";
|
||||||
export * from "./yaak_templates_bg.js";
|
export * from "./yaak_templates_bg.js";
|
||||||
import { __wbg_set_wasm } from "./yaak_templates_bg.js";
|
import * as bg from "./yaak_templates_bg.js";
|
||||||
__wbg_set_wasm(wasm);
|
const instance = await init({ "./yaak_templates_bg.js": bg });
|
||||||
wasm.__wbindgen_start();
|
bg.__wbg_set_wasm(instance.exports);
|
||||||
|
instance.exports.__wbindgen_start();
|
||||||
|
|||||||
2576
package-lock.json
generated
2576
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -63,7 +63,7 @@
|
|||||||
"src-web"
|
"src-web"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "husky",
|
"prepare": "vp config",
|
||||||
"init": "npm install && npm run bootstrap",
|
"init": "npm install && npm run bootstrap",
|
||||||
"start": "npm run app-dev",
|
"start": "npm run app-dev",
|
||||||
"app-build": "tauri build",
|
"app-build": "tauri build",
|
||||||
@@ -83,27 +83,27 @@
|
|||||||
"vendor:vendor-protoc": "node scripts/vendor-protoc.cjs",
|
"vendor:vendor-protoc": "node scripts/vendor-protoc.cjs",
|
||||||
"vendor:vendor-node": "node scripts/vendor-node.cjs",
|
"vendor:vendor-node": "node scripts/vendor-node.cjs",
|
||||||
"lint": "run-p lint:*",
|
"lint": "run-p lint:*",
|
||||||
"lint:biome": "biome lint",
|
"lint:vp": "vp lint",
|
||||||
"lint:extra": "npm run --workspaces --if-present lint",
|
"lint:workspaces": "npm run --workspaces --if-present lint",
|
||||||
"format": "biome format --write .",
|
|
||||||
"replace-version": "node scripts/replace-version.cjs",
|
"replace-version": "node scripts/replace-version.cjs",
|
||||||
"tauri": "tauri",
|
"tauri": "tauri",
|
||||||
"tauri-before-build": "npm run bootstrap",
|
"tauri-before-build": "npm run bootstrap",
|
||||||
"tauri-before-dev": "node scripts/run-workspaces-dev.mjs"
|
"tauri-before-dev": "node scripts/run-workspaces-dev.mjs"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"js-yaml": "^4.1.1"
|
"js-yaml": "^4.1.1",
|
||||||
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
||||||
|
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.3.13",
|
|
||||||
"@tauri-apps/cli": "^2.9.6",
|
"@tauri-apps/cli": "^2.9.6",
|
||||||
"@yaakapp/cli": "^0.5.1",
|
"@yaakapp/cli": "^0.5.1",
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"husky": "^9.1.7",
|
|
||||||
"nodejs-file-downloader": "^4.13.0",
|
"nodejs-file-downloader": "^4.13.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"vitest": "^3.2.4"
|
"vite-plus": "latest",
|
||||||
|
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-go": "^6.0.1",
|
"@codemirror/lang-go": "^6.0.1",
|
||||||
@@ -111,5 +111,6 @@
|
|||||||
"@codemirror/lang-php": "^6.0.2",
|
"@codemirror/lang-php": "^6.0.2",
|
||||||
"@codemirror/lang-python": "^6.2.1",
|
"@codemirror/lang-python": "^6.2.1",
|
||||||
"@codemirror/legacy-modes": "^6.5.2"
|
"@codemirror/legacy-modes": "^6.5.2"
|
||||||
}
|
},
|
||||||
|
"packageManager": "npm@11.11.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
export function debounce(fn: (...args: any[]) => void, delay = 500) {
|
export function debounce(fn: (...args: any[]) => void, delay = 500) {
|
||||||
let timer: ReturnType<typeof setTimeout>;
|
let timer: ReturnType<typeof setTimeout>;
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
const result = (...args: any[]) => {
|
const result = (...args: any[]) => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
timer = setTimeout(() => fn(...args), delay);
|
timer = setTimeout(() => fn(...args), delay);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type AddDynamicMethod<T> = {
|
|||||||
) => MaybePromise<Partial<T> | null | undefined>;
|
) => MaybePromise<Partial<T> | null | undefined>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: distributive conditional type pattern
|
// oxlint-disable-next-line no-explicit-any -- distributive conditional type pattern
|
||||||
type AddDynamic<T> = T extends any
|
type AddDynamic<T> = T extends any
|
||||||
? T extends { inputs?: FormInput[] }
|
? T extends { inputs?: FormInput[] }
|
||||||
? Omit<T, 'inputs'> & {
|
? Omit<T, 'inputs'> & {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type AddDynamicMethod<T> = {
|
|||||||
) => MaybePromise<Partial<T> | null | undefined>;
|
) => MaybePromise<Partial<T> | null | undefined>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: distributive conditional type pattern
|
// oxlint-disable-next-line no-explicit-any -- distributive conditional type pattern
|
||||||
type AddDynamic<T> = T extends any
|
type AddDynamic<T> = T extends any
|
||||||
? T extends { inputs?: FormInput[] }
|
? T extends { inputs?: FormInput[] }
|
||||||
? Omit<T, 'inputs'> & {
|
? Omit<T, 'inputs'> & {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ type AddDynamicMethod<T> = {
|
|||||||
) => MaybePromise<Partial<T> | null | undefined>;
|
) => MaybePromise<Partial<T> | null | undefined>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: distributive conditional type pattern
|
// oxlint-disable-next-line no-explicit-any -- distributive conditional type pattern
|
||||||
type AddDynamic<T> = T extends any
|
type AddDynamic<T> = T extends any
|
||||||
? T extends { inputs?: FormInput[] }
|
? T extends { inputs?: FormInput[] }
|
||||||
? Omit<T, 'inputs'> & {
|
? Omit<T, 'inputs'> & {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class PluginInstance {
|
|||||||
);
|
);
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
await ctx.toast.show({
|
await ctx.toast.show({
|
||||||
message: `Failed to initialize plugin ${this.#workerData.bootRequest.dir.split('/').pop()}: ${err}`,
|
message: `Failed to initialize plugin ${this.#workerData.bootRequest.dir.split('/').pop()}: ${err instanceof Error ? err.message : String(err)}`,
|
||||||
color: 'notice',
|
color: 'notice',
|
||||||
icon: 'alert_triangle',
|
icon: 'alert_triangle',
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
@@ -328,7 +328,8 @@ export class PluginInstance {
|
|||||||
payload.values = applyFormInputDefaults(args, payload.values);
|
payload.values = applyFormInputDefaults(args, payload.values);
|
||||||
const resolvedArgs = await applyDynamicFormInput(ctx, args, payload);
|
const resolvedArgs = await applyDynamicFormInput(ctx, args, payload);
|
||||||
const resolvedActions: HttpAuthenticationAction[] = [];
|
const resolvedActions: HttpAuthenticationAction[] = [];
|
||||||
for (const { onSelect, ...action } of actions ?? []) {
|
// oxlint-disable-next-line unbound-method
|
||||||
|
for (const { onSelect: _onSelect, ...action } of actions ?? []) {
|
||||||
resolvedActions.push(action);
|
resolvedActions.push(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +475,7 @@ export class PluginInstance {
|
|||||||
{
|
{
|
||||||
type: 'call_template_function_response',
|
type: 'call_template_function_response',
|
||||||
value: null,
|
value: null,
|
||||||
error: `${err}`.replace(/^Error:\s*/g, ''),
|
error: (err instanceof Error ? err.message : String(err)).replace(/^Error:\s*/g, ''),
|
||||||
},
|
},
|
||||||
replyId,
|
replyId,
|
||||||
);
|
);
|
||||||
@@ -483,7 +484,7 @@ export class PluginInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const error = `${err}`.replace(/^Error:\s*/g, '');
|
const error = (err instanceof Error ? err.message : String(err)).replace(/^Error:\s*/g, '');
|
||||||
console.log('Plugin call threw exception', payload.type, '→', error);
|
console.log('Plugin call threw exception', payload.type, '→', error);
|
||||||
this.#sendPayload(context, { type: 'error_response', error }, replyId);
|
this.#sendPayload(context, { type: 'error_response', error }, replyId);
|
||||||
return;
|
return;
|
||||||
@@ -909,7 +910,7 @@ export class PluginInstance {
|
|||||||
render: async (args: TemplateRenderRequest) => {
|
render: async (args: TemplateRenderRequest) => {
|
||||||
const payload = { type: 'template_render_request', ...args } as const;
|
const payload = { type: 'template_render_request', ...args } as const;
|
||||||
const result = await this.#sendForReply<TemplateRenderResponse>(context, payload);
|
const result = await this.#sendForReply<TemplateRenderResponse>(context, payload);
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: That's okay
|
// oxlint-disable-next-line no-explicit-any -- That's okay
|
||||||
return result.data as any;
|
return result.data as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -972,8 +973,8 @@ export class PluginInstance {
|
|||||||
|
|
||||||
function stripDynamicCallbacks(inputs: { dynamic?: unknown }[]): FormInput[] {
|
function stripDynamicCallbacks(inputs: { dynamic?: unknown }[]): FormInput[] {
|
||||||
return inputs.map((input) => {
|
return inputs.map((input) => {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: stripping dynamic from union type
|
// oxlint-disable-next-line no-explicit-any -- stripping dynamic from union type
|
||||||
const { dynamic, ...rest } = input as any;
|
const { dynamic: _dynamic, ...rest } = input as any;
|
||||||
if ('inputs' in rest && Array.isArray(rest.inputs)) {
|
if ('inputs' in rest && Array.isArray(rest.inputs)) {
|
||||||
rest.inputs = stripDynamicCallbacks(rest.inputs);
|
rest.inputs = stripDynamicCallbacks(rest.inputs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* oxlint-disable unbound-method */
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
|
|
||||||
export function interceptStdout(intercept: (text: string) => string) {
|
export function interceptStdout(intercept: (text: string) => string) {
|
||||||
@@ -24,5 +25,5 @@ export function interceptStdout(intercept: (text: string) => string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function interceptor(text: string, fn: (text: string) => string) {
|
function interceptor(text: string, fn: (text: string) => string) {
|
||||||
return fn(text).replace(/\n$/, '') + (fn(text) && /\n$/.test(text) ? '\n' : '');
|
return fn(text).replace(/\n$/, '') + (fn(text) && text.endsWith('\n') ? '\n' : '');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { applyFormInputDefaults } from '@yaakapp-internal/lib/templateFunction';
|
import { applyFormInputDefaults } from '@yaakapp-internal/lib/templateFunction';
|
||||||
import type { CallTemplateFunctionArgs } from '@yaakapp-internal/plugins';
|
import type { CallTemplateFunctionArgs } from '@yaakapp-internal/plugins';
|
||||||
import type { Context, DynamicTemplateFunctionArg } from '@yaakapp/api';
|
import type { Context, DynamicTemplateFunctionArg } from '@yaakapp/api';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { applyDynamicFormInput } from '../src/common';
|
import { applyDynamicFormInput } from '../src/common';
|
||||||
|
|
||||||
describe('applyFormInputDefaults', () => {
|
describe('applyFormInputDefaults', () => {
|
||||||
|
|||||||
@@ -10,11 +10,7 @@
|
|||||||
"moduleResolution": "node16",
|
"moduleResolution": "node16",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "build",
|
"outDir": "build"
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"*": ["node_modules/*", "src/types/*"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@faker-js/faker": "^10.1.0"
|
"@faker-js/faker": "^10.1.0"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vite-plus/test';
|
||||||
|
|
||||||
describe('template-function-faker', () => {
|
describe('template-function-faker', () => {
|
||||||
it('exports all expected template functions', async () => {
|
it('exports all expected template functions', async () => {
|
||||||
@@ -13,6 +13,7 @@ describe('template-function-faker', () => {
|
|||||||
it('renders date results as unquoted ISO strings', async () => {
|
it('renders date results as unquoted ISO strings', async () => {
|
||||||
const { plugin } = await import('../src/index');
|
const { plugin } = await import('../src/index');
|
||||||
const fn = plugin.templateFunctions?.find((fn) => fn.name === 'faker.date.future');
|
const fn = plugin.templateFunctions?.find((fn) => fn.name === 'faker.date.future');
|
||||||
|
// oxlint-disable-next-line unbound-method
|
||||||
const onRender = fn?.onRender;
|
const onRender = fn?.onRender;
|
||||||
|
|
||||||
expect(onRender).toBeTypeOf('function');
|
expect(onRender).toBeTypeOf('function');
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ function toHarRequest(request: Partial<HttpRequest>) {
|
|||||||
return har;
|
return har;
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeParseJSON<T>(v: unknown, fallback: T): T | unknown {
|
function maybeParseJSON<T>(v: unknown, fallback: T): unknown {
|
||||||
if (typeof v !== 'string') return fallback;
|
if (typeof v !== 'string') return fallback;
|
||||||
try {
|
try {
|
||||||
return JSON.parse(v);
|
return JSON.parse(v);
|
||||||
@@ -305,7 +305,7 @@ export const plugin: PluginDefinition = {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await ctx.toast.show({
|
await ctx.toast.show({
|
||||||
message: `Failed to generate snippet: ${err}`,
|
message: `Failed to generate snippet: ${err instanceof Error ? err.message : String(err)}`,
|
||||||
icon: 'alert_triangle',
|
icon: 'alert_triangle',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const plugin: PluginDefinition = {
|
|||||||
mcpServer = createMcpServer({ yaak: ctx }, serverPort);
|
mcpServer = createMcpServer({ yaak: ctx }, serverPort);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to start MCP server:', err);
|
console.error('Failed to start MCP server:', err);
|
||||||
ctx.toast.show({
|
void ctx.toast.show({
|
||||||
message: `Failed to start MCP Server: ${err instanceof Error ? err.message : String(err)}`,
|
message: `Failed to start MCP Server: ${err instanceof Error ? err.message : String(err)}`,
|
||||||
icon: 'alert_triangle',
|
icon: 'alert_triangle',
|
||||||
color: 'danger',
|
color: 'danger',
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export function createMcpServer(ctx: McpServerContext, port: number) {
|
|||||||
if (!mcpServer.isConnected()) {
|
if (!mcpServer.isConnected()) {
|
||||||
// Connect the mcp with the transport
|
// Connect the mcp with the transport
|
||||||
await mcpServer.connect(transport);
|
await mcpServer.connect(transport);
|
||||||
ctx.yaak.toast.show({
|
void ctx.yaak.toast.show({
|
||||||
message: `MCP Server connected`,
|
message: `MCP Server connected`,
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
color: 'info',
|
color: 'info',
|
||||||
@@ -48,7 +48,7 @@ export function createMcpServer(ctx: McpServerContext, port: number) {
|
|||||||
},
|
},
|
||||||
(info) => {
|
(info) => {
|
||||||
console.log('Started MCP server on ', info.address);
|
console.log('Started MCP server on ', info.address);
|
||||||
ctx.yaak.toast.show({
|
void ctx.yaak.toast.show({
|
||||||
message: `MCP Server running on http://127.0.0.1:${info.port}`,
|
message: `MCP Server running on http://127.0.0.1:${info.port}`,
|
||||||
icon: 'info',
|
icon: 'info',
|
||||||
color: 'secondary',
|
color: 'secondary',
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convertToCurl } from '../src';
|
import { convertToCurl } from '../src';
|
||||||
|
|
||||||
describe('exporter-curl', () => {
|
describe('exporter-curl', () => {
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convert } from '../src';
|
import { convert } from '../src';
|
||||||
|
|
||||||
describe('exporter-curl', () => {
|
describe('exporter-curl', () => {
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Context } from '@yaakapp/api';
|
import type { Context } from '@yaakapp/api';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { plugin } from '../src';
|
import { plugin } from '../src';
|
||||||
|
|
||||||
const ctx = {} as Context;
|
const ctx = {} as Context;
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Context } from '@yaakapp/api';
|
import type { Context } from '@yaakapp/api';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { plugin } from '../src';
|
import { plugin } from '../src';
|
||||||
|
|
||||||
const ctx = {} as Context;
|
const ctx = {} as Context;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"httpntlm": "^1.8.13"
|
"httpntlm": "^1.8.13"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Context } from '@yaakapp/api';
|
import type { Context } from '@yaakapp/api';
|
||||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
import { beforeEach, describe, expect, test, vi } from 'vite-plus/test';
|
||||||
|
|
||||||
const ntlmMock = vi.hoisted(() => ({
|
const ntlmMock = vi.hoisted(() => ({
|
||||||
createType1Message: vi.fn(),
|
createType1Message: vi.fn(),
|
||||||
@@ -17,6 +17,7 @@ describe('auth-ntlm', () => {
|
|||||||
ntlmMock.parseType2Message.mockReset();
|
ntlmMock.parseType2Message.mockReset();
|
||||||
ntlmMock.createType3Message.mockReset();
|
ntlmMock.createType3Message.mockReset();
|
||||||
ntlmMock.createType1Message.mockReturnValue('NTLM TYPE1');
|
ntlmMock.createType1Message.mockReturnValue('NTLM TYPE1');
|
||||||
|
// oxlint-disable-next-line no-explicit-any
|
||||||
ntlmMock.parseType2Message.mockReturnValue({} as any);
|
ntlmMock.parseType2Message.mockReturnValue({} as any);
|
||||||
ntlmMock.createType3Message.mockReturnValue('NTLM TYPE3');
|
ntlmMock.createType3Message.mockReturnValue('NTLM TYPE3');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsonwebtoken": "^9.0.2"
|
"jsonwebtoken": "^9.0.2"
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export async function fetchAccessToken(
|
|||||||
throw new Error(`Failed to fetch access token with status=${resp.status} and body=${body}`);
|
throw new Error(`Failed to fetch access token with status=${resp.status} and body=${body}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let response: any;
|
let response: any;
|
||||||
try {
|
try {
|
||||||
response = JSON.parse(body);
|
response = JSON.parse(body);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export async function getOrRefreshAccessToken(
|
|||||||
throw new Error(`Failed to refresh access token with status=${resp.status} and body=${body}`);
|
throw new Error(`Failed to refresh access token with status=${resp.status} and body=${body}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let response: any;
|
let response: any;
|
||||||
try {
|
try {
|
||||||
response = JSON.parse(body);
|
response = JSON.parse(body);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ async function getCodeViaEmbeddedBrowser(
|
|||||||
const authorizationUrlStr = authorizationUrl.toString();
|
const authorizationUrlStr = authorizationUrl.toString();
|
||||||
console.log('[oauth2] Authorizing via embedded browser', authorizationUrlStr);
|
console.log('[oauth2] Authorizing via embedded browser', authorizationUrlStr);
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: Required for this pattern
|
// oxlint-disable-next-line no-async-promise-executor -- Required for this pattern
|
||||||
return new Promise<string>(async (resolve, reject) => {
|
return new Promise<string>(async (resolve, reject) => {
|
||||||
let foundCode = false;
|
let foundCode = false;
|
||||||
const { close } = await ctx.window.openUrl({
|
const { close } = await ctx.window.openUrl({
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ function buildClientAssertionJwt(params: {
|
|||||||
signingKey = secret;
|
signingKey = secret;
|
||||||
} else if (trimmed.startsWith('{')) {
|
} else if (trimmed.startsWith('{')) {
|
||||||
// Looks like JSON - treat as JWK. There is surely a better way to detect JWK vs a raw secret, but this should work in most cases.
|
// Looks like JSON - treat as JWK. There is surely a better way to detect JWK vs a raw secret, but this should work in most cases.
|
||||||
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let jwk: any;
|
let jwk: any;
|
||||||
try {
|
try {
|
||||||
jwk = JSON.parse(trimmed);
|
jwk = JSON.parse(trimmed);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ async function getTokenViaEmbeddedBrowser(
|
|||||||
const authorizationUrlStr = authorizationUrl.toString();
|
const authorizationUrlStr = authorizationUrl.toString();
|
||||||
console.log('[oauth2] Authorizing via embedded browser (implicit)', authorizationUrlStr);
|
console.log('[oauth2] Authorizing via embedded browser (implicit)', authorizationUrlStr);
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: Required for this pattern
|
// oxlint-disable-next-line no-async-promise-executor -- Required for this pattern
|
||||||
return new Promise<AccessToken>(async (resolve, reject) => {
|
return new Promise<AccessToken>(async (resolve, reject) => {
|
||||||
let foundAccessToken = false;
|
let foundAccessToken = false;
|
||||||
const { close } = await ctx.window.openUrl({
|
const { close } = await ctx.window.openUrl({
|
||||||
|
|||||||
@@ -590,11 +590,11 @@ export const plugin: PluginDefinition = {
|
|||||||
credentialsInBody,
|
credentialsInBody,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Invalid grant type ${grantType}`);
|
throw new Error(`Invalid grant type ${String(grantType)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerName = stringArg(values, 'headerName') || 'Authorization';
|
const headerName = stringArg(values, 'headerName') || 'Authorization';
|
||||||
const headerValue = `${headerPrefix} ${token.response[tokenName]}`.trim();
|
const headerValue = `${headerPrefix} ${token.response[tokenName] ?? ''}`.trim();
|
||||||
return { setHeaders: [{ name: headerName, value: headerValue }] };
|
return { setHeaders: [{ name: headerName, value: headerValue }] };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { extractCode } from '../src/util';
|
import { extractCode } from '../src/util';
|
||||||
|
|
||||||
describe('extractCode', () => {
|
describe('extractCode', () => {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const plugin: PluginDefinition = {
|
|||||||
const filtered = JSONPath({ path: args.filter, json: parsed });
|
const filtered = JSONPath({ path: args.filter, json: parsed });
|
||||||
return { content: JSON.stringify(filtered, null, 2) };
|
return { content: JSON.stringify(filtered, null, 2) };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { content: '', error: `Invalid filter: ${err}` };
|
return { content: '', error: `Invalid filter: ${err instanceof Error ? err.message : String(err)}` };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* oxlint-disable no-base-to-string */
|
||||||
import { DOMParser } from '@xmldom/xmldom';
|
import { DOMParser } from '@xmldom/xmldom';
|
||||||
import type { PluginDefinition } from '@yaakapp/api';
|
import type { PluginDefinition } from '@yaakapp/api';
|
||||||
import xpath from 'xpath';
|
import xpath from 'xpath';
|
||||||
@@ -7,7 +8,7 @@ export const plugin: PluginDefinition = {
|
|||||||
name: 'XPath',
|
name: 'XPath',
|
||||||
description: 'Filter XPath',
|
description: 'Filter XPath',
|
||||||
onFilter(_ctx, args) {
|
onFilter(_ctx, args) {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
const doc: any = new DOMParser().parseFromString(args.payload, 'text/xml');
|
const doc: any = new DOMParser().parseFromString(args.payload, 'text/xml');
|
||||||
try {
|
try {
|
||||||
const result = xpath.select(args.filter, doc, false);
|
const result = xpath.select(args.filter, doc, false);
|
||||||
@@ -17,7 +18,7 @@ export const plugin: PluginDefinition = {
|
|||||||
// Not sure what cases this happens in (?)
|
// Not sure what cases this happens in (?)
|
||||||
return { content: String(result) };
|
return { content: String(result) };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { content: '', error: `Invalid filter: ${err}` };
|
return { content: '', error: `Invalid filter: ${err instanceof Error ? err.message : String(err)}` };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"shlex": "^3.0.0"
|
"shlex": "^3.0.0"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const plugin: PluginDefinition = {
|
|||||||
name: 'cURL',
|
name: 'cURL',
|
||||||
description: 'Import cURL commands',
|
description: 'Import cURL commands',
|
||||||
onImport(_ctx: Context, args: { text: string }) {
|
onImport(_ctx: Context, args: { text: string }) {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
return convertCurl(args.text) as any;
|
return convertCurl(args.text) as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { HttpRequest, Workspace } from '@yaakapp/api';
|
import type { HttpRequest, Workspace } from '@yaakapp/api';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convertCurl } from '../src';
|
import { convertCurl } from '../src';
|
||||||
|
|
||||||
describe('importer-curl', () => {
|
describe('importer-curl', () => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yaml": "^2.4.2"
|
"yaml": "^2.4.2"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export function deleteUndefinedAttrs<T>(obj: T): T {
|
|||||||
/** Recursively render all nested object properties */
|
/** Recursively render all nested object properties */
|
||||||
export function convertTemplateSyntax<T>(obj: T): T {
|
export function convertTemplateSyntax<T>(obj: T): T {
|
||||||
if (typeof obj === 'string') {
|
if (typeof obj === 'string') {
|
||||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: Yaak template syntax
|
// oxlint-disable-next-line no-template-curly-in-string -- Yaak template syntax
|
||||||
return obj.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}') as T;
|
return obj.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}') as T;
|
||||||
}
|
}
|
||||||
if (Array.isArray(obj) && obj != null) {
|
if (Array.isArray(obj) && obj != null) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// biome-ignore-all lint/suspicious/noExplicitAny: too flexible for strict types
|
/* oxlint-disable no-explicit-any */
|
||||||
import type { PartialImportResources } from '@yaakapp/api';
|
import type { PartialImportResources } from '@yaakapp/api';
|
||||||
import { convertId, convertTemplateSyntax, isJSObject } from './common';
|
import { convertId, convertTemplateSyntax, isJSObject } from './common';
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ function importEnvironment(
|
|||||||
variables: Object.entries(e.data).map(([name, value]) => ({
|
variables: Object.entries(e.data).map(([name, value]) => ({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
name,
|
name,
|
||||||
value: `${value}`,
|
value: String(value),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// biome-ignore-all lint/suspicious/noExplicitAny: too flexible for strict types
|
/* oxlint-disable no-explicit-any */
|
||||||
import type { PartialImportResources } from '@yaakapp/api';
|
import type { PartialImportResources } from '@yaakapp/api';
|
||||||
import { convertId, convertTemplateSyntax, isJSObject } from './common';
|
import { convertId, convertTemplateSyntax, isJSObject } from './common';
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ function importFolder(
|
|||||||
variables: Object.entries(f.environment ?? {}).map(([name, value]) => ({
|
variables: Object.entries(f.environment ?? {}).map(([name, value]) => ({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
name,
|
name,
|
||||||
value: `${value}`,
|
value: String(value),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ function importEnvironment(
|
|||||||
variables: Object.entries(e.data ?? {}).map(([name, value]) => ({
|
variables: Object.entries(e.data ?? {}).map(([name, value]) => ({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
name,
|
name,
|
||||||
value: `${value}`,
|
value: String(value),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import YAML from 'yaml';
|
import YAML from 'yaml';
|
||||||
import { convertInsomnia } from '../src';
|
import { convertInsomnia } from '../src';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"openapi-to-postmanv2": "^5.8.0",
|
"openapi-to-postmanv2": "^5.8.0",
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ export const plugin: PluginDefinition = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function convertOpenApi(contents: string): Promise<ImportPluginResponse | undefined> {
|
export async function convertOpenApi(contents: string): Promise<ImportPluginResponse | undefined> {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let postmanCollection: any;
|
let postmanCollection: any;
|
||||||
try {
|
try {
|
||||||
postmanCollection = await new Promise((resolve, reject) => {
|
postmanCollection = await new Promise((resolve, reject) => {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
convert({ type: 'string', data: contents }, {}, (err, result: any) => {
|
convert({ type: 'string', data: contents }, {}, (err, result: any) => {
|
||||||
if (err != null) reject(err);
|
if (err != null) reject(err);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convertOpenApi } from '../src';
|
import { convertOpenApi } from '../src';
|
||||||
|
|
||||||
describe('importer-openapi', () => {
|
describe('importer-openapi', () => {
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* oxlint-disable no-base-to-string */
|
||||||
import type {
|
import type {
|
||||||
Context,
|
Context,
|
||||||
Environment,
|
Environment,
|
||||||
@@ -84,7 +85,7 @@ function parseJSONToRecord<T>(jsonStr: string): Record<string, T> | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toRecord<T>(value: Record<string, T> | unknown): Record<string, T> {
|
function toRecord<T>(value: unknown): Record<string, T> {
|
||||||
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
return value as Record<string, T>;
|
return value as Record<string, T>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convertPostmanEnvironment } from '../src';
|
import { convertPostmanEnvironment } from '../src';
|
||||||
|
|
||||||
describe('importer-postman-environment', () => {
|
describe('importer-postman-environment', () => {
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* oxlint-disable no-base-to-string */
|
||||||
import type {
|
import type {
|
||||||
Context,
|
Context,
|
||||||
Environment,
|
Environment,
|
||||||
@@ -158,7 +159,7 @@ export function convertPostman(contents: string): ImportPluginResponse | undefin
|
|||||||
return { resources };
|
return { resources };
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertUrl(rawUrl: string | unknown): Pick<HttpRequest, 'url' | 'urlParameters'> {
|
function convertUrl(rawUrl: unknown): Pick<HttpRequest, 'url' | 'urlParameters'> {
|
||||||
if (typeof rawUrl === 'string') {
|
if (typeof rawUrl === 'string') {
|
||||||
return { url: rawUrl, urlParameters: [] };
|
return { url: rawUrl, urlParameters: [] };
|
||||||
}
|
}
|
||||||
@@ -172,7 +173,7 @@ function convertUrl(rawUrl: string | unknown): Pick<HttpRequest, 'url' | 'urlPar
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ('host' in url) {
|
if ('host' in url) {
|
||||||
v += `${Array.isArray(url.host) ? url.host.join('.') : url.host}`;
|
v += `${Array.isArray(url.host) ? url.host.join('.') : String(url.host)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('port' in url && typeof url.port === 'string') {
|
if ('port' in url && typeof url.port === 'string') {
|
||||||
@@ -489,7 +490,7 @@ function parseJSONToRecord<T>(jsonStr: string): Record<string, T> | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toRecord<T>(value: Record<string, T> | unknown): Record<string, T> {
|
function toRecord<T>(value: unknown): Record<string, T> {
|
||||||
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
return value as Record<string, T>;
|
return value as Record<string, T>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { convertPostman } from '../src';
|
import { convertPostman } from '../src';
|
||||||
|
|
||||||
describe('importer-postman', () => {
|
describe('importer-postman', () => {
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const plugin: PluginDefinition = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function migrateImport(contents: string) {
|
export function migrateImport(contents: string) {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
let parsed: any;
|
let parsed: any;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(contents);
|
parsed = JSON.parse(contents);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vite-plus/test';
|
||||||
import { migrateImport } from '../src';
|
import { migrateImport } from '../src';
|
||||||
|
|
||||||
describe('importer-yaak', () => {
|
describe('importer-yaak', () => {
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ async function op(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { client: _clients[hash], clientHash: hash };
|
// oxlint-disable-next-line no-non-null-assertion
|
||||||
|
return { client: _clients[hash]!, clientHash: hash };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getValue(
|
async function getValue(
|
||||||
@@ -123,7 +124,7 @@ export const plugin: PluginDefinition = {
|
|||||||
{
|
{
|
||||||
name: 'token',
|
name: 'token',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: Yaak template syntax
|
// oxlint-disable-next-line no-template-curly-in-string -- Yaak template syntax
|
||||||
defaultValue: '${[1PASSWORD_TOKEN]}',
|
defaultValue: '${[1PASSWORD_TOKEN]}',
|
||||||
dynamic(_ctx, args) {
|
dynamic(_ctx, args) {
|
||||||
switch (args.values.authMethod) {
|
switch (args.values.authMethod) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const plugin: PluginDefinition = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'namespace',
|
name: 'namespace',
|
||||||
label: 'Namespace',
|
label: 'Namespace',
|
||||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: Yaak template syntax
|
// oxlint-disable-next-line no-template-curly-in-string -- Yaak template syntax
|
||||||
defaultValue: '${[ctx.workspace()]}',
|
defaultValue: '${[ctx.workspace()]}',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Context } from '@yaakapp/api';
|
import type { Context } from '@yaakapp/api';
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vite-plus/test';
|
||||||
import { plugin } from '../src';
|
import { plugin } from '../src';
|
||||||
|
|
||||||
describe('regex.match', () => {
|
describe('regex.match', () => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev",
|
"dev": "yaakcli dev",
|
||||||
"test": "vitest --run tests"
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@date-fns/tz": "^1.4.1",
|
"@date-fns/tz": "^1.4.1",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { tz } from '@date-fns/tz';
|
import { tz } from '@date-fns/tz';
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vite-plus/test';
|
||||||
import { calculateDatetime, formatDatetime } from '../src';
|
import { calculateDatetime, formatDatetime } from '../src';
|
||||||
|
|
||||||
describe('formatDatetime', () => {
|
describe('formatDatetime', () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* oxlint-disable no-base-to-string */
|
||||||
import { DOMParser } from '@xmldom/xmldom';
|
import { DOMParser } from '@xmldom/xmldom';
|
||||||
import type { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
import type { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
||||||
import xpath from 'xpath';
|
import xpath from 'xpath';
|
||||||
@@ -68,7 +69,7 @@ export function filterXPath(
|
|||||||
result: XPathResult,
|
result: XPathResult,
|
||||||
join: string | null,
|
join: string | null,
|
||||||
): string {
|
): string {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
const doc: any = new DOMParser().parseFromString(body, 'text/xml');
|
const doc: any = new DOMParser().parseFromString(body, 'text/xml');
|
||||||
const items = xpath.select(path, doc, false);
|
const items = xpath.select(path, doc, false);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ execSync('cargo install wasm-pack --locked', { stdio: 'inherit' });
|
|||||||
function tryExecSync(cmd) {
|
function tryExecSync(cmd) {
|
||||||
try {
|
try {
|
||||||
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
||||||
} catch (_) {
|
} catch {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ for (const ws of workspacesWithDev) {
|
|||||||
|
|
||||||
// Cleanup function to kill all children
|
// Cleanup function to kill all children
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
for (const { ws, child } of children) {
|
for (const { child } of children) {
|
||||||
if (child.exitCode === null) {
|
if (child.exitCode === null) {
|
||||||
// Process still running
|
// Process still running
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ rmSync(tmpDir, { recursive: true, force: true });
|
|||||||
function tryExecSync(cmd) {
|
function tryExecSync(cmd) {
|
||||||
try {
|
try {
|
||||||
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
||||||
} catch (_) {
|
} catch {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ mkdirSync(dstDir, { recursive: true });
|
|||||||
function tryExecSync(cmd) {
|
function tryExecSync(cmd) {
|
||||||
try {
|
try {
|
||||||
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
return execSync(cmd, { stdio: 'pipe' }).toString('utf-8');
|
||||||
} catch (_) {
|
} catch {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export const syncWorkspace = createFastMutation<
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<TableRow key={i}>
|
<TableRow key={i}>
|
||||||
<TableCell className="text-text-subtle">{model}</TableCell>
|
<TableCell className="text-text-subtle">{model}</TableCell>
|
||||||
<TruncatedWideTableCell>{name}</TruncatedWideTableCell>
|
<TruncatedWideTableCell>{name}</TruncatedWideTableCell>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const openWorkspaceFromSyncDir = createFastMutation<void, void, string>({
|
|||||||
|
|
||||||
await applySync(workspace.id, dir, ops);
|
await applySync(workspace.id, dir, ops);
|
||||||
|
|
||||||
router.navigate({
|
await router.navigate({
|
||||||
to: '/workspaces/$workspaceId',
|
to: '/workspaces/$workspaceId',
|
||||||
params: { workspaceId: workspace.id },
|
params: { workspaceId: workspace.id },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { DnsOverride, Workspace } from '@yaakapp-internal/models';
|
import type { DnsOverride, Workspace } from '@yaakapp-internal/models';
|
||||||
import { patchModel } from '@yaakapp-internal/models';
|
import { patchModel } from '@yaakapp-internal/models';
|
||||||
import { useCallback, useId, useMemo } from 'react';
|
import { useCallback, useId, useMemo } from 'react';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { Button } from './core/Button';
|
import { Button } from './core/Button';
|
||||||
import { Checkbox } from './core/Checkbox';
|
import { Checkbox } from './core/Checkbox';
|
||||||
import { IconButton } from './core/IconButton';
|
import { IconButton } from './core/IconButton';
|
||||||
@@ -29,7 +30,7 @@ export function DnsOverridesEditor({ workspace }: Props) {
|
|||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
(overrides: DnsOverride[]) => {
|
(overrides: DnsOverride[]) => {
|
||||||
patchModel(workspace, { settingDnsOverrides: overrides });
|
fireAndForget(patchModel(workspace, { settingDnsOverrides: overrides }));
|
||||||
},
|
},
|
||||||
[workspace],
|
[workspace],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -512,16 +512,14 @@ function HttpRequestArg({
|
|||||||
help={arg.description}
|
help={arg.description}
|
||||||
value={value}
|
value={value}
|
||||||
disabled={arg.disabled}
|
disabled={arg.disabled}
|
||||||
options={[
|
options={httpRequests.map((r) => {
|
||||||
...httpRequests.map((r) => {
|
|
||||||
return {
|
return {
|
||||||
label:
|
label:
|
||||||
buildRequestBreadcrumbs(r, folders).join(' / ') +
|
buildRequestBreadcrumbs(r, folders).join(' / ') +
|
||||||
(r.id === activeHttpRequest?.id ? ' (current)' : ''),
|
(r.id === activeHttpRequest?.id ? ' (current)' : ''),
|
||||||
value: r.id,
|
value: r.id,
|
||||||
};
|
};
|
||||||
}),
|
})}
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
useEnvironmentsBreakdown,
|
useEnvironmentsBreakdown,
|
||||||
} from '../hooks/useEnvironmentsBreakdown';
|
} from '../hooks/useEnvironmentsBreakdown';
|
||||||
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { jotaiStore } from '../lib/jotai';
|
import { jotaiStore } from '../lib/jotai';
|
||||||
import { isBaseEnvironment, isSubEnvironment } from '../lib/model_util';
|
import { isBaseEnvironment, isSubEnvironment } from '../lib/model_util';
|
||||||
import { resolvedModelName } from '../lib/resolvedModelName';
|
import { resolvedModelName } from '../lib/resolvedModelName';
|
||||||
@@ -112,7 +113,7 @@ function EnvironmentEditDialogSidebar({
|
|||||||
const treeRef = useRef<TreeHandle>(null);
|
const treeRef = useRef<TreeHandle>(null);
|
||||||
const { baseEnvironment, baseEnvironments } = useEnvironmentsBreakdown();
|
const { baseEnvironment, baseEnvironments } = useEnvironmentsBreakdown();
|
||||||
|
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (selectedEnvironmentId == null) return;
|
if (selectedEnvironmentId == null) return;
|
||||||
treeRef.current?.selectItem(selectedEnvironmentId);
|
treeRef.current?.selectItem(selectedEnvironmentId);
|
||||||
@@ -199,7 +200,7 @@ function EnvironmentEditDialogSidebar({
|
|||||||
// Not sure why this is needed, but without it the
|
// Not sure why this is needed, but without it the
|
||||||
// edit input blurs immediately after opening.
|
// edit input blurs immediately after opening.
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
actions['sidebar.selected.rename'].cb(items);
|
fireAndForget(actions['sidebar.selected.rename'].cb(items));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function ExportDataDialogContent({
|
|||||||
|
|
||||||
const handleToggleAll = () => {
|
const handleToggleAll = () => {
|
||||||
setSelectedWorkspaces(
|
setSelectedWorkspaces(
|
||||||
// biome-ignore lint/performance/noAccumulatingSpread: none
|
// oxlint-disable-next-line no-accumulating-spread
|
||||||
allSelected ? {} : workspaces.reduce((acc, w) => ({ ...acc, [w.id]: true }), {}),
|
allSelected ? {} : workspaces.reduce((acc, w) => ({ ...acc, [w.id]: true }), {}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { allRequestsAtom } from '../hooks/useAllRequests';
|
|||||||
import { useFolderActions } from '../hooks/useFolderActions';
|
import { useFolderActions } from '../hooks/useFolderActions';
|
||||||
import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
|
import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
|
||||||
import { sendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
|
import { sendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { showDialog } from '../lib/dialog';
|
import { showDialog } from '../lib/dialog';
|
||||||
import { resolvedModelName } from '../lib/resolvedModelName';
|
import { resolvedModelName } from '../lib/resolvedModelName';
|
||||||
import { router } from '../lib/router';
|
import { router } from '../lib/router';
|
||||||
@@ -45,7 +46,7 @@ export function FolderLayout({ folder, style }: Props) {
|
|||||||
}, [folder.id, folders, requests]);
|
}, [folder.id, folders, requests]);
|
||||||
|
|
||||||
const handleSendAll = useCallback(() => {
|
const handleSendAll = useCallback(() => {
|
||||||
sendAllAction?.call(folder);
|
if (sendAllAction) fireAndForget(sendAllAction.call(folder));
|
||||||
}, [sendAllAction, folder]);
|
}, [sendAllAction, folder]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
|||||||
Found services{' '}
|
Found services{' '}
|
||||||
{services?.slice(0, 5).map((s, i) => {
|
{services?.slice(0, 5).map((s, i) => {
|
||||||
return (
|
return (
|
||||||
<span key={s.name + s.methods.join(',')}>
|
<span key={s.name + s.methods.map((m) => m.name).join(',')}>
|
||||||
<InlineCode>{s.name}</InlineCode>
|
<InlineCode>{s.name}</InlineCode>
|
||||||
{i === services.length - 1 ? '' : i === services.length - 2 ? ' and ' : ', '}
|
{i === services.length - 1 ? '' : i === services.length - 2 ? ' and ' : ', '}
|
||||||
</span>
|
</span>
|
||||||
@@ -119,7 +119,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
|||||||
Server reflection found services
|
Server reflection found services
|
||||||
{services?.map((s, i) => {
|
{services?.map((s, i) => {
|
||||||
return (
|
return (
|
||||||
<span key={s.name + s.methods.join(',')}>
|
<span key={s.name + s.methods.map((m) => m.name).join(',')}>
|
||||||
<InlineCode>{s.name}</InlineCode>
|
<InlineCode>{s.name}</InlineCode>
|
||||||
{i === services.length - 1 ? '' : i === services.length - 2 ? ' and ' : ', '}
|
{i === services.length - 1 ? '' : i === services.length - 2 ? ' and ' : ', '}
|
||||||
</span>
|
</span>
|
||||||
@@ -144,7 +144,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
|||||||
{protoFiles.map((f, i) => {
|
{protoFiles.map((f, i) => {
|
||||||
const parts = f.split('/');
|
const parts = f.split('/');
|
||||||
return (
|
return (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<tr key={f + i} className="group">
|
<tr key={f + i} className="group">
|
||||||
<td>
|
<td>
|
||||||
<Icon icon={f.endsWith('.proto') ? 'file_code' : 'folder_code'} />
|
<Icon icon={f.endsWith('.proto') ? 'file_code' : 'folder_code'} />
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function GrpcResponsePane({ style, methodType, activeRequest }: Props) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Set the active message to the first message received if unary
|
// Set the active message to the first message received if unary
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (events.length === 0 || activeEvent != null || methodType !== 'unary') {
|
if (events.length === 0 || activeEvent != null || methodType !== 'unary') {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ export function ImportCurlButton() {
|
|||||||
const importCurl = useImportCurl();
|
const importCurl = useImportCurl();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: none
|
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
readText().then(setClipboardText);
|
readText().then(setClipboardText).catch(() => {});
|
||||||
}, [focused]);
|
}, [focused]);
|
||||||
|
|
||||||
if (!clipboardText?.trim().startsWith('curl ')) {
|
if (!clipboardText?.trim().startsWith('curl ')) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { linter } from '@codemirror/lint';
|
|||||||
import type { HttpRequest } from '@yaakapp-internal/models';
|
import type { HttpRequest } from '@yaakapp-internal/models';
|
||||||
import { patchModel } from '@yaakapp-internal/models';
|
import { patchModel } from '@yaakapp-internal/models';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { useKeyValue } from '../hooks/useKeyValue';
|
import { useKeyValue } from '../hooks/useKeyValue';
|
||||||
import { textLikelyContainsJsonComments } from '../lib/jsonComments';
|
import { textLikelyContainsJsonComments } from '../lib/jsonComments';
|
||||||
import { Banner } from './core/Banner';
|
import { Banner } from './core/Banner';
|
||||||
@@ -58,12 +59,12 @@ export function JsonBodyEditor({ forceUpdateKey, heightMode, request }: Props) {
|
|||||||
} else {
|
} else {
|
||||||
delete newBody.sendJsonComments;
|
delete newBody.sendJsonComments;
|
||||||
}
|
}
|
||||||
patchModel(request, { body: newBody });
|
fireAndForget(patchModel(request, { body: newBody }));
|
||||||
}, [request, autoFix]);
|
}, [request, autoFix]);
|
||||||
|
|
||||||
const handleDropdownOpen = useCallback(() => {
|
const handleDropdownOpen = useCallback(() => {
|
||||||
if (!bannerDismissed) {
|
if (!bannerDismissed) {
|
||||||
setBannerDismissed(true);
|
fireAndForget(setBannerDismissed(true));
|
||||||
}
|
}
|
||||||
}, [bannerDismissed, setBannerDismissed]);
|
}, [bannerDismissed, setBannerDismissed]);
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ const markdownComponents: Partial<Components> = {
|
|||||||
language={match[1]}
|
language={match[1]}
|
||||||
style={prismTheme}
|
style={prismTheme}
|
||||||
>
|
>
|
||||||
{String(children).replace(/\n$/, '')}
|
{String(children as string).replace(/\n$/, '')}
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
) : (
|
) : (
|
||||||
<code {...extraProps} ref={ref} className={className}>
|
<code {...extraProps} ref={ref} className={className}>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { getRecentCookieJars } from '../hooks/useRecentCookieJars';
|
|||||||
import { getRecentEnvironments } from '../hooks/useRecentEnvironments';
|
import { getRecentEnvironments } from '../hooks/useRecentEnvironments';
|
||||||
import { getRecentRequests } from '../hooks/useRecentRequests';
|
import { getRecentRequests } from '../hooks/useRecentRequests';
|
||||||
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { router } from '../lib/router';
|
import { router } from '../lib/router';
|
||||||
|
|
||||||
export function RedirectToLatestWorkspace() {
|
export function RedirectToLatestWorkspace() {
|
||||||
@@ -20,7 +21,7 @@ export function RedirectToLatestWorkspace() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
fireAndForget((async () => {
|
||||||
const workspaceId = recentWorkspaces[0] ?? workspaces[0]?.id ?? 'n/a';
|
const workspaceId = recentWorkspaces[0] ?? workspaces[0]?.id ?? 'n/a';
|
||||||
const environmentId = (await getRecentEnvironments(workspaceId))[0] ?? null;
|
const environmentId = (await getRecentEnvironments(workspaceId))[0] ?? null;
|
||||||
const cookieJarId = (await getRecentCookieJars(workspaceId))[0] ?? null;
|
const cookieJarId = (await getRecentCookieJars(workspaceId))[0] ?? null;
|
||||||
@@ -34,7 +35,7 @@ export function RedirectToLatestWorkspace() {
|
|||||||
|
|
||||||
console.log('Redirecting to workspace', params, search);
|
console.log('Redirecting to workspace', params, search);
|
||||||
await router.navigate({ to: '/workspaces/$workspaceId', params, search });
|
await router.navigate({ to: '/workspaces/$workspaceId', params, search });
|
||||||
})();
|
})());
|
||||||
}, [recentWorkspaces, workspaces, workspaces.length]);
|
}, [recentWorkspaces, workspaces, workspaces.length]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export function ResponseCookies({ response }: Props) {
|
|||||||
) : (
|
) : (
|
||||||
<KeyValueRows>
|
<KeyValueRows>
|
||||||
{sentCookies.map((cookie, i) => (
|
{sentCookies.map((cookie, i) => (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<KeyValueRow labelColor="primary" key={i} label={cookie.name}>
|
<KeyValueRow labelColor="primary" key={i} label={cookie.name}>
|
||||||
{cookie.value}
|
{cookie.value}
|
||||||
</KeyValueRow>
|
</KeyValueRow>
|
||||||
@@ -153,7 +153,7 @@ export function ResponseCookies({ response }: Props) {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
{receivedCookies.map((cookie, i) => (
|
{receivedCookies.map((cookie, i) => (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<div key={i} className="flex flex-col gap-1">
|
<div key={i} className="flex flex-col gap-1">
|
||||||
<div className="flex items-center gap-2 my-1">
|
<div className="flex items-center gap-2 my-1">
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export function ResponseHeaders({ response }: Props) {
|
|||||||
) : (
|
) : (
|
||||||
<KeyValueRows>
|
<KeyValueRows>
|
||||||
{requestHeaders.map((h, i) => (
|
{requestHeaders.map((h, i) => (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<KeyValueRow labelColor="primary" key={i} label={h.name}>
|
<KeyValueRow labelColor="primary" key={i} label={h.name}>
|
||||||
{h.value}
|
{h.value}
|
||||||
</KeyValueRow>
|
</KeyValueRow>
|
||||||
@@ -84,7 +84,7 @@ export function ResponseHeaders({ response }: Props) {
|
|||||||
) : (
|
) : (
|
||||||
<KeyValueRows>
|
<KeyValueRows>
|
||||||
{responseHeaders.map((h, i) => (
|
{responseHeaders.map((h, i) => (
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: none
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<KeyValueRow labelColor="info" key={i} label={h.name}>
|
<KeyValueRow labelColor="info" key={i} label={h.name}>
|
||||||
{h.value}
|
{h.value}
|
||||||
</KeyValueRow>
|
</KeyValueRow>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { VStack } from './core/Stacks';
|
|||||||
export default function RouteError({ error }: { error: unknown }) {
|
export default function RouteError({ error }: { error: unknown }) {
|
||||||
console.log('Error', error);
|
console.log('Error', error);
|
||||||
const stringified = JSON.stringify(error);
|
const stringified = JSON.stringify(error);
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
// oxlint-disable-next-line no-explicit-any
|
||||||
const message = (error as any).message ?? stringified;
|
const message = (error as any).message ?? stringified;
|
||||||
const stack =
|
const stack =
|
||||||
typeof error === 'object' && error != null && 'stack' in error ? String(error.stack) : null;
|
typeof error === 'object' && error != null && 'stack' in error ? String(error.stack) : null;
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ export function SettingsCertificates() {
|
|||||||
<VStack space={3}>
|
<VStack space={3}>
|
||||||
{certificates.map((cert, index) => (
|
{certificates.map((cert, index) => (
|
||||||
<CertificateEditor
|
<CertificateEditor
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: Index is fine here
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
key={index}
|
key={index}
|
||||||
certificate={cert}
|
certificate={cert}
|
||||||
index={index}
|
index={index}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
|||||||
import { getWebsocketRequestActions } from '../hooks/useWebsocketRequestActions';
|
import { getWebsocketRequestActions } from '../hooks/useWebsocketRequestActions';
|
||||||
import { deepEqualAtom } from '../lib/atoms';
|
import { deepEqualAtom } from '../lib/atoms';
|
||||||
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
||||||
|
import { fireAndForget } from '../lib/fireAndForget';
|
||||||
import { jotaiStore } from '../lib/jotai';
|
import { jotaiStore } from '../lib/jotai';
|
||||||
import { resolvedModelName } from '../lib/resolvedModelName';
|
import { resolvedModelName } from '../lib/resolvedModelName';
|
||||||
import { isSidebarFocused } from '../lib/scopes';
|
import { isSidebarFocused } from '../lib/scopes';
|
||||||
@@ -439,7 +440,7 @@ function Sidebar({ className }: { className?: string }) {
|
|||||||
leftSlot: <Icon icon="arrow_right_circle" />,
|
leftSlot: <Icon icon="arrow_right_circle" />,
|
||||||
hidden: workspaces.length <= 1 || requestItems.length === 0 || requestItems.length !== items.length,
|
hidden: workspaces.length <= 1 || requestItems.length === 0 || requestItems.length !== items.length,
|
||||||
onSelect: () => {
|
onSelect: () => {
|
||||||
actions['sidebar.selected.move'].cb(items);
|
fireAndForget(actions['sidebar.selected.move'].cb(items));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ function InitializedTemplateFunctionDialog({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tooLarge = rendered.data ? rendered.data.length > 10000 : false;
|
const tooLarge = rendered.data ? rendered.data.length > 10000 : false;
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Only update this on rendered data change to keep secrets hidden on input change
|
// oxlint-disable-next-line react-hooks/exhaustive-deps -- Only update this on rendered data change to keep secrets hidden on input change
|
||||||
const dataContainsSecrets = useMemo(() => {
|
const dataContainsSecrets = useMemo(() => {
|
||||||
for (const [name, value] of Object.entries(argValues)) {
|
for (const [name, value] of Object.entries(argValues)) {
|
||||||
const arg = templateFunction.data?.args.find((a) => 'name' in a && a.name === name);
|
const arg = templateFunction.data?.args.find((a) => 'name' in a && a.name === name);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export function WorkspaceEncryptionSetting({ size, expanded, onDone, onEnabledEn
|
|||||||
await enableEncryption(workspaceMeta.workspaceId);
|
await enableEncryption(workspaceMeta.workspaceId);
|
||||||
setJustEnabledEncryption(true);
|
setJustEnabledEncryption(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(`Failed to enable encryption: ${err}`);
|
setError(`Failed to enable encryption: ${err instanceof Error ? err.message : String(err)}`);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -285,7 +285,7 @@ function HighlightedKey({ keyText, show }: { keyText: string; show: boolean }) {
|
|||||||
keyText.split('').map((c, i) => {
|
keyText.split('').map((c, i) => {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
// biome-ignore lint/suspicious/noArrayIndexKey: it's fine
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
key={i}
|
key={i}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
c.match(/[0-9]/) && 'text-info',
|
c.match(/[0-9]/) && 'text-info',
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user