facebetter 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -26
- package/dist/facebetter.esm.js +260 -270
- package/dist/facebetter.esm.js.map +1 -1
- package/dist/facebetter.js +260 -261
- package/dist/facebetter.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -46,7 +46,13 @@ For direct browser usage.
|
|
|
46
46
|
<script src="https://cdn.jsdelivr.net/npm/facebetter/dist/facebetter.js"></script>
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
The UMD build loads `facebetter-core` from the **same directory** as `facebetter.js`.
|
|
49
|
+
The UMD build loads `facebetter-core` from the **same directory** as `facebetter.js`. Host these next to `facebetter.js`:
|
|
50
|
+
|
|
51
|
+
- `facebetter-core.js`
|
|
52
|
+
- `facebetter-core.wasm`
|
|
53
|
+
- `resource.fbd`
|
|
54
|
+
|
|
55
|
+
A single jsDelivr URL for `facebetter` is not enough. npm + a bundler is simpler.
|
|
50
56
|
|
|
51
57
|
---
|
|
52
58
|
|
|
@@ -54,34 +60,22 @@ The UMD build loads `facebetter-core` from the **same directory** as `facebetter
|
|
|
54
60
|
|
|
55
61
|
### 1. Initialize the Engine
|
|
56
62
|
|
|
57
|
-
Web 必须联网校验。`EngineConfig` **没有** `appId` / `appKey
|
|
63
|
+
Web 必须联网校验。`EngineConfig` **没有** `appId` / `appKey`:由你的服务器换 token,再传入 `licenseToken`。
|
|
58
64
|
|
|
59
65
|
```javascript
|
|
60
66
|
import {
|
|
61
67
|
BeautyEffectEngine,
|
|
62
68
|
EngineConfig,
|
|
63
|
-
createDirectAuthFetcher,
|
|
64
69
|
} from 'facebetter';
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// 方式 B:把 WASM 的 nonce challenge 转发到你的后端(生产推荐)
|
|
72
|
-
const config = new EngineConfig({
|
|
73
|
-
authProxyUrl: '/api/facebetter/auth',
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// 方式 C:本地调试 / 无自己的服务器时,调用处直连 Cloudflare(密钥会出现在前端,不要用于生产)
|
|
77
|
-
const config = new EngineConfig({
|
|
78
|
-
fetchAuthResponse: createDirectAuthFetcher({
|
|
79
|
-
appId: 'your-app-id',
|
|
80
|
-
appKey: 'your-app-key',
|
|
81
|
-
}),
|
|
71
|
+
const licenseToken = await fetch('/api/facebetter/auth', {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
}).then((r) => {
|
|
74
|
+
if (!r.ok) throw new Error(`auth failed: ${r.status}`);
|
|
75
|
+
return r.text();
|
|
82
76
|
});
|
|
83
77
|
|
|
84
|
-
const engine = new BeautyEffectEngine(
|
|
78
|
+
const engine = new BeautyEffectEngine(new EngineConfig({ licenseToken }));
|
|
85
79
|
|
|
86
80
|
try {
|
|
87
81
|
await engine.init();
|
|
@@ -91,19 +85,30 @@ try {
|
|
|
91
85
|
}
|
|
92
86
|
```
|
|
93
87
|
|
|
94
|
-
|
|
88
|
+
#### 服务端代理(Node)
|
|
89
|
+
|
|
90
|
+
密钥只放在服务器环境变量。签名串为 `v2|{app_id}|{timestamp}|{nonce}|web`,HMAC-SHA256(hex)后请求上游,把**响应原文**返回给前端:
|
|
95
91
|
|
|
96
92
|
```javascript
|
|
97
|
-
import { createHmac } from 'node:crypto';
|
|
93
|
+
import { createHmac, randomBytes } from 'node:crypto';
|
|
94
|
+
|
|
95
|
+
const AUTH_URL = 'https://facebetter.pixpark.net/facebetter/v2/auth';
|
|
98
96
|
|
|
99
97
|
app.post('/api/facebetter/auth', async (req, res) => {
|
|
100
|
-
const { nonce, timestamp, platform, user_agent } = req.body;
|
|
101
98
|
const appId = process.env.FB_APP_ID;
|
|
102
99
|
const appKey = process.env.FB_APP_KEY;
|
|
100
|
+
if (!appId || !appKey) {
|
|
101
|
+
res.status(500).json({ error: 'FB_APP_ID / FB_APP_KEY not configured' });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const nonce = randomBytes(16).toString('hex');
|
|
106
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
107
|
+
const platform = 'web';
|
|
103
108
|
const payload = `v2|${appId}|${timestamp}|${nonce}|${platform}`;
|
|
104
109
|
const hmac = createHmac('sha256', appKey).update(payload).digest('hex');
|
|
105
110
|
|
|
106
|
-
const upstream = await fetch(
|
|
111
|
+
const upstream = await fetch(AUTH_URL, {
|
|
107
112
|
method: 'POST',
|
|
108
113
|
headers: { 'Content-Type': 'application/json' },
|
|
109
114
|
body: JSON.stringify({
|
|
@@ -112,13 +117,15 @@ app.post('/api/facebetter/auth', async (req, res) => {
|
|
|
112
117
|
timestamp,
|
|
113
118
|
nonce,
|
|
114
119
|
platform,
|
|
115
|
-
user_agent,
|
|
120
|
+
user_agent: req.headers['user-agent'] || '',
|
|
116
121
|
}),
|
|
117
122
|
});
|
|
118
123
|
res.status(upstream.status).send(await upstream.text());
|
|
119
124
|
});
|
|
120
125
|
```
|
|
121
126
|
|
|
127
|
+
可运行参考:[Demo `api/facebetter/auth.js`](https://github.com/pixpark/facebetter-sdk/blob/main/demo/web/react/api/facebetter/auth.js)。完整说明见 [Auth & License](https://facebetter.net/docs/intro/license)。
|
|
128
|
+
|
|
122
129
|
iOS / Android 仍可用 `appId` + `appKey` 直连在线鉴权,或使用绑定 Bundle ID / Package Name 的离线 license。Web 不支持离线 license。
|
|
123
130
|
|
|
124
131
|
|
|
@@ -201,7 +208,7 @@ processFrame();
|
|
|
201
208
|
|
|
202
209
|
## ⚠️ Important Notes
|
|
203
210
|
|
|
204
|
-
1. **Runtime package**: `import('facebetter-core')` is resolved by your bundler from `node_modules` (installed with `facebetter`). For a `<script>` tag, place `facebetter-core.js` beside `facebetter.js`.
|
|
211
|
+
1. **Runtime package**: `import('facebetter-core')` is resolved by your bundler from `node_modules` (installed with `facebetter`). The SDK then downloads `facebetter-core.wasm` and `resource.fbd` from that package. For a `<script>` tag, place `facebetter-core.js`, `facebetter-core.wasm`, and `resource.fbd` beside `facebetter.js`. Pass `onProgress` to `init()` for download progress.
|
|
205
212
|
2. **Secure Context**: The SDK requires a Secure Context (HTTPS or localhost) to access modern browser features.
|
|
206
213
|
3. **Performance Optimization**:
|
|
207
214
|
- Always call `processImage` within a `requestAnimationFrame` loop.
|