feat: enable type-aware no-base-to-string rule, fix 56 violations (#22750)
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/nicolo-ribaudo/oxc-project.github.io/refs/heads/json-schema/src/public/.oxlintrc.schema.json",
|
"$schema": "https://raw.githubusercontent.com/nicolo-ribaudo/oxc-project.github.io/refs/heads/json-schema/src/public/.oxlintrc.schema.json",
|
||||||
|
"options": {
|
||||||
|
"typeAware": true
|
||||||
|
},
|
||||||
"categories": {
|
"categories": {
|
||||||
"suspicious": "warn"
|
"suspicious": "warn"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"typescript/no-base-to-string": "warn",
|
||||||
// Effect uses `function*` with Effect.gen/Effect.fnUntraced that don't always yield
|
// Effect uses `function*` with Effect.gen/Effect.fnUntraced that don't always yield
|
||||||
"require-yield": "off",
|
"require-yield": "off",
|
||||||
// SolidJS uses `let ref: T | undefined` for JSX ref bindings assigned at runtime
|
// SolidJS uses `let ref: T | undefined` for JSX ref bindings assigned at runtime
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ const createSessionUrl = action(async (workspaceID: string, returnUrl: string) =
|
|||||||
|
|
||||||
const setUseBalance = action(async (form: FormData) => {
|
const setUseBalance = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const useBalance = form.get("useBalance")?.toString() === "true"
|
const useBalance = (form.get("useBalance") as string | null) === "true"
|
||||||
|
|
||||||
return json(
|
return json(
|
||||||
await withActor(async () => {
|
await withActor(async () => {
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import { formError, localizeError } from "~/lib/form-error"
|
|||||||
|
|
||||||
const setMonthlyLimit = action(async (form: FormData) => {
|
const setMonthlyLimit = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const limit = form.get("limit")?.toString()
|
const limit = form.get("limit") as string | null
|
||||||
if (!limit) return { error: formError.limitRequired }
|
if (!limit) return { error: formError.limitRequired }
|
||||||
const numericLimit = parseInt(limit)
|
const numericLimit = parseInt(limit)
|
||||||
if (numericLimit < 0) return { error: formError.monthlyLimitInvalid }
|
if (numericLimit < 0) return { error: formError.monthlyLimitInvalid }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(
|
return json(
|
||||||
await withActor(
|
await withActor(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { formError, formErrorReloadAmountMin, formErrorReloadTriggerMin, localiz
|
|||||||
|
|
||||||
const reload = action(async (form: FormData) => {
|
const reload = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(await withActor(() => Billing.reload(), workspaceID), {
|
return json(await withActor(() => Billing.reload(), workspaceID), {
|
||||||
revalidate: queryBillingInfo.key,
|
revalidate: queryBillingInfo.key,
|
||||||
@@ -21,11 +21,11 @@ const reload = action(async (form: FormData) => {
|
|||||||
|
|
||||||
const setReload = action(async (form: FormData) => {
|
const setReload = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const reloadValue = form.get("reload")?.toString() === "true"
|
const reloadValue = (form.get("reload") as string | null) === "true"
|
||||||
const amountStr = form.get("reloadAmount")?.toString()
|
const amountStr = form.get("reloadAmount") as string | null
|
||||||
const triggerStr = form.get("reloadTrigger")?.toString()
|
const triggerStr = form.get("reloadTrigger") as string | null
|
||||||
|
|
||||||
const reloadAmount = amountStr && amountStr.trim() !== "" ? parseInt(amountStr) : null
|
const reloadAmount = amountStr && amountStr.trim() !== "" ? parseInt(amountStr) : null
|
||||||
const reloadTrigger = triggerStr && triggerStr.trim() !== "" ? parseInt(triggerStr) : null
|
const reloadTrigger = triggerStr && triggerStr.trim() !== "" ? parseInt(triggerStr) : null
|
||||||
@@ -91,8 +91,8 @@ export function ReloadSection() {
|
|||||||
const info = billingInfo()!
|
const info = billingInfo()!
|
||||||
setStore("show", true)
|
setStore("show", true)
|
||||||
setStore("reload", true)
|
setStore("reload", true)
|
||||||
setStore("reloadAmount", info.reloadAmount.toString())
|
setStore("reloadAmount", String(info.reloadAmount))
|
||||||
setStore("reloadTrigger", info.reloadTrigger.toString())
|
setStore("reloadTrigger", String(info.reloadTrigger))
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
@@ -152,11 +152,11 @@ export function ReloadSection() {
|
|||||||
data-component="input"
|
data-component="input"
|
||||||
name="reloadAmount"
|
name="reloadAmount"
|
||||||
type="number"
|
type="number"
|
||||||
min={billingInfo()?.reloadAmountMin.toString()}
|
min={String(billingInfo()?.reloadAmountMin ?? "")}
|
||||||
step="1"
|
step="1"
|
||||||
value={store.reloadAmount}
|
value={store.reloadAmount}
|
||||||
onInput={(e) => setStore("reloadAmount", e.currentTarget.value)}
|
onInput={(e) => setStore("reloadAmount", e.currentTarget.value)}
|
||||||
placeholder={billingInfo()?.reloadAmount.toString()}
|
placeholder={String(billingInfo()?.reloadAmount ?? "")}
|
||||||
disabled={!store.reload}
|
disabled={!store.reload}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -166,11 +166,11 @@ export function ReloadSection() {
|
|||||||
data-component="input"
|
data-component="input"
|
||||||
name="reloadTrigger"
|
name="reloadTrigger"
|
||||||
type="number"
|
type="number"
|
||||||
min={billingInfo()?.reloadTriggerMin.toString()}
|
min={String(billingInfo()?.reloadTriggerMin ?? "")}
|
||||||
step="1"
|
step="1"
|
||||||
value={store.reloadTrigger}
|
value={store.reloadTrigger}
|
||||||
onInput={(e) => setStore("reloadTrigger", e.currentTarget.value)}
|
onInput={(e) => setStore("reloadTrigger", e.currentTarget.value)}
|
||||||
placeholder={billingInfo()?.reloadTrigger.toString()}
|
placeholder={String(billingInfo()?.reloadTrigger ?? "")}
|
||||||
disabled={!store.reload}
|
disabled={!store.reload}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ const createSessionUrl = action(async (workspaceID: string, returnUrl: string) =
|
|||||||
|
|
||||||
const setLiteUseBalance = action(async (form: FormData) => {
|
const setLiteUseBalance = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const useBalance = form.get("useBalance")?.toString() === "true"
|
const useBalance = (form.get("useBalance") as string | null) === "true"
|
||||||
|
|
||||||
return json(
|
return json(
|
||||||
await withActor(async () => {
|
await withActor(async () => {
|
||||||
|
|||||||
@@ -12,18 +12,18 @@ import { formError, localizeError } from "~/lib/form-error"
|
|||||||
|
|
||||||
const removeKey = action(async (form: FormData) => {
|
const removeKey = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const id = form.get("id")?.toString()
|
const id = form.get("id") as string | null
|
||||||
if (!id) return { error: formError.idRequired }
|
if (!id) return { error: formError.idRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(await withActor(() => Key.remove({ id }), workspaceID), { revalidate: listKeys.key })
|
return json(await withActor(() => Key.remove({ id }), workspaceID), { revalidate: listKeys.key })
|
||||||
}, "key.remove")
|
}, "key.remove")
|
||||||
|
|
||||||
const createKey = action(async (form: FormData) => {
|
const createKey = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const name = form.get("name")?.toString().trim()
|
const name = (form.get("name") as string | null)?.trim()
|
||||||
if (!name) return { error: formError.nameRequired }
|
if (!name) return { error: formError.nameRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(
|
return json(
|
||||||
await withActor(
|
await withActor(
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ const listMembers = query(async (workspaceID: string) => {
|
|||||||
|
|
||||||
const inviteMember = action(async (form: FormData) => {
|
const inviteMember = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const email = form.get("email")?.toString().trim()
|
const email = (form.get("email") as string | null)?.trim()
|
||||||
if (!email) return { error: formError.emailRequired }
|
if (!email) return { error: formError.emailRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const role = form.get("role")?.toString() as (typeof UserRole)[number]
|
const role = form.get("role") as (typeof UserRole)[number] | null
|
||||||
if (!role) return { error: formError.roleRequired }
|
if (!role) return { error: formError.roleRequired }
|
||||||
const limit = form.get("limit")?.toString()
|
const limit = form.get("limit") as string | null
|
||||||
const monthlyLimit = limit && limit.trim() !== "" ? parseInt(limit) : null
|
const monthlyLimit = limit && limit.trim() !== "" ? parseInt(limit) : null
|
||||||
if (monthlyLimit !== null && monthlyLimit < 0) return { error: formError.monthlyLimitInvalid }
|
if (monthlyLimit !== null && monthlyLimit < 0) return { error: formError.monthlyLimitInvalid }
|
||||||
return json(
|
return json(
|
||||||
@@ -47,9 +47,9 @@ const inviteMember = action(async (form: FormData) => {
|
|||||||
|
|
||||||
const removeMember = action(async (form: FormData) => {
|
const removeMember = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const id = form.get("id")?.toString()
|
const id = form.get("id") as string | null
|
||||||
if (!id) return { error: formError.idRequired }
|
if (!id) return { error: formError.idRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(
|
return json(
|
||||||
await withActor(
|
await withActor(
|
||||||
@@ -66,13 +66,13 @@ const removeMember = action(async (form: FormData) => {
|
|||||||
const updateMember = action(async (form: FormData) => {
|
const updateMember = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
|
|
||||||
const id = form.get("id")?.toString()
|
const id = form.get("id") as string | null
|
||||||
if (!id) return { error: formError.idRequired }
|
if (!id) return { error: formError.idRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const role = form.get("role")?.toString() as (typeof UserRole)[number]
|
const role = form.get("role") as (typeof UserRole)[number] | null
|
||||||
if (!role) return { error: formError.roleRequired }
|
if (!role) return { error: formError.roleRequired }
|
||||||
const limit = form.get("limit")?.toString()
|
const limit = form.get("limit") as string | null
|
||||||
const monthlyLimit = limit && limit.trim() !== "" ? parseInt(limit) : null
|
const monthlyLimit = limit && limit.trim() !== "" ? parseInt(limit) : null
|
||||||
if (monthlyLimit !== null && monthlyLimit < 0) return { error: formError.monthlyLimitInvalid }
|
if (monthlyLimit !== null && monthlyLimit < 0) return { error: formError.monthlyLimitInvalid }
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ function MemberRow(props: {
|
|||||||
}
|
}
|
||||||
setStore("editing", true)
|
setStore("editing", true)
|
||||||
setStore("selectedRole", props.member.role)
|
setStore("selectedRole", props.member.role)
|
||||||
setStore("limit", props.member.monthlyLimit?.toString() ?? "")
|
setStore("limit", props.member.monthlyLimit != null ? String(props.member.monthlyLimit) : "")
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ const getModelsInfo = query(async (workspaceID: string) => {
|
|||||||
|
|
||||||
const updateModel = action(async (form: FormData) => {
|
const updateModel = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const model = form.get("model")?.toString()
|
const model = form.get("model") as string | null
|
||||||
if (!model) return { error: formError.modelRequired }
|
if (!model) return { error: formError.modelRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
const enabled = form.get("enabled")?.toString() === "true"
|
const enabled = (form.get("enabled") as string | null) === "true"
|
||||||
return json(
|
return json(
|
||||||
withActor(async () => {
|
withActor(async () => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
@@ -163,7 +163,7 @@ export function ModelSection() {
|
|||||||
<form action={updateModel} method="post">
|
<form action={updateModel} method="post">
|
||||||
<input type="hidden" name="model" value={id} />
|
<input type="hidden" name="model" value={id} />
|
||||||
<input type="hidden" name="workspaceID" value={params.id} />
|
<input type="hidden" name="workspaceID" value={params.id} />
|
||||||
<input type="hidden" name="enabled" value={isEnabled().toString()} />
|
<input type="hidden" name="enabled" value={String(isEnabled())} />
|
||||||
<label data-slot="model-toggle-label">
|
<label data-slot="model-toggle-label">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ function maskCredentials(credentials: string) {
|
|||||||
|
|
||||||
const removeProvider = action(async (form: FormData) => {
|
const removeProvider = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const provider = form.get("provider")?.toString()
|
const provider = form.get("provider") as string | null
|
||||||
if (!provider) return { error: formError.providerRequired }
|
if (!provider) return { error: formError.providerRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(await withActor(() => Provider.remove({ provider }), workspaceID), {
|
return json(await withActor(() => Provider.remove({ provider }), workspaceID), {
|
||||||
revalidate: listProviders.key,
|
revalidate: listProviders.key,
|
||||||
@@ -32,11 +32,11 @@ const removeProvider = action(async (form: FormData) => {
|
|||||||
|
|
||||||
const saveProvider = action(async (form: FormData) => {
|
const saveProvider = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const provider = form.get("provider")?.toString()
|
const provider = form.get("provider") as string | null
|
||||||
const credentials = form.get("credentials")?.toString()
|
const credentials = form.get("credentials") as string | null
|
||||||
if (!provider) return { error: formError.providerRequired }
|
if (!provider) return { error: formError.providerRequired }
|
||||||
if (!credentials) return { error: formError.apiKeyRequired }
|
if (!credentials) return { error: formError.apiKeyRequired }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(
|
return json(
|
||||||
await withActor(
|
await withActor(
|
||||||
@@ -59,10 +59,13 @@ function ProviderRow(props: { provider: Provider }) {
|
|||||||
const params = useParams()
|
const params = useParams()
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const providers = createAsync(() => listProviders(params.id!))
|
const providers = createAsync(() => listProviders(params.id!))
|
||||||
const saveSubmission = useSubmission(saveProvider, ([fd]) => fd.get("provider")?.toString() === props.provider.key)
|
const saveSubmission = useSubmission(
|
||||||
|
saveProvider,
|
||||||
|
([fd]) => (fd.get("provider") as string | null) === props.provider.key,
|
||||||
|
)
|
||||||
const removeSubmission = useSubmission(
|
const removeSubmission = useSubmission(
|
||||||
removeProvider,
|
removeProvider,
|
||||||
([fd]) => fd.get("provider")?.toString() === props.provider.key,
|
([fd]) => (fd.get("provider") as string | null) === props.provider.key,
|
||||||
)
|
)
|
||||||
const [store, setStore] = createStore({ editing: false })
|
const [store, setStore] = createStore({ editing: false })
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ const getWorkspaceInfo = query(async (workspaceID: string) => {
|
|||||||
|
|
||||||
const updateWorkspace = action(async (form: FormData) => {
|
const updateWorkspace = action(async (form: FormData) => {
|
||||||
"use server"
|
"use server"
|
||||||
const name = form.get("name")?.toString().trim()
|
const name = (form.get("name") as string | null)?.trim()
|
||||||
if (!name) return { error: formError.workspaceNameRequired }
|
if (!name) return { error: formError.workspaceNameRequired }
|
||||||
if (name.length > 255) return { error: formError.nameTooLong }
|
if (name.length > 255) return { error: formError.nameTooLong }
|
||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID") as string | null
|
||||||
if (!workspaceID) return { error: formError.workspaceRequired }
|
if (!workspaceID) return { error: formError.workspaceRequired }
|
||||||
return json(
|
return json(
|
||||||
await withActor(
|
await withActor(
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ function generate(schema: z.ZodType) {
|
|||||||
schema.examples = [schema.default]
|
schema.examples = [schema.default]
|
||||||
}
|
}
|
||||||
|
|
||||||
schema.description = [schema.description || "", `default: \`${schema.default}\``]
|
schema.description = [schema.description || "", `default: \`${String(schema.default)}\``]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n\n")
|
.join("\n\n")
|
||||||
.trim()
|
.trim()
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ const clean = (input?: Fields): Fields =>
|
|||||||
Object.fromEntries(Object.entries(input ?? {}).filter((entry) => entry[1] !== undefined && entry[1] !== null))
|
Object.fromEntries(Object.entries(input ?? {}).filter((entry) => entry[1] !== undefined && entry[1] !== null))
|
||||||
|
|
||||||
const text = (input: unknown): string => {
|
const text = (input: unknown): string => {
|
||||||
|
// oxlint-disable-next-line no-base-to-string
|
||||||
if (Array.isArray(input)) return input.map((item) => String(item)).join(" ")
|
if (Array.isArray(input)) return input.map((item) => String(item)).join(" ")
|
||||||
|
// oxlint-disable-next-line no-base-to-string
|
||||||
return input === undefined ? "" : String(input)
|
return input === undefined ? "" : String(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
|
|||||||
const info = await getAuth()
|
const info = await getAuth()
|
||||||
if (info.type !== "oauth") return fetch(request, init)
|
if (info.type !== "oauth") return fetch(request, init)
|
||||||
|
|
||||||
const url = request instanceof URL ? request.href : request.toString()
|
const url = request instanceof URL ? request.href : typeof request === "string" ? request : request.url
|
||||||
const { isVision, isAgent } = iife(() => {
|
const { isVision, isAgent } = iife(() => {
|
||||||
try {
|
try {
|
||||||
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body
|
const body = typeof init?.body === "string" ? JSON.parse(init.body) : init?.body
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ export namespace ProviderTransform {
|
|||||||
|
|
||||||
// Check for empty base64 image data
|
// Check for empty base64 image data
|
||||||
if (part.type === "image") {
|
if (part.type === "image") {
|
||||||
const imageStr = part.image.toString()
|
const imageStr = String(part.image)
|
||||||
if (imageStr.startsWith("data:")) {
|
if (imageStr.startsWith("data:")) {
|
||||||
const match = imageStr.match(/^data:([^;]+);base64,(.*)$/)
|
const match = imageStr.match(/^data:([^;]+);base64,(.*)$/)
|
||||||
if (match && (!match[2] || match[2].length === 0)) {
|
if (match && (!match[2] || match[2].length === 0)) {
|
||||||
@@ -286,7 +286,7 @@ export namespace ProviderTransform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mime = part.type === "image" ? part.image.toString().split(";")[0].replace("data:", "") : part.mediaType
|
const mime = part.type === "image" ? String(part.image).split(";")[0].replace("data:", "") : part.mediaType
|
||||||
const filename = part.type === "file" ? part.filename : undefined
|
const filename = part.type === "file" ? part.filename : undefined
|
||||||
const modality = mimeToModality(mime)
|
const modality = mimeToModality(mime)
|
||||||
if (!modality) return part
|
if (!modality) return part
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ export const layer = Layer.effect(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
onMessage: (message: string | ArrayBuffer) => {
|
onMessage: (message: string | ArrayBuffer) => {
|
||||||
session.process.write(String(message))
|
session.process.write(typeof message === "string" ? message : new TextDecoder().decode(message))
|
||||||
},
|
},
|
||||||
onClose: () => {
|
onClose: () => {
|
||||||
log.info("client disconnected from session", { id })
|
log.info("client disconnected from session", { id })
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export const layer: Layer.Layer<
|
|||||||
Effect.succeed({
|
Effect.succeed({
|
||||||
code: ChildProcessSpawner.ExitCode(1),
|
code: ChildProcessSpawner.ExitCode(1),
|
||||||
text: "",
|
text: "",
|
||||||
stderr: String(err),
|
stderr: err instanceof Error ? err.message : String(err),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -145,7 +145,15 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
case "delete": {
|
case "delete": {
|
||||||
const contentToDelete = yield* afs
|
const contentToDelete = yield* afs
|
||||||
.readFileString(filePath)
|
.readFileString(filePath)
|
||||||
.pipe(Effect.catch((error) => Effect.fail(new Error(`apply_patch verification failed: ${error}`))))
|
.pipe(
|
||||||
|
Effect.catch((error) =>
|
||||||
|
Effect.fail(
|
||||||
|
new Error(
|
||||||
|
`apply_patch verification failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
const deleteDiff = trimDiff(createTwoFilesPatch(filePath, filePath, contentToDelete, ""))
|
const deleteDiff = trimDiff(createTwoFilesPatch(filePath, filePath, contentToDelete, ""))
|
||||||
|
|
||||||
const deletions = contentToDelete.split("\n").length
|
const deletions = contentToDelete.split("\n").length
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export function errorData(error: unknown) {
|
|||||||
acc[key] = value
|
acc[key] = value
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- intentional coercion of arbitrary error properties
|
||||||
acc[key] = value instanceof Error ? value.message : String(value)
|
acc[key] = value instanceof Error ? value.message : String(value)
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ export namespace SessionEntry {
|
|||||||
case "tool.input.delta": {
|
case "tool.input.delta": {
|
||||||
if (!pendingAssistant) break
|
if (!pendingAssistant) break
|
||||||
const match = pendingAssistant.content.findLast((x) => x.type === "tool")
|
const match = pendingAssistant.content.findLast((x) => x.type === "tool")
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- event.delta is a Schema.String (runtime string)
|
||||||
if (match) match.state.input += event.delta
|
if (match) match.state.input += event.delta
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1801,7 +1801,7 @@ test("project config overrides remote well-known config", async () => {
|
|||||||
const originalFetch = globalThis.fetch
|
const originalFetch = globalThis.fetch
|
||||||
let fetchedUrl: string | undefined
|
let fetchedUrl: string | undefined
|
||||||
globalThis.fetch = mock((url: string | URL | Request) => {
|
globalThis.fetch = mock((url: string | URL | Request) => {
|
||||||
const urlStr = url.toString()
|
const urlStr = url instanceof Request ? url.url : url instanceof URL ? url.href : url
|
||||||
if (urlStr.includes(".well-known/opencode")) {
|
if (urlStr.includes(".well-known/opencode")) {
|
||||||
fetchedUrl = urlStr
|
fetchedUrl = urlStr
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
@@ -1858,7 +1858,7 @@ test("wellknown URL with trailing slash is normalized", async () => {
|
|||||||
const originalFetch = globalThis.fetch
|
const originalFetch = globalThis.fetch
|
||||||
let fetchedUrl: string | undefined
|
let fetchedUrl: string | undefined
|
||||||
globalThis.fetch = mock((url: string | URL | Request) => {
|
globalThis.fetch = mock((url: string | URL | Request) => {
|
||||||
const urlStr = url.toString()
|
const urlStr = url instanceof Request ? url.url : url instanceof URL ? url.href : url
|
||||||
if (urlStr.includes(".well-known/opencode")) {
|
if (urlStr.includes(".well-known/opencode")) {
|
||||||
fetchedUrl = urlStr
|
fetchedUrl = urlStr
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const TRANSIENT_MESSAGES = [
|
|||||||
|
|
||||||
function isTransientError(error: unknown): boolean {
|
function isTransientError(error: unknown): boolean {
|
||||||
if (!error) return false
|
if (!error) return false
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- error is unknown, intentional coercion for message matching
|
||||||
const message = String(error instanceof Error ? error.message : error).toLowerCase()
|
const message = String(error instanceof Error ? error.message : error).toLowerCase()
|
||||||
return TRANSIENT_MESSAGES.some((m) => message.includes(m))
|
return TRANSIENT_MESSAGES.some((m) => message.includes(m))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,6 +317,7 @@ describe("util.effect-flock", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const result = yield* flock.withLock(Effect.void, "eflock:perm", dir).pipe(Effect.exit)
|
const result = yield* flock.withLock(Effect.void, "eflock:perm", dir).pipe(Effect.exit)
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- Exit has a useful toString for test assertions
|
||||||
expect(String(result)).toContain("PermissionDenied")
|
expect(String(result)).toContain("PermissionDenied")
|
||||||
yield* Effect.promise(() => fs.chmod(dir, 0o700).then(() => fs.rm(tmp, { recursive: true, force: true })))
|
yield* Effect.promise(() => fs.chmod(dir, 0o700).then(() => fs.rm(tmp, { recursive: true, force: true })))
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ function render(template: string, params?: Record<string, unknown>) {
|
|||||||
return template.replace(/\{\{([^}]+)\}\}/g, (_, key: string) => {
|
return template.replace(/\{\{([^}]+)\}\}/g, (_, key: string) => {
|
||||||
const value = params[key.trim()]
|
const value = params[key.trim()]
|
||||||
if (value === undefined || value === null) return ""
|
if (value === undefined || value === null) return ""
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- value is Record<string, unknown>, always coerced intentionally
|
||||||
return String(value)
|
return String(value)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -698,6 +698,7 @@ function TextViewer<T>(props: TextFileProps<T>) {
|
|||||||
if (typeof value === "string") return value
|
if (typeof value === "string") return value
|
||||||
if (Array.isArray(value)) return value.join("\n")
|
if (Array.isArray(value)) return value.join("\n")
|
||||||
if (value == null) return ""
|
if (value == null) return ""
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- file contents cast to unknown, coercion is intentional
|
||||||
return String(value)
|
return String(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,11 +713,13 @@ function TextViewer<T>(props: TextFileProps<T>) {
|
|||||||
if (typeof value === "string") return value.length
|
if (typeof value === "string") return value.length
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value.reduce(
|
return value.reduce(
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- array parts coerced intentionally
|
||||||
(sum, part) => sum + (typeof part === "string" ? part.length + 1 : String(part).length + 1),
|
(sum, part) => sum + (typeof part === "string" ? part.length + 1 : String(part).length + 1),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (value == null) return 0
|
if (value == null) return 0
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- file contents cast to unknown, coercion is intentional
|
||||||
return String(value).length
|
return String(value).length
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ export function SessionTurn(
|
|||||||
const msg = error()?.data?.message
|
const msg = error()?.data?.message
|
||||||
if (typeof msg === "string") return unwrap(msg)
|
if (typeof msg === "string") return unwrap(msg)
|
||||||
if (msg === undefined || msg === null) return ""
|
if (msg === undefined || msg === null) return ""
|
||||||
|
// oxlint-disable-next-line no-base-to-string -- msg is unknown from error data, coercion is intentional
|
||||||
return unwrap(String(msg))
|
return unwrap(String(msg))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -730,7 +730,13 @@ export function FallbackTool(props: ToolProps) {
|
|||||||
<>
|
<>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div>{arg[0]}</div>
|
<div>{arg[0]}</div>
|
||||||
<div>{String(arg[1] ?? "")}</div>
|
<div>
|
||||||
|
{typeof arg[1] === "string" || typeof arg[1] === "number" || typeof arg[1] === "boolean"
|
||||||
|
? String(arg[1])
|
||||||
|
: arg[1] == null
|
||||||
|
? ""
|
||||||
|
: JSON.stringify(arg[1])}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|||||||
Reference in New Issue
Block a user