mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-29 13:41:51 +02:00
Switch to BiomeJS (#306)
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
export const HEADER_SIZE_MD = '27px';
|
||||
export const HEADER_SIZE_LG = '40px';
|
||||
|
||||
|
||||
@@ -8,20 +8,23 @@ export function languageFromContentType(
|
||||
const justContentType = contentType?.split(';')[0] ?? contentType ?? '';
|
||||
if (justContentType.includes('json')) {
|
||||
return 'json';
|
||||
} else if (justContentType.includes('xml')) {
|
||||
}
|
||||
if (justContentType.includes('xml')) {
|
||||
return 'xml';
|
||||
} else if (justContentType.includes('html')) {
|
||||
}
|
||||
if (justContentType.includes('html')) {
|
||||
const detected = detectFromContent(content);
|
||||
if (detected === 'xml') {
|
||||
// If it's detected as XML, but is already HTML, don't change it
|
||||
return 'html';
|
||||
} else {
|
||||
return detected;
|
||||
}
|
||||
} else if (justContentType.includes('javascript')) {
|
||||
return detected;
|
||||
}
|
||||
if (justContentType.includes('javascript')) {
|
||||
// Sometimes `application/javascript` returns JSON, so try detecting that
|
||||
return detectFromContent(content, 'javascript');
|
||||
} else if (justContentType.includes('markdown')) {
|
||||
}
|
||||
if (justContentType.includes('markdown')) {
|
||||
return 'markdown';
|
||||
}
|
||||
|
||||
@@ -38,12 +41,14 @@ function detectFromContent(
|
||||
|
||||
if (firstBytes.startsWith('{') || firstBytes.startsWith('[')) {
|
||||
return 'json';
|
||||
} else if (
|
||||
}
|
||||
if (
|
||||
firstBytes.toLowerCase().startsWith('<!doctype') ||
|
||||
firstBytes.toLowerCase().startsWith('<html')
|
||||
) {
|
||||
return 'html';
|
||||
} else if (firstBytes.startsWith('<')) {
|
||||
}
|
||||
if (firstBytes.startsWith('<')) {
|
||||
return 'xml';
|
||||
}
|
||||
|
||||
@@ -56,8 +61,7 @@ export function isJSON(content: string | null | undefined): boolean {
|
||||
try {
|
||||
JSON.parse(content);
|
||||
return true;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export function copyToClipboard(
|
||||
writeText(text).catch(console.error);
|
||||
}
|
||||
|
||||
if (text != '' && !disableToast) {
|
||||
if (text !== '' && !disableToast) {
|
||||
showToast({
|
||||
id: 'copied',
|
||||
color: 'success',
|
||||
|
||||
@@ -15,10 +15,13 @@ export async function deleteModelWithConfirm(
|
||||
return false;
|
||||
}
|
||||
const models = Array.isArray(model) ? model : [model];
|
||||
const firstModel = models[0];
|
||||
if (firstModel == null) return false;
|
||||
|
||||
const descriptor =
|
||||
models.length === 1 ? modelTypeLabel(models[0]!) : pluralizeCount('Item', models.length);
|
||||
models.length === 1 ? modelTypeLabel(firstModel) : pluralizeCount('Item', models.length);
|
||||
const confirmed = await showConfirmDelete({
|
||||
id: 'delete-model-' + models.map((m) => m.id).join(','),
|
||||
id: `delete-model-${models.map((m) => m.id).join(',')}`,
|
||||
title: `Delete ${descriptor}`,
|
||||
requireTyping: options.confirmName,
|
||||
description: (
|
||||
@@ -26,7 +29,7 @@ export async function deleteModelWithConfirm(
|
||||
Permanently delete{' '}
|
||||
{models.length === 1 ? (
|
||||
<>
|
||||
<InlineCode>{resolvedModelName(models[0]!)}</InlineCode>?
|
||||
<InlineCode>{resolvedModelName(firstModel)}</InlineCode>?
|
||||
</>
|
||||
) : models.length < 10 ? (
|
||||
<>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { DragMoveEvent } from '@dnd-kit/core';
|
||||
|
||||
export function computeSideForDragMove(
|
||||
id: string,
|
||||
e: DragMoveEvent,
|
||||
): 'above' | 'below' | null {
|
||||
export function computeSideForDragMove(id: string, e: DragMoveEvent): 'above' | 'below' | null {
|
||||
if (e.over == null || e.over.id !== id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ export function analyzeTemplate(template: string): 'global_secured' | 'local_sec
|
||||
|
||||
if (secureTags === 1 && totalTags === 1) {
|
||||
return 'global_secured';
|
||||
} else if (insecureTags === 0) {
|
||||
return 'local_secured';
|
||||
} else {
|
||||
return 'insecure';
|
||||
}
|
||||
if (insecureTags === 0) {
|
||||
return 'local_secured';
|
||||
}
|
||||
return 'insecure';
|
||||
}
|
||||
|
||||
export async function convertTemplateToInsecure(template: string) {
|
||||
|
||||
@@ -14,7 +14,7 @@ export function getNodeText(node: ReactNode): string {
|
||||
}
|
||||
|
||||
if (typeof node === 'object' && node) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
return getNodeText((node as any).props.children);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ export function initGlobalListeners() {
|
||||
variant="border"
|
||||
rightSlot={<Icon icon="external_link" />}
|
||||
onClick={async () => {
|
||||
await openUrl('https://yaak.app/changelog/' + version);
|
||||
await openUrl(`https://yaak.app/changelog/${version}`);
|
||||
}}
|
||||
>
|
||||
What's New
|
||||
|
||||
@@ -3,16 +3,14 @@ import { sleep } from './sleep';
|
||||
/** Ensures a promise takes at least a certain number of milliseconds to resolve */
|
||||
export async function minPromiseMillis<T>(promise: Promise<T>, millis = 300) {
|
||||
const start = Date.now();
|
||||
let result;
|
||||
let err;
|
||||
let result: T;
|
||||
|
||||
try {
|
||||
result = await promise;
|
||||
} catch (e) {
|
||||
err = e;
|
||||
const delayFor = millis - (Date.now() - start);
|
||||
await sleep(delayFor);
|
||||
throw err;
|
||||
throw e;
|
||||
}
|
||||
|
||||
const delayFor = millis - (Date.now() - start);
|
||||
|
||||
@@ -24,7 +24,7 @@ export function cookieDomain(cookie: Cookie): string {
|
||||
}
|
||||
|
||||
export function modelsEq(a: AnyModel, b: AnyModel) {
|
||||
if (a.model != b.model) {
|
||||
if (a.model !== b.model) {
|
||||
return false;
|
||||
}
|
||||
if (a.model === 'key_value' && b.model === 'key_value') {
|
||||
@@ -49,13 +49,13 @@ export function getCharsetFromContentType(headers: HttpResponseHeader[]): string
|
||||
}
|
||||
|
||||
export function isBaseEnvironment(environment: Environment): boolean {
|
||||
return environment.parentModel == 'workspace';
|
||||
return environment.parentModel === 'workspace';
|
||||
}
|
||||
|
||||
export function isSubEnvironment(environment: Environment): boolean {
|
||||
return environment.parentModel == 'environment';
|
||||
return environment.parentModel === 'environment';
|
||||
}
|
||||
|
||||
export function isFolderEnvironment(environment: Environment): boolean {
|
||||
return environment.parentModel == 'folder';
|
||||
return environment.parentModel === 'folder';
|
||||
}
|
||||
|
||||
@@ -39,5 +39,5 @@ export async function showPrompt({
|
||||
|
||||
if (result == null) return null; // Cancelled
|
||||
if (typeof result.value === 'string') return result.value;
|
||||
else return props.defaultValue ?? '';
|
||||
return props.defaultValue ?? '';
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {QueryCache, QueryClient} from "@tanstack/react-query";
|
||||
import { QueryCache, QueryClient } from '@tanstack/react-query';
|
||||
|
||||
export const queryClient = new QueryClient({
|
||||
queryCache: new QueryCache({
|
||||
onError: (err, query) => {
|
||||
console.log('Query client error', { err, query });
|
||||
},
|
||||
}),
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
networkMode: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false, // Don't refetch when a hook mounts
|
||||
},
|
||||
queryCache: new QueryCache({
|
||||
onError: (err, query) => {
|
||||
console.log('Query client error', { err, query });
|
||||
},
|
||||
}),
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
networkMode: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false, // Don't refetch when a hook mounts
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AnyModel} from '@yaakapp-internal/models';
|
||||
import type { AnyModel } from '@yaakapp-internal/models';
|
||||
import { patchModel } from '@yaakapp-internal/models';
|
||||
import { InlineCode } from '../components/core/InlineCode';
|
||||
import { showPrompt } from './prompt';
|
||||
|
||||
@@ -47,14 +47,14 @@ export function resolvedModelNameWithFoldersArray(model: AnyModel | null): strin
|
||||
const folders = jotaiStore.get(foldersAtom) ?? [];
|
||||
|
||||
const getParents = (m: AnyModel, names: string[]) => {
|
||||
names = [...names, resolvedModelName(m)];
|
||||
let newNames = [...names, resolvedModelName(m)];
|
||||
if ('folderId' in m) {
|
||||
const parent = folders.find((f) => f.id === m.folderId);
|
||||
if (parent) {
|
||||
names = [...resolvedModelNameWithFoldersArray(parent), ...names];
|
||||
newNames = [...resolvedModelNameWithFoldersArray(parent), ...newNames];
|
||||
}
|
||||
}
|
||||
return names;
|
||||
return newNames;
|
||||
};
|
||||
|
||||
return getParents(model, []);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Create a new router instance
|
||||
import {createRouter} from "@tanstack/react-router";
|
||||
import {routeTree} from "../routeTree.gen";
|
||||
import { createRouter } from '@tanstack/react-router';
|
||||
import { routeTree } from '../routeTree.gen';
|
||||
|
||||
export const router = createRouter({ routeTree });
|
||||
|
||||
// Register the router instance for type safety
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
router: typeof router;
|
||||
}
|
||||
interface Register {
|
||||
router: typeof router;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
export function isSidebarFocused() {
|
||||
return document.activeElement?.closest('.x-theme-sidebar') != null;
|
||||
}
|
||||
|
||||
@@ -15,20 +15,22 @@ export function setWorkspaceSearchParams(
|
||||
folder_id: string | null;
|
||||
}>,
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(router as any).navigate({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
search: (prev: any) => {
|
||||
// console.log('Navigating to', { prev, search });
|
||||
const o = { ...prev, ...search };
|
||||
for (const k of Object.keys(o)) {
|
||||
if (o[k] == null) {
|
||||
delete o[k];
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
(router as any)
|
||||
.navigate({
|
||||
// biome-ignore lint/suspicious/noExplicitAny: none
|
||||
search: (prev: any) => {
|
||||
// console.log('Navigating to', { prev, search });
|
||||
const o = { ...prev, ...search };
|
||||
for (const k of Object.keys(o)) {
|
||||
if (o[k] == null) {
|
||||
delete o[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return o;
|
||||
},
|
||||
});
|
||||
return o;
|
||||
},
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
export function navigateToRequestOrFolderOrWorkspace(
|
||||
|
||||
@@ -139,7 +139,7 @@ function bannerColorVariables(color: YaakColor | null): Partial<CSSVariables> {
|
||||
|
||||
function buttonSolidColorVariables(
|
||||
color: YaakColor | null,
|
||||
isDefault: boolean = false,
|
||||
isDefault = false,
|
||||
): Partial<CSSVariables> {
|
||||
if (color == null) return {};
|
||||
|
||||
@@ -161,7 +161,7 @@ function buttonSolidColorVariables(
|
||||
|
||||
function buttonBorderColorVariables(
|
||||
color: YaakColor | null,
|
||||
isDefault: boolean = false,
|
||||
isDefault = false,
|
||||
): Partial<CSSVariables> {
|
||||
if (color == null) return {};
|
||||
|
||||
@@ -268,6 +268,7 @@ export function getThemeCSS(theme: Theme): string {
|
||||
theme.components.toast = theme.components.toast ?? theme.components.menu ?? {};
|
||||
const { components, id, label } = theme;
|
||||
const colors = Object.keys(theme.base).reduce((prev, key) => {
|
||||
// biome-ignore lint/performance/noAccumulatingSpread: none
|
||||
return { ...prev, [key]: theme.base[key as YaakColorKey] };
|
||||
}, {}) as ThemeComponentColors;
|
||||
|
||||
@@ -278,11 +279,11 @@ export function getThemeCSS(theme: Theme): string {
|
||||
baseCss,
|
||||
...Object.keys(components ?? {}).map((key) => componentCSS(theme, key as ComponentName)),
|
||||
variablesToCSS(
|
||||
`.x-theme-button--solid--default`,
|
||||
'.x-theme-button--solid--default',
|
||||
buttonSolidColorVariables(yc(theme, theme.base.surface), true),
|
||||
),
|
||||
variablesToCSS(
|
||||
`.x-theme-button--border--default`,
|
||||
'.x-theme-button--border--default',
|
||||
buttonBorderColorVariables(yc(theme, theme.base.surface), true),
|
||||
),
|
||||
...Object.keys(colors ?? {}).map((key) =>
|
||||
@@ -312,7 +313,7 @@ export function addThemeStylesToDocument(rawTheme: Theme | null) {
|
||||
}
|
||||
|
||||
const theme = completeTheme(rawTheme);
|
||||
let styleEl = document.head.querySelector(`style[data-theme]`);
|
||||
let styleEl = document.head.querySelector('style[data-theme]');
|
||||
if (!styleEl) {
|
||||
styleEl = document.createElement('style');
|
||||
document.head.appendChild(styleEl);
|
||||
|
||||
@@ -3,10 +3,10 @@ import parseColor from 'parse-color';
|
||||
export class YaakColor {
|
||||
private readonly appearance: 'dark' | 'light' = 'light';
|
||||
|
||||
private hue: number = 0;
|
||||
private saturation: number = 0;
|
||||
private lightness: number = 0;
|
||||
private alpha: number = 1;
|
||||
private hue = 0;
|
||||
private saturation = 0;
|
||||
private lightness = 0;
|
||||
private alpha = 1;
|
||||
|
||||
constructor(cssColor: string, appearance: 'dark' | 'light' = 'light') {
|
||||
try {
|
||||
@@ -30,11 +30,12 @@ export class YaakColor {
|
||||
}
|
||||
|
||||
set(cssColor: string): YaakColor {
|
||||
let fixedCssColor = cssColor;
|
||||
if (cssColor.startsWith('#') && cssColor.length === 9) {
|
||||
const [r, g, b, a] = hexToRgba(cssColor);
|
||||
cssColor = `rgba(${r},${g},${b},${a})`;
|
||||
fixedCssColor = `rgba(${r},${g},${b},${a})`;
|
||||
}
|
||||
const { hsla } = parseColor(cssColor);
|
||||
const { hsla } = parseColor(fixedCssColor);
|
||||
this.hue = hsla[0];
|
||||
this.saturation = hsla[1];
|
||||
this.lightness = hsla[2];
|
||||
@@ -131,7 +132,7 @@ function rgbaToHex(r: number, g: number, b: number, a: number): string {
|
||||
const hex = Number(Math.round(n)).toString(16);
|
||||
return hex.length === 1 ? `0${hex}` : hex;
|
||||
};
|
||||
return '#' + [toHex(r), toHex(g), toHex(b), toHex(a * 255)].join('').toUpperCase();
|
||||
return `#${[toHex(r), toHex(g), toHex(b), toHex(a * 255)].join('').toUpperCase()}`;
|
||||
}
|
||||
|
||||
function rgbaToHexNoAlpha(r: number, g: number, b: number): string {
|
||||
@@ -139,7 +140,7 @@ function rgbaToHexNoAlpha(r: number, g: number, b: number): string {
|
||||
const hex = Number(Math.round(n)).toString(16);
|
||||
return hex.length === 1 ? `0${hex}` : hex;
|
||||
};
|
||||
return '#' + [toHex(r), toHex(g), toHex(b)].join('').toUpperCase();
|
||||
return `#${[toHex(r), toHex(g), toHex(b)].join('').toUpperCase()}`;
|
||||
}
|
||||
|
||||
function hexToRgba(hex: string): [number, number, number, number] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export function truncate(text: string, len: number): string {
|
||||
if (text.length <= len) return text;
|
||||
return text.slice(0, len) + '…';
|
||||
return `${text.slice(0, len)}…`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user