@ eazo/ sdk (英语)
能力第一SDK用于同时运行在标准浏览器上和Eazo Mobile Webview内部的网络应用. 写入一个代码库;SDK为运行时间选择正确的执行.
安装
npm install @eazo/sdk
快开始
// app/layout.tsx
import { EazoProvider } from "@eazo/sdk/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return <EazoProvider>{children}</EazoProvider>;
}
// Any component
import { auth } from "@eazo/sdk";
import { useEazo } from "@eazo/sdk/react";
export function Header() {
const user = useEazo((s) => s.auth.user);
if (!user) return <button onClick={() => auth.loginWithSocial("google")}>Sign in</button>;
return <span>Hi, {user.name}</span>;
}
API 密码
auth
import { auth } from "@eazo/sdk";
auth.user // User | null
auth.loading // boolean
auth.authenticated // boolean
auth.loginUIOpen // boolean (web login UI)
await auth.getToken() // string | null
auth.onChange((user) => { ... }) // () => void (unsubscribe)
// One-stop login — handles every runtime and idempotent if already signed in.
const user = await auth.login() // User
await auth.login({ timeoutMs: 120_000 }) // custom timeout (default: 5 min)
auth.showLogin() // imperative open (no await)
auth.hideLogin() // imperative close (rejects pending login())
// Low-level login primitives (rarely needed; `login()` orchestrates these).
await auth.loginWithSocial("google")
await auth.loginWithEmailPassword(email, password)
await auth.loginWithEmailCode(email, code)
await auth.sendEmailCode(email)
await auth.logout()
auth.fetchSocialConnections() // SocialConnection[]
auth.login() ——统一登录流量
auth.login() 是签入用户的卡通方式。 它会:
- 如果已经认证, 立即返回当前用户( 参数) .
- 在Eazo Mobile上(主机广告)
auth.requestLogin),本地主机登录UI的代表. - 否则,显示SDK捆绑的登录模式(社会提供者+电子邮件/代码/密码).
<button onClick={async () => {
await auth.login();
doSomethingProtected();
}}>
Do something
</button>
它拒绝 DENIED 如果用户取消,或 TIMEOUT 5分钟后不活动(通过配置) timeoutMs) (中文(简体) ).
device
import { device } from "@eazo/sdk";
device.platform // 'web' | 'mobile'
device.locale // 'zh-CN' | ...
device.getContext() // full DeviceContext
边缘到边缘布局和安全区域
Eazo Mobile 礼物主机应用程序边缘到边缘 viewport-fit=cover打开
iOS, WebKit 通过本地值发布 env(safe-area-inset-*)。 。 。 .
EazoProvider 不在 Mobile 中移动或挂载主机应用程序内容:背景
可见文本和控件必须使用
模板解决 --safe-* 变量(或 env() 直接在应用中进行
不使用模板).
share
手相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 在Eazo Mobile Webview内部,主机打开了它的原生作曲页面,AI从输入中起草一个帖子,让用户编辑并发布;在一个平版浏览器中,SDK显示一个"在Eazo app中继续"的CTA指向 https://eazo.ai/ (英语)。 。 。 .
import { share } from "@eazo/sdk";
await share.compose({
text: "Made carbonara tonight — first time the egg didn't scramble.",
attachments: [
{
type: "image",
url: "data:image/jpeg;base64,...", // data: or https:
caption: "finished dish photo",
},
],
sourceAppId: "recipe-keeper", // optional attribution
targetPath: "/recipes/carbonara-42", // optional app-internal destination
});
// → { accepted: true } in the mobile app
// → { accepted: false } on the web (download CTA shown)
attachments 目前只支持图像附件。 通过最多4个图像材料总量. images: string[] 但新代码应该更适合 attachments 因此图像可以带有短标题/意思.
targetPath 是可选的, 并告诉 Eazo Mobile 当有人对已公布的共享部件进行窃听时, 在哪里打开源代码应用程序 。 它必须是源应用程序内部的相对路径,例如 /profile/u_123 或者说 /result/abc?tab=summary; 绝对URL被拒绝.
share.compose 掷出 INVALID_ARGS 如果没有同步 text, (中文(简体) ), attachments,或 images 如果超过4个图像材料,则提供.
notifications
Per-app push-Notection订阅,由主办方调解. 呼叫通过Message后桥流到移动 shell, 它写着每个( 用户, app) 位点; 嵌入式应用从不在这里直接与平台交谈 .
import { notifications } from "@eazo/sdk";
const { subscribed } = await notifications.isSubscribed();
if (!subscribed) await notifications.subscribe(); // opt the user in
// later…
await notifications.unsubscribe(); // opt the user out
在普通浏览器中( 没有主机) 每种方法都会解决 { subscribed: false } ——没有抛出——所以在本地网络开发过程中,应用程序可以使正确的UI不作特殊分类.
出版 是一个单独的服务器侧表面——见 @eazo/sdk/server 通知。 。 。 .
反应整合
import { EazoProvider, useEazo } from "@eazo/sdk/react";
规则:在React渲染内,通过 useEazo(selector)外部渲染(事件处理器、效果、非反应代码),直接从 auth.xxx 编号 : device.xxx。 。 。 .
const user = useEazo((s) => s.auth.user);
const { platform, locale } = useEazo((s) => s.device);
访问分析
在顶级浏览器页面上, <EazoProvider> 装入主机
eazo-app-analytics.js
一次与应用代号。 它报告部署领域开放情况,并向
Eazo 平台( 在创建者中心上显示)并发送 $pageview 编号 : $pageleave
与Eazo的PostHog项目 具有相同的匿名归属
品牌旗帜。 它不自动点击或输入,也不记录
届会.
它不装入 Eazo 移动 Webview 或嵌入的 Iframe(那些)
主机报告自己的会话),或于 localhost, (中文(简体) ), *.localhost 财务报告和审定财务报表
*.local 开发主机。 设定 window.EAZO_APP_ANALYTICS = false 在此之前
提供者挂载选择退出。 剧本在CDN上更新,所以更改
报告不需要新的SDK版本.
有严格内容-安全政策需要的应用程序 script-src https://cdn.eazo.ai https://us-assets.i.posthog.com 财务报告和审定财务报表 connect-src https://eazo.ai https://us.i.posthog.com。 。 。 .
服务器( Next.js 路由处理器)
import { requireAuth } from "@eazo/sdk/server";
export function GET(req: NextRequest) {
const r = requireAuth(req);
if (!r.ok) return r.response;
// r.user: User
}
要求数 EAZO_PRIVATE_KEY 在服务器环境中.
notifications.publish
发送一个系统推向每个用户订阅您的应用程序 。 与 ES256K JWT 签署 EAZO_PRIVATE_KEY ——在范围上没有用户JWT,所以这是由克龙驱动的文摘,由事件驱动的提醒,或任何后端发端通知的正确路径.
import { notifications } from "@eazo/sdk/server";
export async function POST() {
const { delivered, publishId } = await notifications.publish({
title: "Slow-cooker timer",
body: "Your stew is ready.",
data: { recipeId: "stew-42" }, // optional, surfaces in the device tap handler
});
return Response.json({ delivered, publishId });
}
audience 默认为 "subscribers" (v1唯一的值).
掷出 EazoNotificationPublishError 关于平台级别错误( q)code 401 = 坏JWT, 403 = appId 不属于你的密钥, 413 = > 5000 订阅者等).
付款
Eazo市场付款通过付款子路径提供。 生成的apps创建了本地的Next.js路由和页面,但平台检出/状态调用则停留在SDK内部.
安装一个与支付SDK兼容的释放,验证依赖性和锁文件, 然后从安装的软件包中取出脚手架:
pnpm add '@eazo/sdk@>=0.22.3'
./node_modules/.bin/eazo-sdk payments doctor --minimum-version 0.22.3
./node_modules/.bin/eazo-sdk payments init --minimum-version 0.22.3 --recipe one-time-unlock
Eazo 生成的应用程序应该使用提供的平台 sdk_package_spec 换成
假设 npm 的公开来源. 0.22.3 是相容层,不是
上行针; 后相容释放, 如 0.23.x 或者说 0.24.x 保留
当需要的付款出口出现时,有效.
生成的文件包括:
src/lib/eazo-payments/catalog.ts
src/components/eazo-payments/PaymentUnlockPanel.tsx
src/app/api/payments/checkout/route.ts
src/app/api/payments/status/route.ts
src/app/api/payments/entitlements/route.ts
src/app/payment/success/page.tsx
src/app/payment/cancel/page.tsx
src/lib/eazo-payments/payment-contract.test.ts
src/lib/eazo-payments/payment-ui-contract.test.tsx
一次付款中的几个项目
一次性付款也可包括几个细列项目,或不止一个
同一项目one-time-items 食谱, @eazo/sdk >=0.23.0:
./node_modules/.bin/eazo-sdk payments init --recipe one-time-items
Eazo为应用定价的线路收取了1个Frede的检查费用(最多100个线路,
5 000美元以下的小计 getEazoItemsMaximumAmount, (中文(简体) ),
应用可选应用程序计算折扣,为每行提供权利
与 entitlementKey,并报告是否付款。 应用程序写
两个功能在 lib/eazo-payments/items.ts数字 :
resolveItems({ lines, data })浏览器的价格{ id, quantity }线条 在服务器上返回{ currency, items, discountAmount?, discountLabel? }, (中文(简体) ), 或者说null拒绝这一要求.fulfillPayment(payment, { user })给予无entitlement_key。它只支付支付款项,必须具备以下条件:payment.payment_id。 。 。 .
它使用与单产品支付相同的路线: createEazoCheckoutRoute({ resolveItems }) (与 getProduct 如果应用程序还销售目录产品,
createEazoPaymentStatusRoute({ fulfill }), (中文(简体) ), /payment/success 财务报告和审定财务报表
/payment/cancel附加时 createEazoPaymentSyncRoute({ fulfill }) 时间
/api/payments/sync 与 PaymentSync 在根的布局中。 浏览器开始
退职 startEazoItemsCheckout(lines, { data })。见
examples/payments/one-time-items。 。 。 .
UI 代码应该设置脚手架组件, 因此要检查、 登录、 状态 投票 和权利状态 停留在SDK拥有的生命周期:
import {
PaymentUnlockPanel,
PremiumEntitlementGate,
} from "@/components/eazo-payments/PaymentUnlockPanel";
<PaymentUnlockPanel productKey="premium" />
<PremiumEntitlementGate
paid={<PremiumExperience />}
free={<UpgradeExperience />}
/>
对于自定义的 UI , 编辑 脚手架面板的标记/ 类/ 文本或使用
EazoPaymentLifecycle 编号 : useEazoPaymentLifecycle(productKey) 从
@eazo/sdk/payments/react。SDK生命周期拥有检查、登录、状态
投票、错误和应享权利更新;应用代码只应使
返回状态.
服务器代码应该使用由 CLI 生成的路由助手 :
import { createEazoCheckoutRoute } from "@eazo/sdk/payments/next";
import { getPaymentProduct } from "@/lib/eazo-payments/catalog";
export const POST = createEazoCheckoutRoute({ getProduct: getPaymentProduct });
完整可复制的Next.js实例见:
examples/payments/one-time-unlock/
这个例子包括产品目录常数,本地路由处理器, 成功/取消页面、概况/升级UI和离职模拟合同测试, 状况、应享待遇和遗产流程回归检查.
不要添加 Frede SDKs , Frede webhoks , 并添加 Frede webhoks , STRIPE_SECRET_KEY直接
/api/open/payments/* 请求机构,或 本地Storage 单溢价状态
生成的应用程序 。 退出使用同窗导航,确认付款方式
投票 Eazo 分类账在 Stale 返回后使用 payment_id刷新时
平台拥有的权益在支付UI之前就已生效.
测试
import { __resetSDK, __dispatchHostMessage } from "@eazo/sdk/testing";
afterEach(() => __resetSDK());
类型
interface User {
id: string;
email: string | null;
name: string | null;
avatarUrl: string | null;
}
interface DeviceContext {
platform: "web" | "mobile";
locale: string;
}
如何运作
SDK跟Eazo移动主机谈 postMessage 使用 议定书.md当主机在1.5秒内没有回复时,SDK会回归到网络本土执行(GenAuth用于登录, localStorage 届会, navigator.language (关于当地人).
App代码从不在环境上分出——两个平台的能力API都是一样的.
环境
| 变量 | 需求 | 用于 |
|---|---|---|
EAZO_APP_ID | 对 | App ID; 自动解决 <EazoProvider>。 。 。 . |
EAZO_API_BASE | 对 | Eazo 平台基础; 支付服务器助手生成创建器 /creator 基地从它. |
EAZO_PLATFORM_API_BASE | 选项 | 覆盖 Eazo 平台基础 URL( 默认为 https://eazo.ai) (中文(简体) ). |
EAZO_PRIVATE_KEY | 服务器 | requireAuth, (中文(简体) ), notifications.publish,支付结账/状态路线 |