orpc-contract-first by langgenius/dify
npx skills add https://github.com/langgenius/dify --skill orpc-contract-firstweb/contract/* 中。useQuery(consoleQuery|marketplaceQuery.xxx.queryOptions(...))。web/contract/
├── base.ts
├── router.ts
├── marketplace.ts
└── console/
├── billing.ts
└── ...其他领域
web/service/client.ts
web/contract/console/{domain}.ts 或 web/contract/marketplace.ts 中定义契约
base.route({...}).output(type<...>()) 作为基线。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
params/query/body 时添加 .input(type<...>())。GET 请求,省略 .input(...)(不要使用 .input(type<unknown>()))。web/contract/router.ts 中注册契约
import { useQuery } from '@tanstack/react-query'
import { consoleQuery } from '@/service/client'
const invoiceQuery = useQuery(consoleQuery.billing.invoices.queryOptions({
staleTime: 5 * 60 * 1000,
throwOnError: true,
select: invoice => invoice.url,
}))
*.queryOptions(...)。retry: false),提取一个小的 queryOptions 辅助函数,而不是 use-* 透传钩子。web/service/use-{domain}.ts:
const invoicesBaseQueryOptions = () =>
consoleQuery.billing.invoices.queryOptions({ retry: false })
const invoiceQuery = useQuery({
...invoicesBaseQueryOptions(),
throwOnError: true,
})
consoleQuery / marketplaceQuery 调用变更辅助函数,例如 useMutation(consoleQuery.billing.bindPartnerStack.mutationOptions(...))。mutationFn(例如 consoleClient.xxx / marketplaceClient.xxx),而不是通用的手写非 oRPC 变更逻辑。.key vs .queryKey vs .mutationKey).key(...):
queryClient.invalidateQueries({ queryKey: consoleQuery.billing.key() }).queryKey(...):
.mutationKey(...):
useIsMutating、queryClient.isMutating)或显式的开发者工具分组。options?: Partial<UseQueryOptions> 包装 useQuery。queryOptions 已存在且符合用例时,不要拆分本地的 queryKey/queryFn。use-* 透传钩子。data 可能变成 unknown,尤其是在 throwOnError/select 周围),并增加不必要的间接层。{ params, query?, body? } 格式.input(...);不要使用 .input(type<unknown>()){paramName},在 params 对象中匹配/billing/* -> billing: {})@/types/ 导入,使用 type<T>() 辅助函数mutationOptions;主要将显式的 mutationKey 用于默认值/过滤/开发者工具export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>
每周安装量
712
代码仓库
GitHub 星标
134.6K
首次出现
2026年1月20日
安全审计
安装于
claude-code529
gemini-cli484
cursor465
opencode460
antigravity414
codex413
web/contract/*.useQuery(consoleQuery|marketplaceQuery.xxx.queryOptions(...)) when endpoint behavior maps 1:1 to the contract.web/contract/
├── base.ts
├── router.ts
├── marketplace.ts
└── console/
├── billing.ts
└── ...other domains
web/service/client.ts
web/contract/console/{domain}.ts or web/contract/marketplace.ts
base.route({...}).output(type<...>()) as baseline..input(type<...>()) only when request has params/query/body.GET without input, omit .input(...) (do not use .input(type<unknown>())).web/contract/router.ts
import { useQuery } from '@tanstack/react-query'
import { consoleQuery } from '@/service/client'
const invoiceQuery = useQuery(consoleQuery.billing.invoices.queryOptions({
staleTime: 5 * 60 * 1000,
throwOnError: true,
select: invoice => invoice.url,
}))
*.queryOptions(...).retry: false), extract a small queryOptions helper, not a use-* passthrough hook.web/service/use-{domain}.ts only for orchestration:
const invoicesBaseQueryOptions = () =>
consoleQuery.billing.invoices.queryOptions({ retry: false })
const invoiceQuery = useQuery({
...invoicesBaseQueryOptions(),
throwOnError: true,
})
consoleQuery / marketplaceQuery, for example useMutation(consoleQuery.billing.bindPartnerStack.mutationOptions(...)).mutationFn (for example consoleClient.xxx / marketplaceClient.xxx), instead of generic handwritten non-oRPC mutation logic..key vs .queryKey vs .mutationKey).key(...):
queryClient.invalidateQueries({ queryKey: consoleQuery.billing.key() }).queryKey(...):
.mutationKey(...):
useIsMutating, queryClient.isMutating), or explicit devtools grouping.useQuery with options?: Partial<UseQueryOptions>.queryKey/queryFn when oRPC queryOptions already exists and fits the use case.use-* passthrough hooks for a single endpoint.data may become unknown, especially around throwOnError/select) and add unnecessary indirection.{ params, query?, body? } format.input(...); do not use .input(type<unknown>()){paramName} in path, match in params object/billing/* -> billing: {})@/types/, use type<T>() helperexport type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>
Weekly Installs
712
Repository
GitHub Stars
134.6K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code529
gemini-cli484
cursor465
opencode460
antigravity414
codex413
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
136,300 周安装
mutationOptions; use explicit mutationKey mainly for defaults/filtering/devtools