mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 20:00:29 +01:00
Fix lint errors and show docs explorer on Cmd click
This commit is contained in:
133
package-lock.json
generated
133
package-lock.json
generated
@@ -7839,6 +7839,19 @@
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fault": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
|
||||
"integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"format": "^0.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
@@ -8030,6 +8043,14 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/format": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||
"integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
|
||||
"engines": {
|
||||
"node": ">=0.4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/format-graphql": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/format-graphql/-/format-graphql-1.5.0.tgz",
|
||||
@@ -8987,6 +9008,29 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hast-util-to-html": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
|
||||
"integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/hast": "^3.0.0",
|
||||
"@types/unist": "^3.0.0",
|
||||
"ccount": "^2.0.0",
|
||||
"comma-separated-tokens": "^2.0.0",
|
||||
"hast-util-whitespace": "^3.0.0",
|
||||
"html-void-elements": "^3.0.0",
|
||||
"mdast-util-to-hast": "^13.0.0",
|
||||
"property-information": "^7.0.0",
|
||||
"space-separated-tokens": "^2.0.0",
|
||||
"stringify-entities": "^4.0.0",
|
||||
"zwitch": "^2.0.4"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hast-util-to-jsx-runtime": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
|
||||
@@ -9074,6 +9118,16 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/html-void-elements": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
|
||||
"integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/http-reasons": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz",
|
||||
@@ -10885,6 +10939,36 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-frontmatter": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz",
|
||||
"integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/mdast": "^4.0.0",
|
||||
"devlop": "^1.0.0",
|
||||
"escape-string-regexp": "^5.0.0",
|
||||
"mdast-util-from-markdown": "^2.0.0",
|
||||
"mdast-util-to-markdown": "^2.0.0",
|
||||
"micromark-extension-frontmatter": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
|
||||
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-gfm": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
|
||||
@@ -11259,6 +11343,22 @@
|
||||
"micromark-util-types": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/micromark-extension-frontmatter": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz",
|
||||
"integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fault": "^2.0.0",
|
||||
"micromark-util-character": "^2.0.0",
|
||||
"micromark-util-symbol": "^2.0.0",
|
||||
"micromark-util-types": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/micromark-extension-gfm": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
|
||||
@@ -14587,6 +14687,37 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-stringify": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz",
|
||||
"integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/hast": "^3.0.0",
|
||||
"hast-util-to-html": "^9.0.0",
|
||||
"unified": "^11.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-frontmatter": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz",
|
||||
"integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/mdast": "^4.0.0",
|
||||
"mdast-util-frontmatter": "^2.0.0",
|
||||
"micromark-extension-frontmatter": "^2.0.0",
|
||||
"unified": "^11.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-gfm": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
|
||||
@@ -18626,6 +18757,8 @@
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-use": "^17.6.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"slugify": "^1.6.6",
|
||||
"uuid": "^11.1.0",
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PluginDefinition } from '@yaakapp/api';
|
||||
import type { PluginDefinition } from '@yaakapp/api';
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
authentication: {
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PluginDefinition } from '@yaakapp/api';
|
||||
import type { PluginDefinition } from '@yaakapp/api';
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
authentication: {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^9.0.2"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PluginDefinition } from '@yaakapp/api';
|
||||
import type { PluginDefinition } from '@yaakapp/api';
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
const algorithms = [
|
||||
@@ -20,49 +20,49 @@ const algorithms = [
|
||||
const defaultAlgorithm = algorithms[0];
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
authentication: {
|
||||
name: 'jwt',
|
||||
label: 'JWT Bearer',
|
||||
shortLabel: 'JWT',
|
||||
args: [
|
||||
{
|
||||
type: 'select',
|
||||
name: 'algorithm',
|
||||
label: 'Algorithm',
|
||||
hideLabel: true,
|
||||
defaultValue: defaultAlgorithm,
|
||||
options: algorithms.map(value => ({ label: value === 'none' ? 'None' : value, value })),
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'secret',
|
||||
label: 'Secret or Private Key',
|
||||
password: true,
|
||||
optional: true,
|
||||
multiLine: true,
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'secretBase64',
|
||||
label: 'Secret is base64 encoded',
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
name: 'payload',
|
||||
label: 'Payload',
|
||||
language: 'json',
|
||||
defaultValue: '{\n "foo": "bar"\n}',
|
||||
placeholder: '{ }',
|
||||
},
|
||||
],
|
||||
async onApply(_ctx, { values }) {
|
||||
const { algorithm, secret: _secret, secretBase64, payload } = values;
|
||||
const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`;
|
||||
const token = jwt.sign(`${payload}`, secret, { algorithm: algorithm as any });
|
||||
const value = `Bearer ${token}`;
|
||||
return { setHeaders: [{ name: 'Authorization', value }] };
|
||||
}
|
||||
,
|
||||
authentication: {
|
||||
name: 'jwt',
|
||||
label: 'JWT Bearer',
|
||||
shortLabel: 'JWT',
|
||||
args: [
|
||||
{
|
||||
type: 'select',
|
||||
name: 'algorithm',
|
||||
label: 'Algorithm',
|
||||
hideLabel: true,
|
||||
defaultValue: defaultAlgorithm,
|
||||
options: algorithms.map((value) => ({ label: value === 'none' ? 'None' : value, value })),
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'secret',
|
||||
label: 'Secret or Private Key',
|
||||
password: true,
|
||||
optional: true,
|
||||
multiLine: true,
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'secretBase64',
|
||||
label: 'Secret is base64 encoded',
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
name: 'payload',
|
||||
label: 'Payload',
|
||||
language: 'json',
|
||||
defaultValue: '{\n "foo": "bar"\n}',
|
||||
placeholder: '{ }',
|
||||
},
|
||||
],
|
||||
async onApply(_ctx, { values }) {
|
||||
const { algorithm, secret: _secret, secretBase64, payload } = values;
|
||||
const secret = secretBase64 ? Buffer.from(`${_secret}`, 'base64') : `${_secret}`;
|
||||
const token = jwt.sign(`${payload}`, secret, {
|
||||
algorithm: algorithm as (typeof algorithms)[number],
|
||||
});
|
||||
const value = `Bearer ${token}`;
|
||||
return { setHeaders: [{ name: 'Authorization', value }] };
|
||||
},
|
||||
}
|
||||
;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Context } from '@yaakapp/api';
|
||||
import type { Context } from '@yaakapp/api';
|
||||
|
||||
export async function storeToken(
|
||||
ctx: Context,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonpath-plus": "^10.3.0"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"shell-quote": "^1.8.1"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"yaml": "^2.4.2"
|
||||
|
||||
@@ -4,11 +4,11 @@ export function convertSyntax(variable: string): string {
|
||||
return variable.replaceAll(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}');
|
||||
}
|
||||
|
||||
export function isJSObject(obj: any) {
|
||||
export function isJSObject(obj: unknown) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]';
|
||||
}
|
||||
|
||||
export function isJSString(obj: any) {
|
||||
export function isJSString(obj: unknown) {
|
||||
return Object.prototype.toString.call(obj) === '[object String]';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Context, PluginDefinition } from '@yaakapp/api';
|
||||
import type { Context, PluginDefinition } from '@yaakapp/api';
|
||||
import YAML from 'yaml';
|
||||
import { deleteUndefinedAttrs, isJSObject } from './common';
|
||||
import { convertInsomniaV4 } from './v4';
|
||||
@@ -15,16 +15,18 @@ export const plugin: PluginDefinition = {
|
||||
};
|
||||
|
||||
export function convertInsomnia(contents: string) {
|
||||
let parsed: any;
|
||||
let parsed: unknown;
|
||||
|
||||
try {
|
||||
parsed = JSON.parse(contents);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Fall through
|
||||
}
|
||||
|
||||
try {
|
||||
parsed = parsed ?? YAML.parse(contents);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Fall through
|
||||
}
|
||||
|
||||
if (!isJSObject(parsed)) return null;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { PartialImportResources } from '@yaakapp/api';
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { PartialImportResources } from '@yaakapp/api';
|
||||
import { convertId, convertSyntax, isJSObject } from './common';
|
||||
|
||||
export function convertInsomniaV4(parsed: Record<string, any>) {
|
||||
export function convertInsomniaV4(parsed: any) {
|
||||
if (!Array.isArray(parsed.resources)) return null;
|
||||
|
||||
const resources: PartialImportResources = {
|
||||
@@ -14,7 +15,9 @@ export function convertInsomniaV4(parsed: Record<string, any>) {
|
||||
};
|
||||
|
||||
// Import workspaces
|
||||
const workspacesToImport = parsed.resources.filter(r => isJSObject(r) && r._type === 'workspace');
|
||||
const workspacesToImport = parsed.resources.filter(
|
||||
(r: any) => isJSObject(r) && r._type === 'workspace',
|
||||
);
|
||||
for (const w of workspacesToImport) {
|
||||
resources.workspaces.push({
|
||||
id: convertId(w._id),
|
||||
@@ -40,13 +43,9 @@ export function convertInsomniaV4(parsed: Record<string, any>) {
|
||||
resources.folders.push(importFolder(child, w._id));
|
||||
nextFolder(child._id);
|
||||
} else if (child._type === 'request') {
|
||||
resources.httpRequests.push(
|
||||
importHttpRequest(child, w._id),
|
||||
);
|
||||
resources.httpRequests.push(importHttpRequest(child, w._id));
|
||||
} else if (child._type === 'grpc_request') {
|
||||
resources.grpcRequests.push(
|
||||
importGrpcRequest(child, w._id),
|
||||
);
|
||||
resources.grpcRequests.push(importGrpcRequest(child, w._id));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -64,10 +63,7 @@ export function convertInsomniaV4(parsed: Record<string, any>) {
|
||||
return { resources };
|
||||
}
|
||||
|
||||
function importHttpRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
): PartialImportResources['httpRequests'][0] {
|
||||
function importHttpRequest(r: any, workspaceId: string): PartialImportResources['httpRequests'][0] {
|
||||
let bodyType: string | null = null;
|
||||
let body = {};
|
||||
if (r.body.mimeType === 'application/octet-stream') {
|
||||
@@ -141,10 +137,7 @@ function importHttpRequest(
|
||||
};
|
||||
}
|
||||
|
||||
function importGrpcRequest(
|
||||
r: any,
|
||||
workspaceId: string,
|
||||
): PartialImportResources['grpcRequests'][0] {
|
||||
function importGrpcRequest(r: any, workspaceId: string): PartialImportResources['grpcRequests'][0] {
|
||||
const parts = r.protoMethodName.split('/').filter((p: any) => p !== '');
|
||||
const service = parts[0] ?? null;
|
||||
const method = parts[1] ?? null;
|
||||
@@ -186,13 +179,18 @@ function importFolder(f: any, workspaceId: string): PartialImportResources['fold
|
||||
};
|
||||
}
|
||||
|
||||
function importEnvironment(e: any, workspaceId: string, isParent?: boolean): PartialImportResources['environments'][0] {
|
||||
function importEnvironment(
|
||||
e: any,
|
||||
workspaceId: string,
|
||||
isParent?: boolean,
|
||||
): PartialImportResources['environments'][0] {
|
||||
return {
|
||||
id: convertId(e._id),
|
||||
createdAt: e.created ? new Date(e.created).toISOString().replace('Z', '') : undefined,
|
||||
updatedAt: e.modified ? new Date(e.modified).toISOString().replace('Z', '') : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
sortPriority: e.metaSortKey, // Will be added to Yaak later
|
||||
base: isParent ?? e.parentId === workspaceId,
|
||||
model: 'environment',
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { PartialImportResources } from '@yaakapp/api';
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { PartialImportResources } from '@yaakapp/api';
|
||||
import { convertId, convertSyntax, isJSObject } from './common';
|
||||
|
||||
export function convertInsomniaV5(parsed: Record<string, any>) {
|
||||
if (!Array.isArray(parsed.collection)) return null;
|
||||
export function convertInsomniaV5(parsed: any) {
|
||||
// Assert parsed is object
|
||||
if (parsed == null || typeof parsed !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!('collection' in parsed) || !Array.isArray(parsed.collection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const resources: PartialImportResources = {
|
||||
environments: [],
|
||||
@@ -14,7 +22,7 @@ export function convertInsomniaV5(parsed: Record<string, any>) {
|
||||
};
|
||||
|
||||
// Import workspaces
|
||||
const meta: Record<string, any> = parsed.meta ?? {};
|
||||
const meta = ('meta' in parsed ? parsed.meta : {}) as Record<string, any>;
|
||||
resources.workspaces.push({
|
||||
id: convertId(meta.id ?? 'collection'),
|
||||
createdAt: meta.created ? new Date(meta.created).toISOString().replace('Z', '') : undefined,
|
||||
@@ -36,17 +44,11 @@ export function convertInsomniaV5(parsed: Record<string, any>) {
|
||||
resources.folders.push(importFolder(child, meta.id, parentId));
|
||||
nextFolder(child.children, child.meta.id);
|
||||
} else if (child.method) {
|
||||
resources.httpRequests.push(
|
||||
importHttpRequest(child, meta.id, parentId),
|
||||
);
|
||||
resources.httpRequests.push(importHttpRequest(child, meta.id, parentId));
|
||||
} else if (child.protoFileId) {
|
||||
resources.grpcRequests.push(
|
||||
importGrpcRequest(child, meta.id, parentId),
|
||||
);
|
||||
resources.grpcRequests.push(importGrpcRequest(child, meta.id, parentId));
|
||||
} else if (child.url) {
|
||||
resources.websocketRequests.push(
|
||||
importWebsocketRequest(child, meta.id, parentId),
|
||||
);
|
||||
resources.websocketRequests.push(importWebsocketRequest(child, meta.id, parentId));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -219,7 +221,11 @@ function importAuthentication(r: any) {
|
||||
return { authenticationType, authentication } as const;
|
||||
}
|
||||
|
||||
function importFolder(f: any, workspaceId: string, parentId: string): PartialImportResources['folders'][0] {
|
||||
function importFolder(
|
||||
f: any,
|
||||
workspaceId: string,
|
||||
parentId: string,
|
||||
): PartialImportResources['folders'][0] {
|
||||
const id = f.meta?.id ?? f._id;
|
||||
const created = f.meta?.created ?? f.created;
|
||||
const updated = f.meta?.modified ?? f.updated;
|
||||
@@ -238,8 +244,11 @@ function importFolder(f: any, workspaceId: string, parentId: string): PartialImp
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function importEnvironment(e: any, workspaceId: string, isParent?: boolean): PartialImportResources['environments'][0] {
|
||||
function importEnvironment(
|
||||
e: any,
|
||||
workspaceId: string,
|
||||
isParent?: boolean,
|
||||
): PartialImportResources['environments'][0] {
|
||||
const id = e.meta?.id ?? e._id;
|
||||
const created = e.meta?.created ?? e.created;
|
||||
const updated = e.meta?.modified ?? e.updated;
|
||||
@@ -251,7 +260,8 @@ function importEnvironment(e: any, workspaceId: string, isParent?: boolean): Par
|
||||
updatedAt: updated ? new Date(updated).toISOString().replace('Z', '') : undefined,
|
||||
workspaceId: convertId(workspaceId),
|
||||
public: !e.isPrivate,
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
sortPriority: sortKey, // Will be added to Yaak later
|
||||
base: isParent ?? e.parentId === workspaceId,
|
||||
model: 'environment',
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"openapi-to-postmanv2": "^5.0.0",
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Environment, PluginDefinition } from '@yaakapp/api';
|
||||
import type { Environment, PluginDefinition } from '@yaakapp/api';
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
importer: {
|
||||
name: 'Yaak',
|
||||
description: 'Yaak official format',
|
||||
onImport(_ctx, args) {
|
||||
return migrateImport(args.text) as any;
|
||||
return migrateImport(args.text);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -14,7 +14,7 @@ export function migrateImport(contents: string) {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(contents);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,6 @@ export function migrateImport(contents: string) {
|
||||
return { resources: parsed.resources }; // Should already be in the correct format
|
||||
}
|
||||
|
||||
function isJSObject(obj: any) {
|
||||
function isJSObject(obj: unknown) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]';
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
||||
import type { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
templateFunctions: [
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
||||
import type { CallTemplateFunctionArgs, Context, PluginDefinition } from '@yaakapp/api';
|
||||
import { createHash, createHmac } from 'node:crypto';
|
||||
|
||||
const algorithms = ['md5', 'sha1', 'sha256', 'sha512'] as const;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonpath-plus": "^10.3.0"
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonpath-plus": "^10.3.0",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^11.1.0"
|
||||
|
||||
@@ -7,7 +7,7 @@ export const plugin: PluginDefinition = {
|
||||
name: 'uuid.v1',
|
||||
description: 'Generate a UUID V1',
|
||||
args: [],
|
||||
async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise<string | null> {
|
||||
async onRender(): Promise<string | null> {
|
||||
return v1();
|
||||
},
|
||||
},
|
||||
@@ -32,7 +32,7 @@ export const plugin: PluginDefinition = {
|
||||
name: 'uuid.v4',
|
||||
description: 'Generate a UUID V4',
|
||||
args: [],
|
||||
async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise<string | null> {
|
||||
async onRender(): Promise<string | null> {
|
||||
return v4();
|
||||
},
|
||||
},
|
||||
@@ -68,7 +68,7 @@ export const plugin: PluginDefinition = {
|
||||
name: 'uuid.v7',
|
||||
description: 'Generate a UUID V7',
|
||||
args: [],
|
||||
async onRender(_ctx: Context, _args: CallTemplateFunctionArgs): Promise<string | null> {
|
||||
async onRender(): Promise<string | null> {
|
||||
return v7();
|
||||
},
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev",
|
||||
"lint": "tsc --noEmit"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ import classNames from 'classnames';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { CSSProperties } from 'react';
|
||||
import React from 'react';
|
||||
import { showGraphQLDocExplorerAtom } from '../atoms/graphqlSchemaAtom';
|
||||
import { useCurrentGraphQLSchema } from '../hooks/useIntrospectGraphQL';
|
||||
import type { SlotProps } from './core/SplitLayout';
|
||||
import { SplitLayout } from './core/SplitLayout';
|
||||
import { GraphQLDocsExplorer } from './GraphQLDocsExplorer';
|
||||
import { GraphQLDocsExplorer } from './graphql/GraphQLDocsExplorer';
|
||||
import { showGraphQLDocExplorerAtom } from './graphql/graphqlAtoms';
|
||||
import { HttpRequestPane } from './HttpRequestPane';
|
||||
import { HttpResponsePane } from './HttpResponsePane';
|
||||
|
||||
@@ -17,7 +17,6 @@ interface Props {
|
||||
}
|
||||
|
||||
export function HttpRequestLayout({ activeRequest, style }: Props) {
|
||||
const { bodyType } = activeRequest;
|
||||
const showGraphQLDocExplorer = useAtomValue(showGraphQLDocExplorerAtom);
|
||||
const graphQLSchema = useCurrentGraphQLSchema(activeRequest);
|
||||
|
||||
@@ -39,11 +38,11 @@ export function HttpRequestLayout({ activeRequest, style }: Props) {
|
||||
/>
|
||||
);
|
||||
|
||||
if (bodyType === 'graphql' && showGraphQLDocExplorer && graphQLSchema != null) {
|
||||
if (activeRequest.bodyType === 'graphql' && showGraphQLDocExplorer && graphQLSchema != null) {
|
||||
return (
|
||||
<SplitLayout
|
||||
name="graphql_layout"
|
||||
defaultRatio={1/3}
|
||||
defaultRatio={1 / 3}
|
||||
firstSlot={requestResponseSplit}
|
||||
secondSlot={({ style, orientation }) => (
|
||||
<GraphQLDocsExplorer
|
||||
|
||||
@@ -47,13 +47,13 @@ import type { TabItem } from './core/Tabs/Tabs';
|
||||
import { EmptyStateText } from './EmptyStateText';
|
||||
import { FormMultipartEditor } from './FormMultipartEditor';
|
||||
import { FormUrlencodedEditor } from './FormUrlencodedEditor';
|
||||
import { GraphQLEditor } from './GraphQLEditor';
|
||||
import { HeadersEditor } from './HeadersEditor';
|
||||
import { HttpAuthenticationEditor } from './HttpAuthenticationEditor';
|
||||
import { MarkdownEditor } from './MarkdownEditor';
|
||||
import { RequestMethodDropdown } from './RequestMethodDropdown';
|
||||
import { UrlBar } from './UrlBar';
|
||||
import { UrlParametersEditor } from './UrlParameterEditor';
|
||||
import { GraphQLEditor } from './graphql/GraphQLEditor';
|
||||
|
||||
interface Props {
|
||||
style: CSSProperties;
|
||||
|
||||
@@ -6,7 +6,9 @@ import {
|
||||
} from '@codemirror/autocomplete';
|
||||
import { history, historyKeymap } from '@codemirror/commands';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { json } from '@codemirror/lang-json';
|
||||
import { markdown } from '@codemirror/lang-markdown';
|
||||
import { xml } from '@codemirror/lang-xml';
|
||||
import type { LanguageSupport } from '@codemirror/language';
|
||||
import {
|
||||
codeFolding,
|
||||
@@ -35,15 +37,15 @@ import {
|
||||
import { tags as t } from '@lezer/highlight';
|
||||
import type { EnvironmentVariable } from '@yaakapp-internal/models';
|
||||
import { graphql } from 'cm6-graphql';
|
||||
import { renderMarkdown } from '../../../lib/markdown';
|
||||
import { pluralizeCount } from '../../../lib/pluralize';
|
||||
import { showInGraphQLDocsExplorer } from '../../graphql/useGraphQLDocsExplorer';
|
||||
import type { EditorProps } from './Editor';
|
||||
import { pairs } from './pairs/extension';
|
||||
import { text } from './text/extension';
|
||||
import type { TwigCompletionOption } from './twig/completion';
|
||||
import { twig } from './twig/extension';
|
||||
import { pathParametersPlugin } from './twig/pathParameters';
|
||||
import { json } from '@codemirror/lang-json';
|
||||
import { xml } from '@codemirror/lang-xml';
|
||||
import { pairs } from './pairs/extension';
|
||||
import { url } from './url/extension';
|
||||
|
||||
export const syntaxHighlightStyle = HighlightStyle.define([
|
||||
@@ -123,7 +125,22 @@ export function getLanguageExtension({
|
||||
|
||||
// GraphQL is a special exception
|
||||
if (language === 'graphql') {
|
||||
return [graphql(), extraExtensions];
|
||||
return [
|
||||
graphql(undefined, {
|
||||
async onCompletionInfoRender(gqlCompletionItem): Promise<Node | null> {
|
||||
if (!gqlCompletionItem.documentation) return null;
|
||||
const innerHTML = await renderMarkdown(gqlCompletionItem.documentation);
|
||||
const span = document.createElement('span');
|
||||
span.innerHTML = innerHTML;
|
||||
return span;
|
||||
},
|
||||
onShowInDocs(field, type, parentType) {
|
||||
console.log("SHOW IN DOCS", field);
|
||||
showInGraphQLDocsExplorer(field, type, parentType).catch(console.error);
|
||||
},
|
||||
}),
|
||||
extraExtensions,
|
||||
];
|
||||
}
|
||||
|
||||
const base_ = syntaxExtensions[language ?? 'text'] ?? text();
|
||||
@@ -229,7 +246,6 @@ export const multiLineExtensions = ({ hideGutter }: { hideGutter?: boolean }) =>
|
||||
}
|
||||
},
|
||||
}),
|
||||
EditorState.allowMultipleSelections.of(true),
|
||||
indentOnInput(),
|
||||
rectangularSelection(),
|
||||
crosshairCursor(),
|
||||
|
||||
@@ -64,7 +64,7 @@ export function SplitLayout({
|
||||
}
|
||||
|
||||
const size = useContainerSize(containerRef);
|
||||
const verticalBasedOnSize = size.width < STACK_VERTICAL_WIDTH;
|
||||
const verticalBasedOnSize = size.width !== 0 && size.width < STACK_VERTICAL_WIDTH;
|
||||
const vertical = layout !== 'horizontal' && (layout === 'vertical' || verticalBasedOnSize);
|
||||
|
||||
const styles = useMemo<CSSProperties>(() => {
|
||||
@@ -142,31 +142,25 @@ export function SplitLayout({
|
||||
[width, height, vertical, minHeightPx, setHeight, minWidthPx, setWidth],
|
||||
);
|
||||
|
||||
const containerQueryReady = size.width > 0 || size.height > 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={styles}
|
||||
className={classNames(className, 'grid w-full h-full overflow-hidden')}
|
||||
>
|
||||
{containerQueryReady && (
|
||||
{firstSlot({ style: areaL, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
{secondSlot && (
|
||||
<>
|
||||
{firstSlot({ style: areaL, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
{secondSlot && (
|
||||
<>
|
||||
<ResizeHandle
|
||||
style={areaD}
|
||||
isResizing={isResizing}
|
||||
className={classNames(vertical ? '-translate-y-1.5' : '-translate-x-1.5')}
|
||||
onResizeStart={handleResizeStart}
|
||||
onReset={handleReset}
|
||||
side={vertical ? 'top' : 'left'}
|
||||
justify="center"
|
||||
/>
|
||||
{secondSlot({ style: areaR, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
</>
|
||||
)}
|
||||
<ResizeHandle
|
||||
style={areaD}
|
||||
isResizing={isResizing}
|
||||
className={classNames(vertical ? '-translate-y-1.5' : '-translate-x-1.5')}
|
||||
onResizeStart={handleResizeStart}
|
||||
onReset={handleReset}
|
||||
side={vertical ? 'top' : 'left'}
|
||||
justify="center"
|
||||
/>
|
||||
{secondSlot({ style: areaR, orientation: vertical ? 'vertical' : 'horizontal' })}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -23,17 +23,18 @@ import {
|
||||
} from 'graphql';
|
||||
import type { CSSProperties, HTMLAttributes, KeyboardEvent, ReactNode } from 'react';
|
||||
import { Fragment, memo, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { showGraphQLDocExplorerAtom } from '../atoms/graphqlSchemaAtom';
|
||||
import { useClickOutside } from '../hooks/useClickOutside';
|
||||
import { useContainerSize } from '../hooks/useContainerQuery';
|
||||
import { useDebouncedValue } from '../hooks/useDebouncedValue';
|
||||
import { useStateWithDeps } from '../hooks/useStateWithDeps';
|
||||
import { jotaiStore } from '../lib/jotai';
|
||||
import { CountBadge } from './core/CountBadge';
|
||||
import { Icon } from './core/Icon';
|
||||
import { IconButton } from './core/IconButton';
|
||||
import { PlainInput } from './core/PlainInput';
|
||||
import { Markdown } from './Markdown';
|
||||
import { useClickOutside } from '../../hooks/useClickOutside';
|
||||
import { useContainerSize } from '../../hooks/useContainerQuery';
|
||||
import { useDebouncedValue } from '../../hooks/useDebouncedValue';
|
||||
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||
import { jotaiStore } from '../../lib/jotai';
|
||||
import { CountBadge } from '../core/CountBadge';
|
||||
import { Icon } from '../core/Icon';
|
||||
import { IconButton } from '../core/IconButton';
|
||||
import { PlainInput } from '../core/PlainInput';
|
||||
import { Markdown } from '../Markdown';
|
||||
import { showGraphQLDocExplorerAtom } from './graphqlAtoms';
|
||||
import { useGraphQLDocsExplorerEvent } from './useGraphQLDocsExplorer';
|
||||
|
||||
interface Props {
|
||||
style?: CSSProperties;
|
||||
@@ -58,6 +59,17 @@ export const GraphQLDocsExplorer = memo(function GraphQLDocsExplorer({
|
||||
const mutType = schema.getMutationType();
|
||||
const subType = schema.getSubscriptionType();
|
||||
|
||||
useGraphQLDocsExplorerEvent('gql_docs_explorer.show_in_docs', ({ field }) => {
|
||||
walkTypeGraph(schema, null, (t) => {
|
||||
if (t.name === field) {
|
||||
setActiveItem(toExplorerItem(t, null));
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const qryItem: ExplorerItem = qryType ? { kind: 'type', type: qryType, from: null } : null;
|
||||
const mutItem: ExplorerItem = mutType ? { kind: 'type', type: mutType, from: null } : null;
|
||||
const subItem: ExplorerItem = subType ? { kind: 'type', type: subType, from: null } : null;
|
||||
@@ -642,22 +654,20 @@ function GqlSchemaSearch({
|
||||
|
||||
const results = useMemo(() => {
|
||||
const results: SearchResult[] = [];
|
||||
walkTypeGraph(
|
||||
currentItem?.type ?? null,
|
||||
(type, from, depth) => {
|
||||
if (type === currentItem?.type) {
|
||||
return null; // Remove the current type from results
|
||||
}
|
||||
walkTypeGraph(schema, currentItem?.type ?? null, (type, from, depth) => {
|
||||
if (type === currentItem?.type) {
|
||||
return true; // Skip the current type and continue
|
||||
}
|
||||
|
||||
const match = fuzzyMatch(type.name, debouncedValue);
|
||||
if (match == null) {
|
||||
// Do nothing
|
||||
} else {
|
||||
results.push({ name: type.name, type, score: match.score, from, depth });
|
||||
}
|
||||
},
|
||||
schema,
|
||||
);
|
||||
const match = fuzzyMatch(type.name, debouncedValue);
|
||||
if (match == null) {
|
||||
// Do nothing
|
||||
} else {
|
||||
results.push({ name: type.name, type, score: match.score, from, depth });
|
||||
}
|
||||
|
||||
return true; // Continue searching
|
||||
});
|
||||
results.sort((a, b) => {
|
||||
if (value == '') {
|
||||
if (a.name.startsWith('_') && !b.name.startsWith('_')) {
|
||||
@@ -831,13 +841,13 @@ function DocMarkdown({ children, className }: { children: string | null; classNa
|
||||
}
|
||||
|
||||
function walkTypeGraph(
|
||||
schema: GraphQLSchema,
|
||||
start: GraphQLType | GraphQLField<any, any> | GraphQLInputField | null,
|
||||
cb: (
|
||||
type: GraphQLNamedType | GraphQLField<any, any> | GraphQLInputField,
|
||||
from: GraphQLNamedType | null,
|
||||
path: string[],
|
||||
) => void,
|
||||
schema: GraphQLSchema,
|
||||
) => boolean,
|
||||
) {
|
||||
const visited = new Set<string>();
|
||||
const queue: Array<{
|
||||
@@ -867,7 +877,8 @@ function walkTypeGraph(
|
||||
if (visited.has(name)) continue;
|
||||
visited.add(name);
|
||||
|
||||
cb(current, from, path);
|
||||
const cont = cb(current, from, path);
|
||||
if (!cont) break;
|
||||
|
||||
if (isObjectType(current) || isInterfaceType(current)) {
|
||||
for (const field of Object.values(current.getFields())) {
|
||||
@@ -6,19 +6,19 @@ import { formatSdl } from 'format-graphql';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useEffect, useMemo, useRef } from 'react';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
import { showGraphQLDocExplorerAtom } from '../atoms/graphqlSchemaAtom';
|
||||
import { useIntrospectGraphQL } from '../hooks/useIntrospectGraphQL';
|
||||
import { useStateWithDeps } from '../hooks/useStateWithDeps';
|
||||
import { showDialog } from '../lib/dialog';
|
||||
import { Banner } from './core/Banner';
|
||||
import { Button } from './core/Button';
|
||||
import type { DropdownItem } from './core/Dropdown';
|
||||
import { Dropdown } from './core/Dropdown';
|
||||
import type { EditorProps } from './core/Editor/Editor';
|
||||
import { Editor } from './core/Editor/Editor';
|
||||
import { FormattedError } from './core/FormattedError';
|
||||
import { Icon } from './core/Icon';
|
||||
import { Separator } from './core/Separator';
|
||||
import { useIntrospectGraphQL } from '../../hooks/useIntrospectGraphQL';
|
||||
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||
import { showDialog } from '../../lib/dialog';
|
||||
import { Banner } from '../core/Banner';
|
||||
import { Button } from '../core/Button';
|
||||
import type { DropdownItem } from '../core/Dropdown';
|
||||
import { Dropdown } from '../core/Dropdown';
|
||||
import type { EditorProps } from '../core/Editor/Editor';
|
||||
import { Editor } from '../core/Editor/Editor';
|
||||
import { FormattedError } from '../core/FormattedError';
|
||||
import { Icon } from '../core/Icon';
|
||||
import { Separator } from '../core/Separator';
|
||||
import { showGraphQLDocExplorerAtom } from './graphqlAtoms';
|
||||
|
||||
type Props = Pick<EditorProps, 'heightMode' | 'className' | 'forceUpdateKey'> & {
|
||||
baseRequest: HttpRequest;
|
||||
@@ -1,3 +1,3 @@
|
||||
import { atomWithKVStorage } from '../lib/atoms/atomWithKVStorage';
|
||||
import { atomWithKVStorage } from '../../lib/atoms/atomWithKVStorage';
|
||||
|
||||
export const showGraphQLDocExplorerAtom = atomWithKVStorage<boolean>('show_graphql_docs', false);
|
||||
63
src-web/components/graphql/useGraphQLDocsExplorer.ts
Normal file
63
src-web/components/graphql/useGraphQLDocsExplorer.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import type { DependencyList } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { jotaiStore } from '../../lib/jotai';
|
||||
import { sleep } from '../../lib/sleep';
|
||||
import { showGraphQLDocExplorerAtom } from './graphqlAtoms';
|
||||
|
||||
type EventDataMap = {
|
||||
'gql_docs_explorer.show_in_docs': { field?: string; type?: string; parentType?: string };
|
||||
'gql_docs_explorer.focus_tab': undefined;
|
||||
};
|
||||
|
||||
export function useGraphQLDocsExplorerEvent<
|
||||
Event extends keyof EventDataMap,
|
||||
Data extends EventDataMap[Event],
|
||||
>(event: Event, fn: (data: Data) => void, deps?: DependencyList) {
|
||||
useEffect(() => {
|
||||
emitter.on(event, fn);
|
||||
return () => {
|
||||
emitter.off(event, fn);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, deps);
|
||||
}
|
||||
|
||||
export async function showInGraphQLDocsExplorer(
|
||||
field: string | undefined,
|
||||
type: string | undefined,
|
||||
parentType: string | undefined,
|
||||
) {
|
||||
const isVisible = jotaiStore.get(showGraphQLDocExplorerAtom);
|
||||
if (!isVisible) {
|
||||
// Show and give some time for the explorer to start listening for events
|
||||
jotaiStore.set(showGraphQLDocExplorerAtom, true);
|
||||
await sleep(100);
|
||||
}
|
||||
emitter.emit('gql_docs_explorer.show_in_docs', { field, type, parentType });
|
||||
}
|
||||
|
||||
const emitter = new (class GraphQLDocsExplorerEventEmitter {
|
||||
#emitter: EventEmitter = new EventEmitter();
|
||||
|
||||
emit<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
|
||||
event: Event,
|
||||
data: Data,
|
||||
) {
|
||||
this.#emitter.emit(event, data);
|
||||
}
|
||||
|
||||
on<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
|
||||
event: Event,
|
||||
fn: (data: Data) => void,
|
||||
) {
|
||||
this.#emitter.on(event, fn);
|
||||
}
|
||||
|
||||
off<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
|
||||
event: Event,
|
||||
fn: (data: Data) => void,
|
||||
) {
|
||||
this.#emitter.off(event, fn);
|
||||
}
|
||||
})();
|
||||
27
src-web/lib/markdown.ts
Normal file
27
src-web/lib/markdown.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkRehype from 'remark-rehype';
|
||||
import { unified } from 'unified';
|
||||
|
||||
const renderer = unified()
|
||||
.use(remarkParse)
|
||||
.use(remarkGfm)
|
||||
.use(remarkRehype, {
|
||||
// handlers: {
|
||||
// link: (state, node, parent) => {
|
||||
// return node;
|
||||
// },
|
||||
// },
|
||||
})
|
||||
.use(rehypeStringify);
|
||||
|
||||
export async function renderMarkdown(md: string): Promise<string> {
|
||||
try {
|
||||
const r = await renderer.process(md);
|
||||
return r.toString();
|
||||
} catch (err) {
|
||||
console.log('FAILED TO RENDER MARKDOWN', err);
|
||||
return 'error';
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite dev --force",
|
||||
"build": "vite build",
|
||||
"lint": "tsc --noEmit && eslint . --ext .ts,.tsx"
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/commands": "^6.8.1",
|
||||
@@ -61,6 +61,8 @@
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-use": "^17.6.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"slugify": "^1.6.6",
|
||||
"uuid": "^11.1.0",
|
||||
|
||||
Reference in New Issue
Block a user