0.3.40 • Published 3d ago
@wzyjs/middle-sdk
Licence
—
Version
0.3.40
Deps
2
Size
36 kB
Vulns
0
Weekly
0
@wzyjs/middle-sdk
Login
业务项目通过 @wzyjs/middle-sdk/login 接入中台登录。
创建 NextAuth 配置
import { createMiddleNextAuthOptions } from '@wzyjs/middle-sdk/login'
export const authOptions = createMiddleNextAuthOptions({
cookiePrefix: 'my-app',
clientId: process.env.MIDDLE_OIDC_CLIENT_ID!,
clientSecret: process.env.MIDDLE_OIDC_CLIENT_SECRET!,
issuer: process.env.MIDDLE_OIDC_ISSUER!,
secret: process.env.NEXTAUTH_SECRET!,
pages: {
signIn: '/auth/signin',
error: '/auth/error',
},
})
配置参数
interface CreateMiddleNextAuthOptions {
// 中台 OAuth client id。
clientId: string
// 中台 OAuth client secret。
clientSecret: string
// 中台站点地址,例如 https://middle.example.com。
issuer: string
// NextAuth secret。
secret: string
// Cookie 名称前缀,用来避免多个业务系统的 NextAuth cookie 冲突。
cookiePrefix?: string
// 是否开启 NextAuth debug 日志。
debug?: boolean
// NextAuth 登录页、错误页等页面配置。
pages?: NextAuthOptions['pages']
// 是否给 NextAuth cookie 添加 secure 标记。
secureCookies?: boolean
}
Session 参数
登录成功后,业务项目可以从 session 里读取这些参数:
session.middleAccessToken
session.app
session.pages
session.permissions
session.roles
补充 Session 类型
NextAuth 默认的 Session 类型不知道 SDK 增加的中台字段。
业务项目如果要在 TypeScript 里安全访问 session.middleAccessToken、session.app、session.pages 等字段,需要补充一次类型声明。
import type { DefaultSession } from 'next-auth'
import type { MiddleNextAuthSessionFields } from '@wzyjs/middle-sdk/login'
declare module 'next-auth' {
interface Session extends MiddleNextAuthSessionFields {
user?: DefaultSession['user'] & {
id?: string
}
}
}
手动刷新权限资料
业务项目需要重新读取中台应用、页面、角色、权限时,可以调用:
import { createMiddleAccessProfileRefreshUpdate } from '@wzyjs/middle-sdk/login'
import { useSession } from 'next-auth/react'
const { update } = useSession()
await update(createMiddleAccessProfileRefreshUpdate())
Page
业务项目通过 @wzyjs/middle-sdk/page 处理中台页面配置。
模块功能
- 把
session.pages里的页面配置解析成菜单可直接使用的数据。 - 自动区分站内路由、iframe 外链、新开窗口外链。
- 提供中台 iframe 承载页组件。
解析菜单页面
import { resolveMiddleMenuPages } from '@wzyjs/middle-sdk/page'
const pathname = usePathname()
const menuItems = resolveMiddleMenuPages(session.pages, {
// iframe 承载页自己的路由地址。
// 当中台页面是外链但不走新开窗口时,SDK 会把它解析成 `/middle?url=...` 这种地址。
iframePagePath: '/middle',
// 当前页面 pathname,用来判断菜单是否处于激活状态。
// 站内路由菜单会拿它和 page.path 对比。
pathname,
// 当前 iframe 承载页里实际打开的外链地址。
// 当 pathname 是 `/middle` 时,SDK 会继续用这个值判断当前激活的是哪个 iframe 菜单。
iframeUrl: searchParams.get('url'),
})
返回结果里的每一项都会带这些字段:
interface MiddleResolvedPage {
href: string
isActive: boolean
isBlank: boolean
isExternal: boolean
isIframe: boolean
isRoute: boolean
page: MiddlePage
rel?: 'noreferrer'
target?: '_blank'
type: 'route' | 'iframe' | 'blank'
}
挂载 iframe 页面
import { Suspense } from 'react'
import { MiddleIframeRoutePage } from '@wzyjs/middle-sdk/page'
export default function MiddlePage() {
return (
<Suspense>
<MiddleIframeRoutePage />
</Suspense>
)
}
默认会从当前地址的 url query 参数读取 iframe 地址,例如 /middle?url=https://example.com。
类型
interface MiddlePage {
icon: string | null
isMenu: boolean
name: string
openMode: 'iframe' | 'blank' | null
path: string
permissions: string[]
}
Proxy
业务项目通过 @wzyjs/middle-sdk/proxy 生成中台代理地址。
生成代理地址
import { createMiddleProxyUrlFactory } from '@wzyjs/middle-sdk/proxy'
const createAppProxyUrl = createMiddleProxyUrlFactory({
appid: 'ertyuertyu',
baseUrl: 'https://middle.example.com',
})
const proxyUrl = createAppProxyUrl('https://example.com/path?a=1')
// https://middle.example.com/api/proxy/my-app?url=https%3A%2F%2Fexample.com%2Fpath%3Fa%3D1
参数
interface CreateMiddleProxyUrlParams {
url: string
appid: string
baseUrl: string
}
interface CreateMiddleProxyUrlFactoryParams {
appid: string
baseUrl: string
}
规则
- 只会代理
http和https地址。 - 已经是
/api/proxy/...的地址会原样返回,不会重复包装。 appid为空时会直接抛错。baseUrl为空时会直接抛错。- 返回值始终是带中台域名的完整代理地址。
Search
业务项目通过 @wzyjs/middle-sdk/search 调用中台搜索能力。
import { createMiddleSearchFactory } from '@wzyjs/middle-sdk/search'
const searchMiddle = createMiddleSearchFactory({
baseUrl: 'https://middle.example.com',
accessToken: async () => session.middleAccessToken!,
})
const results = await searchMiddle({
query: 'OpenAI 最新动态',
source: 'serper',
})
source 支持 serper、minimax、google、searxng、zhihu、weibo 和 baidu,不传时默认使用 serper。搜索接口需要中台登录态。
Upload
业务项目通过 @wzyjs/middle-sdk/upload 上传文件到中台。
JS 上传二进制文件
import { createMiddleUploadFileFactory } from '@wzyjs/middle-sdk/upload'
const uploadMiddleFile = createMiddleUploadFileFactory({
baseUrl: 'https://middle.example.com',
accessToken: 'your-access-token',
})
const result = await uploadMiddleFile({
file: fileInput.files![0],
fileName: 'avatar.png',
mimeType: 'image/png',
business: 'avatar',
})
JS 上传 URL 文件源
import { createMiddleUploadFileFactory } from '@wzyjs/middle-sdk/upload'
const uploadMiddleFile = createMiddleUploadFileFactory({
baseUrl: 'https://middle.example.com',
accessToken: async () => session.middleAccessToken!,
})
const result = await uploadMiddleFile({
type: 'url',
file: 'https://example.com/image.png',
business: 'avatar',
})
给上传组件使用
import { createMiddleUploadPropsFactory } from '@wzyjs/middle-sdk/upload'
const createUploadProps = createMiddleUploadPropsFactory({
baseUrl: 'https://middle.example.com',
accessToken: session.middleAccessToken,
})
<FileUploader
immediateUpload
trigger='button'
showUploadList={false}
{...createUploadProps({ business: 'file' })}
/>
参数
interface CreateMiddleUploadFileFactoryParams {
baseUrl: string
accessToken: string | (() => Promise<string> | string)
}
interface CreateMiddleUploadPropsFactoryParams {
baseUrl: string
accessToken?: string | null
}
interface CreateMiddleUploadPropsParams {
business?: string
}
type MiddleUploadFileInput =
| {
type?: 'file'
file: Blob | ArrayBuffer | Uint8Array
business?: string
fileName?: string
mimeType?: string
}
| {
type: 'url'
file: string
business?: string
fileName?: string
mimeType?: string
}
返回值
interface MiddleUploadedFile {
id: string
name: string
mimeType: string
ext: string
size: number
hash: string
objectKey: string
provider: string
status: string
business: string | null
applicationId: string
creatorId: string
url: string
createdAt: string | Date
updatedAt: string | Date
isDeleted: boolean
}