@qmuse/appwrite-runtime-sdk 1.0.5-dev.1 → 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
@@ -199,57 +199,42 @@ export function TodoList() {
199
199
 
200
200
  ## Taro 项目
201
201
 
202
- Taro 项目通过 `createPortableAppwriteClients()` 使用同一套 Runtime API。该方式适用于 Taro H5、支付宝小程序和微信小程序。
202
+ Taro 项目通过 `createQmuseAppwriteRuntime()` 使用同一套 Runtime API,SDK 会在内部创建跨端客户端。该方式适用于 Taro H5、支付宝小程序和微信小程序。
203
+
204
+ Taro 的跨端客户端模式必须从构建环境传入 `appwriteConfig`,SDK 不会请求 `/runtime/appwrite/config`。React Web 应用原有的动态配置流程不受影响。
203
205
 
204
206
  ### 1. 配置跨端环境变量
205
207
 
206
208
  在 Taro 的 `.env.development` 和 `.env.production` 中按目标环境配置:
207
209
 
208
210
  ```dotenv
209
- TARO_APP_QMUSE_APP_ID=3789326422662181
210
- TARO_APP_QMUSE_RUNTIME_ENV=dev
211
- TARO_APP_QMUSE_RUNTIME_DOMAIN=https://appio-pre.qmuse.cn
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
- TARO_APP_QMUSE_APP_ID: string;
227
- TARO_APP_QMUSE_RUNTIME_ENV: 'dev' | 'prod';
228
- TARO_APP_QMUSE_RUNTIME_DOMAIN: string;
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
- ### 2. 读取固定运行时配置
234
-
235
- ```ts
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、支付宝和微信产物使用同一套注入方式。
235
+ 所有 Taro dev/build 命令都需要增加 `--env-prefix QMUSE_`。上述配置会编译进客户端产物,只能存放公开连接信息,禁止写入 Appwrite API Key、Custom Token secret 或用户 Session。
251
236
 
252
- ### 3. 提供跨端请求与存储
237
+ ### 2. 提供跨端请求与存储
253
238
 
254
239
  H5 可以使用浏览器 `fetch`,小程序端需要将 `Taro.request` 适配为 SDK 接收的 `fetch` 接口:
255
240
 
@@ -327,33 +312,43 @@ export const platformStorage = {
327
312
  };
328
313
  ```
329
314
 
330
- ### 4. 创建 Taro Runtime 单例
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
- createPortableAppwriteClients,
337
321
  createQmuseAppwriteRuntime,
322
+ type AppwriteRuntimeConfig,
338
323
  type Models,
324
+ type QmuseRuntimeContext,
339
325
  } from '@qmuse/appwrite-runtime-sdk';
340
- import { getMuseRuntimeConfig } from '../runtime/qmuse';
341
326
  import { platformFetch, platformStorage } from './platform';
342
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
+
343
342
  function getQmuseLoginUserId(): string | null {
344
343
  return null;
345
344
  }
346
345
 
347
- const clients = createPortableAppwriteClients({
348
- fetch: platformFetch,
349
- storage: platformStorage,
350
- });
351
-
352
346
  const runtime = createQmuseAppwriteRuntime({
353
- ...clients,
354
- getMuseRuntime: getMuseRuntimeConfig,
347
+ appwriteConfig,
348
+ getMuseRuntime,
355
349
  getQmuseLoginUserId,
356
350
  fetch: platformFetch,
351
+ storage: platformStorage,
357
352
  });
358
353
 
359
354
  export const initAppwrite = runtime.init;
@@ -370,7 +365,7 @@ export type { Models };
370
365
  export { ID, Permission, Query, Role };
371
366
  ```
372
367
 
373
- ### 5. 在 Taro 应用启动时初始化
368
+ ### 4. 在 Taro 应用启动时初始化
374
369
 
375
370
  ```tsx
376
371
  // src/app.tsx
@@ -465,7 +460,7 @@ await deleteQmuseRow({
465
460
  ## 接入约束
466
461
 
467
462
  - 每个应用只创建一个 `createQmuseAppwriteRuntime()` 实例。
468
- - React 应用使用 Appwrite Web SDK 客户端;Taro 应用使用 `createPortableAppwriteClients()`。
463
+ - React 应用向 `createQmuseAppwriteRuntime()` 传入 Appwrite Web SDK 客户端;Taro 应用传入跨端 `fetch`、`storage` 和构建期 `appwriteConfig`。
469
464
  - H5、支付宝小程序和微信小程序必须使用相同的 `appId`、`env` 和 `domain` 配置来源。
470
465
  - React 应用的 `getQmuseLoginUserId()` 只返回有效的用户 ID 或 `null`;Taro 应用固定返回 `null`。
471
466
  - 业务代码通过 Runtime 的 CRUD 方法读写数据,不直接拼接 Appwrite HTTP 接口。
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export { createQmuseAppwriteRuntime } from './runtime';
2
- export { createPortableAppwriteClients } from './portable';
3
- export type { AppwriteAccountLike, AppwriteClientLike, AppwriteError, AppwriteRuntimeConfig, AppwriteRuntimeStorage, AppwriteSession, AppwriteTablesDBLike, AppwriteUser, BusinessRowData, CreateRowInput, DeleteRowInput, GetRowInput, ListRowsInput, Models, QmuseAppwriteClients, QmuseAppwriteRuntimeApi, QmuseAppwriteRuntimeOptions, QmuseEnvironment, QmuseRuntimeContext, PortableAppwriteClientsOptions, UpdateRowInput, } from './types';
2
+ export type { AppwriteAccountLike, AppwriteClientLike, AppwriteError, AppwriteRuntimeConfig, AppwriteRuntimeStorage, AppwriteSession, AppwriteTablesDBLike, AppwriteUser, BusinessRowData, CreateRowInput, DeleteRowInput, GetRowInput, ListRowsInput, Models, QmuseAppwriteClients, QmuseAppwriteRuntimeApi, QmuseAppwriteRuntimeOptions, QmuseEnvironment, QmuseRuntimeContext, UpdateRowInput, } from './types';
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- export { createQmuseAppwriteRuntime } from "./runtime";
2
- export { createPortableAppwriteClients } from "./portable";
1
+ export { createQmuseAppwriteRuntime } from "./runtime";
@@ -1,5 +1,5 @@
1
1
  import type { AppwriteAccountLike, AppwriteClientLike, AppwriteTablesDBLike, PortableAppwriteClientsOptions } from './types';
2
- export declare function createPortableAppwriteClients(options: PortableAppwriteClientsOptions): {
2
+ export declare function createPortableAppwriteClientsInternal(options: PortableAppwriteClientsOptions): {
3
3
  client: AppwriteClientLike;
4
4
  account: AppwriteAccountLike;
5
5
  tablesDB: AppwriteTablesDBLike;
package/dist/portable.js CHANGED
@@ -369,7 +369,7 @@ var PortableTablesDB = /*#__PURE__*/function () {
369
369
  }]);
370
370
  return PortableTablesDB;
371
371
  }();
372
- export function createPortableAppwriteClients(options) {
372
+ export function createPortableAppwriteClientsInternal(options) {
373
373
  var client = new PortableAppwriteClient(options);
374
374
  return {
375
375
  client: client,
@@ -1,4 +1,4 @@
1
- import type { AppwriteUser, QmuseAppwriteRuntimeOptions } from '../types';
1
+ import type { AppwriteUser, ResolvedQmuseAppwriteRuntimeOptions } from '../types';
2
2
  export declare class AppwriteSessionCoordinator {
3
3
  private readonly options;
4
4
  private readonly request;
@@ -6,7 +6,7 @@ export declare class AppwriteSessionCoordinator {
6
6
  private initPromise;
7
7
  private sessionSyncPromise;
8
8
  private refreshPromise;
9
- constructor(options: QmuseAppwriteRuntimeOptions, request: typeof globalThis.fetch);
9
+ constructor(options: ResolvedQmuseAppwriteRuntimeOptions, request: typeof globalThis.fetch);
10
10
  init(): Promise<void>;
11
11
  getDatabaseId(): Promise<string>;
12
12
  getCurrentUser(): Promise<AppwriteUser>;
@@ -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, config;
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 = 3;
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 3:
248
+ case 5:
224
249
  response = _context6.sent;
225
- _context6.next = 6;
250
+ _context6.next = 8;
226
251
  return readResponsePayload(response);
227
- case 6:
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 = 10;
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 10:
241
- config = {
242
- endpoint: data.endpoint,
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
  }
@@ -1,4 +1,4 @@
1
- import type { QmuseAppwriteRuntimeApi, QmuseAppwriteRuntimeOptions } from '../types';
1
+ import type { QmuseAppwriteRuntimeApi, ResolvedQmuseAppwriteRuntimeOptions } from '../types';
2
2
  export declare class QmuseAppwriteRuntime implements QmuseAppwriteRuntimeApi {
3
3
  private readonly options;
4
4
  readonly init: QmuseAppwriteRuntimeApi['init'];
@@ -12,7 +12,7 @@ export declare class QmuseAppwriteRuntime implements QmuseAppwriteRuntimeApi {
12
12
  readonly deleteRow: QmuseAppwriteRuntimeApi['deleteRow'];
13
13
  private readonly session;
14
14
  private readonly auditReporter;
15
- constructor(options: QmuseAppwriteRuntimeOptions);
15
+ constructor(options: ResolvedQmuseAppwriteRuntimeOptions);
16
16
  private getClientsInternal;
17
17
  private listRowsInternal;
18
18
  private getRowInternal;
package/dist/runtime.js CHANGED
@@ -1,4 +1,17 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
1
2
  import { QmuseAppwriteRuntime } from "./runtime/QmuseAppwriteRuntime";
3
+ import { createPortableAppwriteClientsInternal } from "./portable";
4
+ function resolveRuntimeOptions(options) {
5
+ if (options.client && options.account && options.tablesDB) {
6
+ return options;
7
+ }
8
+ var clients = createPortableAppwriteClientsInternal({
9
+ fetch: options.fetch,
10
+ storage: options.storage,
11
+ storageKeyPrefix: options.storageKeyPrefix
12
+ });
13
+ return _objectSpread(_objectSpread({}, options), clients);
14
+ }
2
15
  export function createQmuseAppwriteRuntime(options) {
3
- return new QmuseAppwriteRuntime(options);
16
+ return new QmuseAppwriteRuntime(resolveRuntimeOptions(options));
4
17
  }
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;
@@ -80,12 +79,29 @@ export interface AppwriteTablesDBLike {
80
79
  rowId: string;
81
80
  }): Promise<unknown>;
82
81
  }
83
- export interface QmuseAppwriteRuntimeOptions {
82
+ interface QmuseAppwriteRuntimeBaseOptions {
83
+ getMuseRuntime(): QmuseRuntimeContext;
84
+ getQmuseLoginUserId(): string | null;
85
+ appwriteConfig?: AppwriteRuntimeConfig;
86
+ }
87
+ interface QmuseAppwriteInjectedClientsOptions extends QmuseAppwriteRuntimeBaseOptions {
88
+ client: AppwriteClientLike;
89
+ account: AppwriteAccountLike;
90
+ tablesDB: AppwriteTablesDBLike;
91
+ fetch?: typeof globalThis.fetch;
92
+ storage?: never;
93
+ }
94
+ interface QmuseAppwritePortableRuntimeOptions extends QmuseAppwriteRuntimeBaseOptions, PortableAppwriteClientsOptions {
95
+ appwriteConfig: AppwriteRuntimeConfig;
96
+ client?: never;
97
+ account?: never;
98
+ tablesDB?: never;
99
+ }
100
+ export type QmuseAppwriteRuntimeOptions = QmuseAppwriteInjectedClientsOptions | QmuseAppwritePortableRuntimeOptions;
101
+ export interface ResolvedQmuseAppwriteRuntimeOptions extends QmuseAppwriteRuntimeBaseOptions {
84
102
  client: AppwriteClientLike;
85
103
  account: AppwriteAccountLike;
86
104
  tablesDB: AppwriteTablesDBLike;
87
- getMuseRuntime(): QmuseRuntimeContext;
88
- getQmuseLoginUserId(): string | null;
89
105
  fetch?: typeof globalThis.fetch;
90
106
  }
91
107
  export interface QmuseAppwriteClients {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qmuse/appwrite-runtime-sdk",
3
- "version": "1.0.5-dev.1",
3
+ "version": "1.0.5-dev.3",
4
4
  "description": "QMuse Appwrite browser runtime SDK",
5
5
  "repository": {
6
6
  "type": "git",