Compare commits
1 commit
dev
...
worktree-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
873cb69319 |
22 changed files with 30 additions and 63 deletions
|
|
@ -34,10 +34,10 @@ const AUTOCOMPLETE_ROWS = FOOTER_MENU_ROWS
|
||||||
const AUTOCOMPLETE_BOTTOM_ROWS = 1
|
const AUTOCOMPLETE_BOTTOM_ROWS = 1
|
||||||
|
|
||||||
export const TEXTAREA_MIN_ROWS = 1
|
export const TEXTAREA_MIN_ROWS = 1
|
||||||
export const TEXTAREA_MAX_ROWS = 6
|
const TEXTAREA_MAX_ROWS = 6
|
||||||
export const PROMPT_MAX_ROWS = TEXTAREA_MAX_ROWS + AUTOCOMPLETE_ROWS - 1 + AUTOCOMPLETE_BOTTOM_ROWS
|
export const PROMPT_MAX_ROWS = TEXTAREA_MAX_ROWS + AUTOCOMPLETE_ROWS - 1 + AUTOCOMPLETE_BOTTOM_ROWS
|
||||||
|
|
||||||
export const HINT_BREAKPOINTS = {
|
const HINT_BREAKPOINTS = {
|
||||||
send: 50,
|
send: 50,
|
||||||
newline: 66,
|
newline: 66,
|
||||||
history: 80,
|
history: 80,
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,6 @@ type RunFooterViewProps = {
|
||||||
onSubagentSelect?: (sessionID: string | undefined) => void
|
onSubagentSelect?: (sessionID: string | undefined) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export { TEXTAREA_MIN_ROWS, TEXTAREA_MAX_ROWS } from "./footer.prompt"
|
|
||||||
|
|
||||||
export function RunFooterView(props: RunFooterViewProps) {
|
export function RunFooterView(props: RunFooterViewProps) {
|
||||||
const term = useTerminalDimensions()
|
const term = useTerminalDimensions()
|
||||||
const active = createMemo<FooterView>(() => props.view?.() ?? { type: "prompt" })
|
const active = createMemo<FooterView>(() => props.view?.() ?? { type: "prompt" })
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ function todoColor(theme: RunTheme, status: string) {
|
||||||
return status === "in_progress" ? theme.footer.warning : theme.block.muted
|
return status === "in_progress" ? theme.footer.warning : theme.block.muted
|
||||||
}
|
}
|
||||||
|
|
||||||
export function entryGroupKey(commit: StreamCommit): string | undefined {
|
function entryGroupKey(commit: StreamCommit): string | undefined {
|
||||||
if (!commit.partID) {
|
if (!commit.partID) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ export function sameEntryGroup(left: StreamCommit | undefined, right: StreamComm
|
||||||
return Boolean(current && next && current === next)
|
return Boolean(current && next && current === next)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function entryLayout(commit: StreamCommit, body: RunEntryBody = entryBody(commit)): EntryLayout {
|
function entryLayout(commit: StreamCommit, body: RunEntryBody = entryBody(commit)): EntryLayout {
|
||||||
if (commit.kind === "tool") {
|
if (commit.kind === "tool") {
|
||||||
if (body.type === "structured" || body.type === "markdown") {
|
if (body.type === "structured" || body.type === "markdown") {
|
||||||
return "block"
|
return "block"
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ import { useDialog } from "@tui/ui/dialog"
|
||||||
import { useSync } from "@tui/context/sync"
|
import { useSync } from "@tui/context/sync"
|
||||||
import { For, Match, Switch, Show, createMemo } from "solid-js"
|
import { For, Match, Switch, Show, createMemo } from "solid-js"
|
||||||
|
|
||||||
export type DialogStatusProps = {}
|
|
||||||
|
|
||||||
export function DialogStatus() {
|
export function DialogStatus() {
|
||||||
const sync = useSync()
|
const sync = useSync()
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export function recentConnectedWorkspaces<WorkspaceInfo extends { id: string; ti
|
||||||
return { recent, hasMore: recent.length < workspaces.length }
|
return { recent, hasMore: recent.length < workspaces.length }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function warpReminderText(dir: string) {
|
function warpReminderText(dir: string) {
|
||||||
return `<system-reminder>The user has changed the current working directory to "${dir}". This is still the same project but at a possibly new location; take this into account when working with any files from now on.</system-reminder>`
|
return `<system-reminder>The user has changed the current working directory to "${dir}". This is still the same project but at a possibly new location; take this into account when working with any files from now on.</system-reminder>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ export async function confirmWorkspaceFileChanges(input: {
|
||||||
return fileChangeChoice === "yes"
|
return fileChangeChoice === "yes"
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DialogWorkspaceSelect(props: {
|
function DialogWorkspaceSelect(props: {
|
||||||
adapters?: Adapter[]
|
adapters?: Adapter[]
|
||||||
onSelect: (selection: WorkspaceSelection) => Promise<void> | void
|
onSelect: (selection: WorkspaceSelection) => Promise<void> | void
|
||||||
}) {
|
}) {
|
||||||
|
|
|
||||||
|
|
@ -878,8 +878,3 @@ export function Logo(props: { shape?: LogoShape; ink?: RGBA; idle?: boolean } =
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GoLogo() {
|
|
||||||
const { theme } = useTheme()
|
|
||||||
const base = tint(theme.background, theme.text, 0.62)
|
|
||||||
return <Logo shape={go} ink={base} idle />
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import { useSDK } from "./sdk"
|
||||||
import { RGBA } from "@opentui/core"
|
import { RGBA } from "@opentui/core"
|
||||||
import { Filesystem } from "@/util/filesystem"
|
import { Filesystem } from "@/util/filesystem"
|
||||||
|
|
||||||
export function parseModel(model: string) {
|
function parseModel(model: string) {
|
||||||
const [providerID, ...rest] = model.split("/")
|
const [providerID, ...rest] = model.split("/")
|
||||||
return {
|
return {
|
||||||
providerID: providerID,
|
providerID: providerID,
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,18 @@ import { createStore, reconcile } from "solid-js/store"
|
||||||
import { createSimpleContext } from "./helper"
|
import { createSimpleContext } from "./helper"
|
||||||
import type { PromptInfo } from "../component/prompt/history"
|
import type { PromptInfo } from "../component/prompt/history"
|
||||||
|
|
||||||
export type HomeRoute = {
|
type HomeRoute = {
|
||||||
type: "home"
|
type: "home"
|
||||||
prompt?: PromptInfo
|
prompt?: PromptInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SessionRoute = {
|
type SessionRoute = {
|
||||||
type: "session"
|
type: "session"
|
||||||
sessionID: string
|
sessionID: string
|
||||||
prompt?: PromptInfo
|
prompt?: PromptInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PluginRoute = {
|
type PluginRoute = {
|
||||||
type: "plugin"
|
type: "plugin"
|
||||||
id: string
|
id: string
|
||||||
data?: Record<string, unknown>
|
data?: Record<string, unknown>
|
||||||
|
|
@ -44,8 +44,6 @@ export const { use: useRoute, provider: RouteProvider } = createSimpleContext({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export type RouteContext = ReturnType<typeof useRoute>
|
|
||||||
|
|
||||||
export function useRouteData<T extends Route["type"]>(type: T) {
|
export function useRouteData<T extends Route["type"]>(type: T) {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
return route.data as Extract<Route, { type: typeof type }>
|
return route.data as Extract<Route, { type: typeof type }>
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,7 @@ export function tint(base: RGBA, overlay: RGBA, alpha: number): RGBA {
|
||||||
return RGBA.fromInts(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255))
|
return RGBA.fromInts(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJson {
|
function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJson {
|
||||||
const bg = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)
|
const bg = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)
|
||||||
const fg = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)
|
const fg = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)
|
||||||
const transparent = RGBA.fromValues(bg.r, bg.g, bg.b, 0)
|
const transparent = RGBA.fromValues(bg.r, bg.g, bg.b, 0)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { buildFileTree, flattenFileTree, type FileTreeItem } from "./diff-viewer
|
||||||
const FILE_TREE_WIDTH = 32
|
const FILE_TREE_WIDTH = 32
|
||||||
const FILE_TREE_HORIZONTAL_PADDING = 2
|
const FILE_TREE_HORIZONTAL_PADDING = 2
|
||||||
|
|
||||||
export type DiffViewerFileTreeTheme = {
|
type DiffViewerFileTreeTheme = {
|
||||||
readonly background: ColorInput
|
readonly background: ColorInput
|
||||||
readonly backgroundPanel: ColorInput
|
readonly backgroundPanel: ColorInput
|
||||||
readonly backgroundElement: ColorInput
|
readonly backgroundElement: ColorInput
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import type { TuiConfig } from "./config/tui"
|
||||||
import { useTuiConfig } from "./context/tui-config"
|
import { useTuiConfig } from "./context/tui-config"
|
||||||
import { TuiKeybind } from "./config/keybind"
|
import { TuiKeybind } from "./config/keybind"
|
||||||
|
|
||||||
export const LEADER_TOKEN = "leader"
|
const LEADER_TOKEN = "leader"
|
||||||
export const OPENCODE_BASE_MODE = "base"
|
export const OPENCODE_BASE_MODE = "base"
|
||||||
export const COMMAND_PALETTE_COMMAND = "command.palette.show"
|
export const COMMAND_PALETTE_COMMAND = "command.palette.show"
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ function isVisiblePaletteCommand(command: Command) {
|
||||||
return command.hidden !== true && command.name !== COMMAND_PALETTE_COMMAND
|
return command.hidden !== true && command.name !== COMMAND_PALETTE_COMMAND
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createOpencodeModeStack(keymap: OpenTuiKeymap) {
|
function createOpencodeModeStack(keymap: OpenTuiKeymap) {
|
||||||
keymap.setData(OPENCODE_MODE_KEY, OPENCODE_BASE_MODE)
|
keymap.setData(OPENCODE_MODE_KEY, OPENCODE_BASE_MODE)
|
||||||
|
|
||||||
const offFields = keymap.registerLayerFields({
|
const offFields = keymap.registerLayerFields({
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { isRecord } from "@/util/record"
|
||||||
type RuntimeSlotMap = TuiSlotMap<Record<string, object>>
|
type RuntimeSlotMap = TuiSlotMap<Record<string, object>>
|
||||||
|
|
||||||
type Slot = <Name extends string>(props: TuiSlotProps<Name>) => JSX.Element | null
|
type Slot = <Name extends string>(props: TuiSlotProps<Name>) => JSX.Element | null
|
||||||
export type HostSlotPlugin<Slots extends Record<string, object> = {}> = SolidPlugin<TuiSlotMap<Slots>, TuiSlotContext>
|
type HostSlotPlugin<Slots extends Record<string, object> = {}> = SolidPlugin<TuiSlotMap<Slots>, TuiSlotContext>
|
||||||
|
|
||||||
export type HostPluginApi = TuiPluginApi
|
export type HostPluginApi = TuiPluginApi
|
||||||
export type HostSlots = {
|
export type HostSlots = {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export type DialogConfirmProps = {
|
||||||
label?: string
|
label?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DialogConfirmResult = boolean | undefined
|
type DialogConfirmResult = boolean | undefined
|
||||||
|
|
||||||
export function DialogConfirm(props: DialogConfirmProps) {
|
export function DialogConfirm(props: DialogConfirmProps) {
|
||||||
const dialog = useDialog()
|
const dialog = useDialog()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { Schema } from "effect"
|
||||||
import { TuiEvent } from "../event"
|
import { TuiEvent } from "../event"
|
||||||
|
|
||||||
type ToastInput = Schema.Codec.Encoded<typeof TuiEvent.ToastShow.properties>
|
type ToastInput = Schema.Codec.Encoded<typeof TuiEvent.ToastShow.properties>
|
||||||
export type ToastOptions = Schema.Schema.Type<typeof TuiEvent.ToastShow.properties>
|
type ToastOptions = Schema.Schema.Type<typeof TuiEvent.ToastShow.properties>
|
||||||
|
|
||||||
const decodeToastOptions = Schema.decodeUnknownSync(TuiEvent.ToastShow.properties)
|
const decodeToastOptions = Schema.decodeUnknownSync(TuiEvent.ToastShow.properties)
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ function init() {
|
||||||
return toast
|
return toast
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToastContext = ReturnType<typeof init>
|
type ToastContext = ReturnType<typeof init>
|
||||||
|
|
||||||
const ctx = createContext<ToastContext>()
|
const ctx = createContext<ToastContext>()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { SDKProvider, type EventSource } from "../../../../src/cli/cmd/tui/conte
|
||||||
import { SyncProvider, useSync } from "../../../../src/cli/cmd/tui/context/sync"
|
import { SyncProvider, useSync } from "../../../../src/cli/cmd/tui/context/sync"
|
||||||
import type { GlobalEvent } from "@opencode-ai/sdk/v2"
|
import type { GlobalEvent } from "@opencode-ai/sdk/v2"
|
||||||
|
|
||||||
export const worktree = "/tmp/opencode"
|
const worktree = "/tmp/opencode"
|
||||||
export const directory = `${worktree}/packages/opencode`
|
export const directory = `${worktree}/packages/opencode`
|
||||||
|
|
||||||
export async function wait(fn: () => boolean, timeout = 2000) {
|
export async function wait(fn: () => boolean, timeout = 2000) {
|
||||||
|
|
@ -27,11 +27,7 @@ export function json(data: unknown, init?: ResponseInit) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function eventSource(): EventSource {
|
function createEventSource() {
|
||||||
return { subscribe: async () => () => {} }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createEventSource() {
|
|
||||||
let fn: ((event: GlobalEvent) => void) | undefined
|
let fn: ((event: GlobalEvent) => void) | undefined
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -52,7 +48,7 @@ export function createEventSource() {
|
||||||
|
|
||||||
type FetchHandler = (url: URL) => Response | Promise<Response> | undefined
|
type FetchHandler = (url: URL) => Response | Promise<Response> | undefined
|
||||||
|
|
||||||
export function createFetch(override?: FetchHandler) {
|
function createFetch(override?: FetchHandler) {
|
||||||
const session = [] as URL[]
|
const session = [] as URL[]
|
||||||
const fetch = (async (input: RequestInfo | URL) => {
|
const fetch = (async (input: RequestInfo | URL) => {
|
||||||
const url = new URL(input instanceof Request ? input.url : String(input))
|
const url = new URL(input instanceof Request ? input.url : String(input))
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ type ResolvedInput = Omit<TuiConfig.Resolved, "attention" | "keybinds" | "leader
|
||||||
leader_timeout?: number
|
leader_timeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTuiResolvedKeybinds(input: Partial<TuiKeybind.Keybinds> = {}): TuiConfig.Resolved["keybinds"] {
|
function createTuiResolvedKeybinds(input: Partial<TuiKeybind.Keybinds> = {}): TuiConfig.Resolved["keybinds"] {
|
||||||
const keybinds = TuiKeybind.Keybinds.parse(input)
|
const keybinds = TuiKeybind.Keybinds.parse(input)
|
||||||
return createBindingLookup(TuiKeybind.toBindingConfig(keybinds), {
|
return createBindingLookup(TuiKeybind.toBindingConfig(keybinds), {
|
||||||
commandMap: TuiKeybind.CommandMap,
|
commandMap: TuiKeybind.CommandMap,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import { it } from "./effect"
|
||||||
const opencodeRoot = path.resolve(import.meta.dir, "../../")
|
const opencodeRoot = path.resolve(import.meta.dir, "../../")
|
||||||
const cliEntry = path.join(opencodeRoot, "src/index.ts")
|
const cliEntry = path.join(opencodeRoot, "src/index.ts")
|
||||||
|
|
||||||
export const testModelID = "test/test-model"
|
const testModelID = "test/test-model"
|
||||||
|
|
||||||
// Wrap a Bun subprocess pipe (or any ReadableStream<Uint8Array>) as a Stream.
|
// Wrap a Bun subprocess pipe (or any ReadableStream<Uint8Array>) as a Stream.
|
||||||
// Centralizes the `evaluate` + `onError` boilerplate and tags errors with the
|
// Centralizes the `evaluate` + `onError` boilerplate and tags errors with the
|
||||||
|
|
@ -177,7 +177,7 @@ export type CliFixture = {
|
||||||
// up the tmpdir on scope exit. TestLLMServer.layer is provided internally so
|
// up the tmpdir on scope exit. TestLLMServer.layer is provided internally so
|
||||||
// the caller doesn't need to wire it up — the fixture's lifetime is tied to
|
// the caller doesn't need to wire it up — the fixture's lifetime is tied to
|
||||||
// the surrounding Scope.
|
// the surrounding Scope.
|
||||||
export function withCliFixture<A, E>(
|
function withCliFixture<A, E>(
|
||||||
fn: (input: CliFixture) => Effect.Effect<A, E, Scope.Scope | HttpClient.HttpClient>,
|
fn: (input: CliFixture) => Effect.Effect<A, E, Scope.Scope | HttpClient.HttpClient>,
|
||||||
): Effect.Effect<A, E | unknown, Scope.Scope> {
|
): Effect.Effect<A, E | unknown, Scope.Scope> {
|
||||||
return Effect.gen(function* () {
|
return Effect.gen(function* () {
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,7 @@ function fail(item: HttpError) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Reply {
|
class Reply {
|
||||||
#head: unknown[] = [role()]
|
#head: unknown[] = [role()]
|
||||||
#tail: unknown[] = []
|
#tail: unknown[] = []
|
||||||
#usage: Usage | undefined
|
#usage: Usage | undefined
|
||||||
|
|
@ -557,7 +557,7 @@ export function reply() {
|
||||||
return new Reply()
|
return new Reply()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function httpError(status: number, body: unknown): Item {
|
function httpError(status: number, body: unknown): Item {
|
||||||
return {
|
return {
|
||||||
type: "http-error",
|
type: "http-error",
|
||||||
status,
|
status,
|
||||||
|
|
|
||||||
|
|
@ -21,25 +21,16 @@ const REAL_TMP = fs.realpathSync(TMP)
|
||||||
* snapshots captured on macOS/Linux contain LF, so a Windows run without
|
* snapshots captured on macOS/Linux contain LF, so a Windows run without
|
||||||
* this step always diffs.
|
* this step always diffs.
|
||||||
*/
|
*/
|
||||||
export function stripCrlf(text: string): string {
|
function stripCrlf(text: string): string {
|
||||||
return text.replaceAll("\r\n", "\n")
|
return text.replaceAll("\r\n", "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts Windows-style `\` separators to POSIX `/` so paths render
|
|
||||||
* identically across OSes. Use for path strings you want stable in a
|
|
||||||
* snapshot, not for filesystem operations.
|
|
||||||
*/
|
|
||||||
export function toPosixPath(p: string): string {
|
|
||||||
return p.replaceAll("\\", "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strips both the OS-level `os.tmpdir()` and its realpath form (macOS
|
* Strips both the OS-level `os.tmpdir()` and its realpath form (macOS
|
||||||
* `/var/folders` → `/private/var/folders`) from text, replacing each
|
* `/var/folders` → `/private/var/folders`) from text, replacing each
|
||||||
* occurrence with `marker` (default `<TMPDIR>`).
|
* occurrence with `marker` (default `<TMPDIR>`).
|
||||||
*/
|
*/
|
||||||
export function withTmpdirStripped(text: string, marker = "<TMPDIR>"): string {
|
function withTmpdirStripped(text: string, marker = "<TMPDIR>"): string {
|
||||||
return text.replaceAll(REAL_TMP, marker).replaceAll(TMP, marker)
|
return text.replaceAll(REAL_TMP, marker).replaceAll(TMP, marker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import type {
|
||||||
RequestSpec,
|
RequestSpec,
|
||||||
ScenarioContext,
|
ScenarioContext,
|
||||||
SeededContext,
|
SeededContext,
|
||||||
TodoScenario,
|
|
||||||
} from "./types"
|
} from "./types"
|
||||||
|
|
||||||
class ScenarioBuilder<S = undefined> {
|
class ScenarioBuilder<S = undefined> {
|
||||||
|
|
@ -186,14 +185,6 @@ export const http = {
|
||||||
ticketBypass: routes("ticket-bypass"),
|
ticketBypass: routes("ticket-bypass"),
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pending = (method: Method, path: string, name: string, reason: string): TodoScenario => ({
|
|
||||||
kind: "todo",
|
|
||||||
method,
|
|
||||||
path,
|
|
||||||
name,
|
|
||||||
reason,
|
|
||||||
})
|
|
||||||
|
|
||||||
export function route(template: string, params: Record<string, string>) {
|
export function route(template: string, params: Record<string, string>) {
|
||||||
return Object.entries(params).reduce(
|
return Object.entries(params).reduce(
|
||||||
(next, [key, value]) => next.replaceAll(`{${key}}`, value).replaceAll(`:${key}`, value),
|
(next, [key, value]) => next.replaceAll(`{${key}}`, value).replaceAll(`:${key}`, value),
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export function parseOptions(args: string[]): Options {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function matches(options: Options, scenario: Scenario) {
|
function matches(options: Options, scenario: Scenario) {
|
||||||
if (!options.include) return true
|
if (!options.include) return true
|
||||||
return (
|
return (
|
||||||
scenario.name.includes(options.include) ||
|
scenario.name.includes(options.include) ||
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import type { MessageV2 } from "../../../src/session/message-v2"
|
||||||
import type { SessionID } from "../../../src/session/schema"
|
import type { SessionID } from "../../../src/session/schema"
|
||||||
|
|
||||||
export const OpenApiMethods = ["get", "post", "put", "delete", "patch"] as const
|
export const OpenApiMethods = ["get", "post", "put", "delete", "patch"] as const
|
||||||
export const Methods = ["GET", "POST", "PUT", "DELETE", "PATCH"] as const
|
const Methods = ["GET", "POST", "PUT", "DELETE", "PATCH"] as const
|
||||||
|
|
||||||
export type Method = (typeof Methods)[number]
|
export type Method = (typeof Methods)[number]
|
||||||
export type OpenApiMethod = (typeof OpenApiMethods)[number]
|
export type OpenApiMethod = (typeof OpenApiMethods)[number]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue