@qmuse/appwrite-runtime-sdk 1.0.5-dev.2 → 1.0.5-dev.3
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
CHANGED
|
@@ -201,55 +201,40 @@ export function TodoList() {
|
|
|
201
201
|
|
|
202
202
|
Taro 项目通过 `createQmuseAppwriteRuntime()` 使用同一套 Runtime API,SDK 会在内部创建跨端客户端。该方式适用于 Taro H5、支付宝小程序和微信小程序。
|
|
203
203
|
|
|
204
|
+
Taro 的跨端客户端模式必须从构建环境传入 `appwriteConfig`,SDK 不会请求 `/runtime/appwrite/config`。React Web 应用原有的动态配置流程不受影响。
|
|
205
|
+
|
|
204
206
|
### 1. 配置跨端环境变量
|
|
205
207
|
|
|
206
208
|
在 Taro 的 `.env.development` 和 `.env.production` 中按目标环境配置:
|
|
207
209
|
|
|
208
210
|
```dotenv
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
211
|
+
QMUSE_APP_ID=3789326422662181
|
|
212
|
+
QMUSE_RUNTIME_ENV=dev
|
|
213
|
+
QMUSE_RUNTIME_DOMAIN=https://appio-pre.qmuse.cn
|
|
214
|
+
QMUSE_APPWRITE_ENDPOINT=https://appbase-qmuse.oceanbase.com/v1
|
|
215
|
+
QMUSE_APPWRITE_PROJECT_ID=6a8e99ba000a9dc3fe53
|
|
216
|
+
QMUSE_APPWRITE_DATABASE_ID=qmuse-app-db
|
|
212
217
|
```
|
|
213
218
|
|
|
214
219
|
补充环境变量类型:
|
|
215
220
|
|
|
216
221
|
```ts
|
|
217
222
|
// types/global.d.ts
|
|
218
|
-
interface QMuseRuntimeConfig {
|
|
219
|
-
appId: string;
|
|
220
|
-
env: 'dev' | 'prod';
|
|
221
|
-
domain: string;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
223
|
declare namespace NodeJS {
|
|
225
224
|
interface ProcessEnv {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
225
|
+
QMUSE_APP_ID: string;
|
|
226
|
+
QMUSE_RUNTIME_ENV: 'dev' | 'prod';
|
|
227
|
+
QMUSE_RUNTIME_DOMAIN: string;
|
|
228
|
+
QMUSE_APPWRITE_ENDPOINT: string;
|
|
229
|
+
QMUSE_APPWRITE_PROJECT_ID: string;
|
|
230
|
+
QMUSE_APPWRITE_DATABASE_ID: string;
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
```
|
|
232
234
|
|
|
233
|
-
|
|
235
|
+
所有 Taro dev/build 命令都需要增加 `--env-prefix QMUSE_`。上述配置会编译进客户端产物,只能存放公开连接信息,禁止写入 Appwrite API Key、Custom Token secret 或用户 Session。
|
|
234
236
|
|
|
235
|
-
|
|
236
|
-
// src/runtime/qmuse.ts
|
|
237
|
-
import type { QmuseRuntimeContext } from '@qmuse/appwrite-runtime-sdk';
|
|
238
|
-
|
|
239
|
-
const runtimeConfig: QmuseRuntimeContext = Object.freeze({
|
|
240
|
-
appId: process.env.TARO_APP_QMUSE_APP_ID,
|
|
241
|
-
env: process.env.TARO_APP_QMUSE_RUNTIME_ENV,
|
|
242
|
-
domain: process.env.TARO_APP_QMUSE_RUNTIME_DOMAIN,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
export function getMuseRuntimeConfig(): QmuseRuntimeContext {
|
|
246
|
-
return runtimeConfig;
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
使用 `TARO_APP_*` 环境变量可以让 Taro 在 dev 和 build 命令中为 H5、支付宝和微信产物使用同一套注入方式。
|
|
251
|
-
|
|
252
|
-
### 3. 提供跨端请求与存储
|
|
237
|
+
### 2. 提供跨端请求与存储
|
|
253
238
|
|
|
254
239
|
H5 可以使用浏览器 `fetch`,小程序端需要将 `Taro.request` 适配为 SDK 接收的 `fetch` 接口:
|
|
255
240
|
|
|
@@ -327,24 +312,40 @@ export const platformStorage = {
|
|
|
327
312
|
};
|
|
328
313
|
```
|
|
329
314
|
|
|
330
|
-
###
|
|
315
|
+
### 3. 创建 Taro Runtime 单例
|
|
331
316
|
|
|
332
317
|
```ts
|
|
333
318
|
// src/services/appwrite.ts
|
|
334
319
|
import { ID, Permission, Query, Role } from 'appwrite';
|
|
335
320
|
import {
|
|
336
321
|
createQmuseAppwriteRuntime,
|
|
322
|
+
type AppwriteRuntimeConfig,
|
|
337
323
|
type Models,
|
|
324
|
+
type QmuseRuntimeContext,
|
|
338
325
|
} from '@qmuse/appwrite-runtime-sdk';
|
|
339
|
-
import { getMuseRuntimeConfig } from '../runtime/qmuse';
|
|
340
326
|
import { platformFetch, platformStorage } from './platform';
|
|
341
327
|
|
|
328
|
+
function getMuseRuntime(): QmuseRuntimeContext {
|
|
329
|
+
return {
|
|
330
|
+
appId: process.env.QMUSE_APP_ID,
|
|
331
|
+
env: process.env.QMUSE_RUNTIME_ENV,
|
|
332
|
+
domain: process.env.QMUSE_RUNTIME_DOMAIN,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const appwriteConfig: AppwriteRuntimeConfig = {
|
|
337
|
+
endpoint: process.env.QMUSE_APPWRITE_ENDPOINT,
|
|
338
|
+
projectId: process.env.QMUSE_APPWRITE_PROJECT_ID,
|
|
339
|
+
databaseId: process.env.QMUSE_APPWRITE_DATABASE_ID,
|
|
340
|
+
};
|
|
341
|
+
|
|
342
342
|
function getQmuseLoginUserId(): string | null {
|
|
343
343
|
return null;
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
const runtime = createQmuseAppwriteRuntime({
|
|
347
|
-
|
|
347
|
+
appwriteConfig,
|
|
348
|
+
getMuseRuntime,
|
|
348
349
|
getQmuseLoginUserId,
|
|
349
350
|
fetch: platformFetch,
|
|
350
351
|
storage: platformStorage,
|
|
@@ -364,7 +365,7 @@ export type { Models };
|
|
|
364
365
|
export { ID, Permission, Query, Role };
|
|
365
366
|
```
|
|
366
367
|
|
|
367
|
-
###
|
|
368
|
+
### 4. 在 Taro 应用启动时初始化
|
|
368
369
|
|
|
369
370
|
```tsx
|
|
370
371
|
// src/app.tsx
|
|
@@ -459,7 +460,7 @@ await deleteQmuseRow({
|
|
|
459
460
|
## 接入约束
|
|
460
461
|
|
|
461
462
|
- 每个应用只创建一个 `createQmuseAppwriteRuntime()` 实例。
|
|
462
|
-
- React 应用向 `createQmuseAppwriteRuntime()` 传入 Appwrite Web SDK 客户端;Taro 应用传入跨端 `fetch`
|
|
463
|
+
- React 应用向 `createQmuseAppwriteRuntime()` 传入 Appwrite Web SDK 客户端;Taro 应用传入跨端 `fetch`、`storage` 和构建期 `appwriteConfig`。
|
|
463
464
|
- H5、支付宝小程序和微信小程序必须使用相同的 `appId`、`env` 和 `domain` 配置来源。
|
|
464
465
|
- React 应用的 `getQmuseLoginUserId()` 只返回有效的用户 ID 或 `null`;Taro 应用固定返回 `null`。
|
|
465
466
|
- 业务代码通过 Runtime 的 CRUD 方法读写数据,不直接拼接 Appwrite HTTP 接口。
|
|
@@ -16,6 +16,7 @@ export declare class AppwriteSessionCoordinator {
|
|
|
16
16
|
private getMuseRuntime;
|
|
17
17
|
private requireRuntimeConfig;
|
|
18
18
|
private clearCurrentSession;
|
|
19
|
+
private validateRuntimeConfig;
|
|
19
20
|
private loadRuntimeConfig;
|
|
20
21
|
private cacheCurrentSession;
|
|
21
22
|
private tryCacheCurrentSession;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
3
|
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
4
4
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
5
5
|
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
6
6
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
7
7
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
8
8
|
import { createResponseError, getErrorCode, isRecord, readResponsePayload, resolveRuntimeUrl } from "./utils";
|
|
9
|
+
var DEFAULT_AUTH_TOKEN_ENDPOINT = '/runtime/appwrite/auth/custom-token';
|
|
9
10
|
export var AppwriteSessionCoordinator = /*#__PURE__*/function () {
|
|
10
11
|
function AppwriteSessionCoordinator(options, request) {
|
|
11
12
|
_classCallCheck(this, AppwriteSessionCoordinator);
|
|
@@ -199,16 +200,40 @@ export var AppwriteSessionCoordinator = /*#__PURE__*/function () {
|
|
|
199
200
|
this.state.currentSessionProvider = null;
|
|
200
201
|
this.state.confirmedQmuseUserId = null;
|
|
201
202
|
}
|
|
203
|
+
}, {
|
|
204
|
+
key: "validateRuntimeConfig",
|
|
205
|
+
value: function validateRuntimeConfig(config) {
|
|
206
|
+
if (!isRecord(config)) {
|
|
207
|
+
throw new Error('Appwrite runtime config is incomplete');
|
|
208
|
+
}
|
|
209
|
+
var normalized = {
|
|
210
|
+
endpoint: config.endpoint,
|
|
211
|
+
projectId: config.projectId,
|
|
212
|
+
databaseId: config.databaseId
|
|
213
|
+
};
|
|
214
|
+
if (typeof normalized.endpoint !== 'string' || !normalized.endpoint || typeof normalized.projectId !== 'string' || !normalized.projectId || typeof normalized.databaseId !== 'string' || !normalized.databaseId) {
|
|
215
|
+
throw new Error('Appwrite runtime config is incomplete');
|
|
216
|
+
}
|
|
217
|
+
return normalized;
|
|
218
|
+
}
|
|
202
219
|
}, {
|
|
203
220
|
key: "loadRuntimeConfig",
|
|
204
221
|
value: function () {
|
|
205
222
|
var _loadRuntimeConfig = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
|
|
206
|
-
var runtime, response, payload, data
|
|
223
|
+
var runtime, response, payload, data;
|
|
207
224
|
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
208
225
|
while (1) switch (_context6.prev = _context6.next) {
|
|
209
226
|
case 0:
|
|
227
|
+
if (!this.options.appwriteConfig) {
|
|
228
|
+
_context6.next = 2;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
return _context6.abrupt("return", _objectSpread(_objectSpread({}, this.validateRuntimeConfig(this.options.appwriteConfig)), {}, {
|
|
232
|
+
authTokenEndpoint: DEFAULT_AUTH_TOKEN_ENDPOINT
|
|
233
|
+
}));
|
|
234
|
+
case 2:
|
|
210
235
|
runtime = this.getMuseRuntime();
|
|
211
|
-
_context6.next =
|
|
236
|
+
_context6.next = 5;
|
|
212
237
|
return this.request(resolveRuntimeUrl('/runtime/appwrite/config', runtime.domain), {
|
|
213
238
|
method: 'POST',
|
|
214
239
|
credentials: 'include',
|
|
@@ -220,15 +245,15 @@ export var AppwriteSessionCoordinator = /*#__PURE__*/function () {
|
|
|
220
245
|
env: runtime.env
|
|
221
246
|
})
|
|
222
247
|
});
|
|
223
|
-
case
|
|
248
|
+
case 5:
|
|
224
249
|
response = _context6.sent;
|
|
225
|
-
_context6.next =
|
|
250
|
+
_context6.next = 8;
|
|
226
251
|
return readResponsePayload(response);
|
|
227
|
-
case
|
|
252
|
+
case 8:
|
|
228
253
|
payload = _context6.sent;
|
|
229
254
|
data = isRecord(payload === null || payload === void 0 ? void 0 : payload.data) ? payload.data : null;
|
|
230
255
|
if (!(!response.ok || (payload === null || payload === void 0 ? void 0 : payload.success) !== true || !data)) {
|
|
231
|
-
_context6.next =
|
|
256
|
+
_context6.next = 12;
|
|
232
257
|
break;
|
|
233
258
|
}
|
|
234
259
|
throw createResponseError({
|
|
@@ -237,21 +262,21 @@ export var AppwriteSessionCoordinator = /*#__PURE__*/function () {
|
|
|
237
262
|
fallbackMessage: "Appwrite config request failed: ".concat(response.status),
|
|
238
263
|
fallbackType: 'appwrite_config_error'
|
|
239
264
|
});
|
|
240
|
-
case
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
projectId: data.projectId,
|
|
244
|
-
databaseId: data.databaseId,
|
|
245
|
-
authTokenEndpoint: data.authTokenEndpoint
|
|
246
|
-
};
|
|
247
|
-
if (!(typeof config.endpoint !== 'string' || !config.endpoint || typeof config.projectId !== 'string' || !config.projectId || typeof config.databaseId !== 'string' || !config.databaseId || typeof config.authTokenEndpoint !== 'string' || !config.authTokenEndpoint)) {
|
|
248
|
-
_context6.next = 13;
|
|
265
|
+
case 12:
|
|
266
|
+
if (!(typeof data.authTokenEndpoint !== 'string' || !data.authTokenEndpoint)) {
|
|
267
|
+
_context6.next = 14;
|
|
249
268
|
break;
|
|
250
269
|
}
|
|
251
270
|
throw new Error('Appwrite runtime config is incomplete');
|
|
252
|
-
case 13:
|
|
253
|
-
return _context6.abrupt("return", config);
|
|
254
271
|
case 14:
|
|
272
|
+
return _context6.abrupt("return", _objectSpread(_objectSpread({}, this.validateRuntimeConfig({
|
|
273
|
+
endpoint: data.endpoint,
|
|
274
|
+
projectId: data.projectId,
|
|
275
|
+
databaseId: data.databaseId
|
|
276
|
+
})), {}, {
|
|
277
|
+
authTokenEndpoint: data.authTokenEndpoint
|
|
278
|
+
}));
|
|
279
|
+
case 15:
|
|
255
280
|
case "end":
|
|
256
281
|
return _context6.stop();
|
|
257
282
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -10,7 +10,6 @@ export interface AppwriteRuntimeConfig {
|
|
|
10
10
|
endpoint: string;
|
|
11
11
|
projectId: string;
|
|
12
12
|
databaseId: string;
|
|
13
|
-
authTokenEndpoint: string;
|
|
14
13
|
}
|
|
15
14
|
export interface AppwriteUser {
|
|
16
15
|
$id: string;
|
|
@@ -83,6 +82,7 @@ export interface AppwriteTablesDBLike {
|
|
|
83
82
|
interface QmuseAppwriteRuntimeBaseOptions {
|
|
84
83
|
getMuseRuntime(): QmuseRuntimeContext;
|
|
85
84
|
getQmuseLoginUserId(): string | null;
|
|
85
|
+
appwriteConfig?: AppwriteRuntimeConfig;
|
|
86
86
|
}
|
|
87
87
|
interface QmuseAppwriteInjectedClientsOptions extends QmuseAppwriteRuntimeBaseOptions {
|
|
88
88
|
client: AppwriteClientLike;
|
|
@@ -92,6 +92,7 @@ interface QmuseAppwriteInjectedClientsOptions extends QmuseAppwriteRuntimeBaseOp
|
|
|
92
92
|
storage?: never;
|
|
93
93
|
}
|
|
94
94
|
interface QmuseAppwritePortableRuntimeOptions extends QmuseAppwriteRuntimeBaseOptions, PortableAppwriteClientsOptions {
|
|
95
|
+
appwriteConfig: AppwriteRuntimeConfig;
|
|
95
96
|
client?: never;
|
|
96
97
|
account?: never;
|
|
97
98
|
tablesDB?: never;
|