diff --git a/.eslintrc.cjs b/.eslintrc.cjs index d714ffdf..d3c06978 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -12,7 +12,13 @@ module.exports = { parserOptions: { project: ["./tsconfig.json"] }, - ignorePatterns: ["scripts/**/*", "plugin-runtime/**/*", "src-tauri/**/*", "plugins/**/*"], + ignorePatterns: [ + "scripts/**/*", + "plugin-runtime/**/*", + "plugin-runtime-types/**/*", + "src-tauri/**/*", + "plugins/**/*", + ], settings: { react: { version: "detect" diff --git a/plugin-runtime-types/.gitignore b/plugin-runtime-types/.gitignore new file mode 100644 index 00000000..3063f07d --- /dev/null +++ b/plugin-runtime-types/.gitignore @@ -0,0 +1,2 @@ +lib +node_modules diff --git a/plugin-runtime-types/package-lock.json b/plugin-runtime-types/package-lock.json new file mode 100644 index 00000000..1ef3d1b5 --- /dev/null +++ b/plugin-runtime-types/package-lock.json @@ -0,0 +1,44 @@ +{ + "name": "@yaakapp/api", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@yaakapp/api", + "version": "0.0.1", + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.5.4" + } + }, + "node_modules/@types/node": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz", + "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", + "dev": true, + "dependencies": { + "undici-types": "~6.11.1" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", + "dev": true + } + } +} diff --git a/plugin-runtime-types/package.json b/plugin-runtime-types/package.json new file mode 100644 index 00000000..d9cb6a91 --- /dev/null +++ b/plugin-runtime-types/package.json @@ -0,0 +1,18 @@ +{ + "name": "@yaakapp/api", + "version": "0.0.5", + "main": "lib/index.js", + "typings": "./lib/index.d.ts", + "files": [ + "lib" + ], + "scripts": { + "prepublish": "tsc" + }, + "dependencies": { + "@types/node": "^22.0.0" + }, + "devDependencies": { + "typescript": "^5.5.4" + } +} diff --git a/plugin-runtime-types/src/helpers.ts b/plugin-runtime-types/src/helpers.ts new file mode 100644 index 00000000..be548943 --- /dev/null +++ b/plugin-runtime-types/src/helpers.ts @@ -0,0 +1,2 @@ +export type AtLeast = Partial & Pick; +export type SingleOrArray = T[] | T; diff --git a/plugin-runtime-types/src/index.ts b/plugin-runtime-types/src/index.ts new file mode 100644 index 00000000..7f2551d3 --- /dev/null +++ b/plugin-runtime-types/src/index.ts @@ -0,0 +1,3 @@ +export type * from './models'; +export type * from './plugins'; +export type * from './themes'; diff --git a/plugin-runtime-types/src/models/index.ts b/plugin-runtime-types/src/models/index.ts new file mode 100644 index 00000000..fcb073fe --- /dev/null +++ b/plugin-runtime-types/src/models/index.ts @@ -0,0 +1 @@ +export * from './types'; diff --git a/plugin-runtime-types/src/models/types.ts b/plugin-runtime-types/src/models/types.ts new file mode 100644 index 00000000..e5c8f0ed --- /dev/null +++ b/plugin-runtime-types/src/models/types.ts @@ -0,0 +1,135 @@ +export interface BaseModel { + readonly model: string; + readonly id: string; + readonly createdAt: string; + readonly updatedAt: string; +} + +export interface Workspace extends BaseModel { + readonly model: 'workspace'; + name: string; + description: string; + variables: EnvironmentVariable[]; + settingValidateCertificates: boolean; + settingFollowRedirects: boolean; + settingRequestTimeout: number; +} + +export interface EnvironmentVariable { + name: string; + value: string; + enabled?: boolean; +} + +export interface Folder extends BaseModel { + readonly workspaceId: string; + readonly model: 'folder'; + folderId: string | null; + sortPriority: number; + name: string; +} + +export interface Environment extends BaseModel { + readonly workspaceId: string; + readonly model: 'environment'; + name: string; + variables: EnvironmentVariable[]; +} + +export interface HttpHeader { + name: string; + value: string; + enabled?: boolean; +} + +export interface HttpUrlParameter { + name: string; + value: string; + enabled?: boolean; +} + +export interface GrpcMetadataEntry { + name: string; + value: string; + enabled?: boolean; +} + +export interface GrpcRequest extends BaseModel { + readonly workspaceId: string; + readonly model: 'grpc_request'; + folderId: string | null; + sortPriority: number; + name: string; + url: string; + service: string | null; + method: string | null; + message: string; + authentication: Record; + authenticationType: string | null; + metadata: GrpcMetadataEntry[]; +} + +export interface GrpcEvent extends BaseModel { + readonly workspaceId: string; + readonly requestId: string; + readonly connectionId: string; + readonly model: 'grpc_event'; + content: string; + status: number | null; + error: string | null; + eventType: + | 'info' + | 'error' + | 'client_message' + | 'server_message' + | 'connection_start' + | 'connection_end'; + metadata: Record; +} + +export interface GrpcConnection extends BaseModel { + readonly workspaceId: string; + readonly requestId: string; + readonly model: 'grpc_connection'; + service: string; + method: string; + elapsed: number; + elapsedConnection: number; + status: number; + url: string; + error: string | null; + trailers: Record; +} + +export interface HttpRequest extends BaseModel { + readonly workspaceId: string; + readonly model: 'http_request'; + folderId: string | null; + sortPriority: number; + name: string; + url: string; + urlParameters: HttpUrlParameter[]; + body: Record; + bodyType: string | null; + authentication: Record; + authenticationType: string | null; + method: string; + headers: HttpHeader[]; +} + +export interface HttpResponse extends BaseModel { + readonly workspaceId: string; + readonly model: 'http_response'; + readonly requestId: string; + readonly bodyPath: string | null; + readonly contentLength: number | null; + readonly error: string; + readonly status: number; + readonly elapsed: number; + readonly elapsedHeaders: number; + readonly statusReason: string; + readonly version: string; + readonly remoteAddr: string; + readonly url: string; + readonly headers: HttpHeader[]; +} diff --git a/plugin-runtime-types/src/plugins/context.ts b/plugin-runtime-types/src/plugins/context.ts new file mode 100644 index 00000000..5f5f9f76 --- /dev/null +++ b/plugin-runtime-types/src/plugins/context.ts @@ -0,0 +1,11 @@ +import { HttpRequest, HttpResponse } from '../models'; + +export type YaakContext = { + metadata: { + getVersion(): Promise; + }; + httpRequest: { + send(id: string): Promise; + getById(id: string): Promise; + }; +}; diff --git a/plugin-runtime-types/src/plugins/import.ts b/plugin-runtime-types/src/plugins/import.ts new file mode 100644 index 00000000..6868ef3f --- /dev/null +++ b/plugin-runtime-types/src/plugins/import.ts @@ -0,0 +1,16 @@ +import { AtLeast } from '../helpers'; +import { Environment, Folder, HttpRequest, Workspace } from '../models'; +import { YaakContext } from './context'; + +export type ImportPluginResponse = null | { + resources: Partial<{ + workspaces: AtLeast[]; + environments: AtLeast[]; + httpRequests: AtLeast[]; + folders: AtLeast[]; + }>; +}; + +export type ImporterPlugin = { + onImport(ctx: YaakContext, fileContents: string): Promise; +}; diff --git a/plugin-runtime-types/src/plugins/index.ts b/plugin-runtime-types/src/plugins/index.ts new file mode 100644 index 00000000..e6716db9 --- /dev/null +++ b/plugin-runtime-types/src/plugins/index.ts @@ -0,0 +1,13 @@ +import { SingleOrArray } from '../helpers'; +import { ImporterPlugin } from './import'; +import { ThemePlugin } from './theme'; + +/** + * The global structure of a Yaak plugin + */ +export type YaakPlugin = { + /** One or many plugins to import data into Yaak */ + importers?: SingleOrArray; + /** One or many themes to customize the Yaak UI */ + themes?: SingleOrArray; +}; diff --git a/plugin-runtime-types/src/plugins/theme.ts b/plugin-runtime-types/src/plugins/theme.ts new file mode 100644 index 00000000..fb8b2312 --- /dev/null +++ b/plugin-runtime-types/src/plugins/theme.ts @@ -0,0 +1,5 @@ +import { Theme } from '../themes'; + +export type ThemePlugin = { + theme: Theme; +}; diff --git a/plugin-runtime-types/src/themes/index.ts b/plugin-runtime-types/src/themes/index.ts new file mode 100644 index 00000000..40412dc7 --- /dev/null +++ b/plugin-runtime-types/src/themes/index.ts @@ -0,0 +1,44 @@ +export type Colors = { + surface: string; + surfaceHighlight?: string; + surfaceActive?: string; + + text: string; + textSubtle?: string; + textSubtlest?: string; + + border?: string; + borderSubtle?: string; + borderFocus?: string; + + shadow?: string; + backdrop?: string; + selection?: string; + + primary?: string; + secondary?: string; + info?: string; + success?: string; + notice?: string; + warning?: string; + danger?: string; +}; + +export type Theme = Colors & { + id: string; + name: string; + components?: Partial<{ + dialog: Partial; + menu: Partial; + toast: Partial; + sidebar: Partial; + responsePane: Partial; + appHeader: Partial; + button: Partial; + banner: Partial; + placeholder: Partial; + urlBar: Partial; + editor: Partial; + input: Partial; + }>; +}; diff --git a/plugin-runtime-types/tsconfig.json b/plugin-runtime-types/tsconfig.json new file mode 100644 index 00000000..afa6c5f8 --- /dev/null +++ b/plugin-runtime-types/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "node16", + "target": "es6", + "lib": ["es2021"], + "declaration": true, + "declarationDir": "./lib", + "outDir": "./lib", + "strict": true, + "types": ["node"] + }, + "files": [ + "src/index.ts" + ] +} diff --git a/plugin-runtime/tsconfig.json b/plugin-runtime/tsconfig.json index a3217bba..9ccaccf0 100644 --- a/plugin-runtime/tsconfig.json +++ b/plugin-runtime/tsconfig.json @@ -11,7 +11,6 @@ "sourceMap": true, "outDir": "dist", "baseUrl": ".", - "skipLibCheck": true, "paths": { "*": [ "node_modules/*", diff --git a/src-web/index.d.ts b/src-web/index.d.ts deleted file mode 100644 index 6e7077f3..00000000 --- a/src-web/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare module 'format-graphql' { - export function formatSdl(query: string): string; -} - -declare module '*.svg' { - export const ReactComponent: React.FunctionComponent>; -} diff --git a/src-web/lib/models.ts b/src-web/lib/models.ts index afe4df5e..fe0299de 100644 --- a/src-web/lib/models.ts +++ b/src-web/lib/models.ts @@ -1,3 +1,18 @@ +import type { + BaseModel, + Workspace, + HttpResponse, + HttpRequest, + HttpHeader, + Folder, + GrpcRequest, + GrpcEvent, + GrpcConnection, + Environment, +} from '../../plugin-runtime-types'; + +export * from '../../plugin-runtime-types'; + export const BODY_TYPE_NONE = null; export const BODY_TYPE_GRAPHQL = 'graphql'; export const BODY_TYPE_JSON = 'application/json'; @@ -24,12 +39,6 @@ export type Model = | Environment | CookieJar; -export interface BaseModel { - readonly id: string; - readonly createdAt: string; - readonly updatedAt: string; -} - export interface Settings extends BaseModel { readonly model: 'settings'; theme: string; @@ -44,16 +53,6 @@ export interface Settings extends BaseModel { openWorkspaceNewWindow: boolean | null; } -export interface Workspace extends BaseModel { - readonly model: 'workspace'; - name: string; - description: string; - variables: EnvironmentVariable[]; - settingValidateCertificates: boolean; - settingFollowRedirects: boolean; - settingRequestTimeout: number; -} - export interface CookieJar extends BaseModel { readonly model: 'cookie_jar'; workspaceId: string; @@ -81,108 +80,6 @@ export function cookieDomain(cookie: Cookie): string { return 'unknown'; } -export interface EnvironmentVariable { - name: string; - value: string; - enabled?: boolean; -} - -export interface Folder extends BaseModel { - readonly workspaceId: string; - readonly model: 'folder'; - folderId: string | null; - sortPriority: number; - name: string; -} - -export interface Environment extends BaseModel { - readonly workspaceId: string; - readonly model: 'environment'; - name: string; - variables: EnvironmentVariable[]; -} - -export interface HttpHeader { - name: string; - value: string; - enabled?: boolean; -} - -export interface HttpUrlParameter { - name: string; - value: string; - enabled?: boolean; -} - -export interface GrpcMetadataEntry { - name: string; - value: string; - enabled?: boolean; -} - -export interface GrpcRequest extends BaseModel { - readonly workspaceId: string; - readonly model: 'grpc_request'; - folderId: string | null; - sortPriority: number; - name: string; - url: string; - service: string | null; - method: string | null; - message: string; - authentication: Record; - authenticationType: string | null; - metadata: GrpcMetadataEntry[]; -} - -export interface GrpcEvent extends BaseModel { - readonly workspaceId: string; - readonly requestId: string; - readonly connectionId: string; - readonly model: 'grpc_event'; - content: string; - status: number | null; - error: string | null; - eventType: - | 'info' - | 'error' - | 'client_message' - | 'server_message' - | 'connection_start' - | 'connection_end'; - metadata: Record; -} - -export interface GrpcConnection extends BaseModel { - readonly workspaceId: string; - readonly requestId: string; - readonly model: 'grpc_connection'; - service: string; - method: string; - elapsed: number; - elapsedConnection: number; - status: number; - url: string; - error: string | null; - trailers: Record; -} - -export interface HttpRequest extends BaseModel { - readonly workspaceId: string; - readonly model: 'http_request'; - folderId: string | null; - sortPriority: number; - name: string; - url: string; - urlParameters: HttpUrlParameter[]; - body: Record; - bodyType: string | null; - authentication: Record; - authenticationType: string | null; - method: string; - headers: HttpHeader[]; -} - export interface KeyValue extends Omit { readonly model: 'key_value'; readonly key: string; @@ -190,23 +87,6 @@ export interface KeyValue extends Omit { value: string; } -export interface HttpResponse extends BaseModel { - readonly workspaceId: string; - readonly model: 'http_response'; - readonly requestId: string; - readonly bodyPath: string | null; - readonly contentLength: number | null; - readonly error: string; - readonly status: number; - readonly elapsed: number; - readonly elapsedHeaders: number; - readonly statusReason: string; - readonly version: string; - readonly remoteAddr: string; - readonly url: string; - readonly headers: HttpHeader[]; -} - export function isResponseLoading(response: HttpResponse | GrpcConnection): boolean { return response.elapsed === 0; } diff --git a/src-web/plugin/runtime.d.ts b/src-web/plugin/runtime.d.ts deleted file mode 100644 index 13f022b6..00000000 --- a/src-web/plugin/runtime.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare global { - const YAML: { - parse: (yml: string) => unknown; - }; - interface YaakContext { - foo: string; - } -} - -export {};