@visiblebase/core 0.2.0 → 0.2.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.
Files changed (57) hide show
  1. package/README.md +12 -11
  2. package/bin/core/auth/authenticator.d.ts +17 -6
  3. package/bin/core/auth/authenticator.d.ts.map +1 -1
  4. package/bin/core/auth/authenticator.js +49 -30
  5. package/bin/core/auth/authenticator.js.map +1 -1
  6. package/bin/core/base/base.d.ts +11 -40
  7. package/bin/core/base/base.d.ts.map +1 -1
  8. package/bin/core/base/base.js +146 -102
  9. package/bin/core/base/base.js.map +1 -1
  10. package/bin/core/runtime.d.ts +10 -0
  11. package/bin/core/runtime.d.ts.map +1 -1
  12. package/bin/index.d.ts +5 -14
  13. package/bin/index.d.ts.map +1 -1
  14. package/bin/index.js +5 -14
  15. package/bin/index.js.map +1 -1
  16. package/bin/service/action.d.ts +44 -0
  17. package/bin/service/action.d.ts.map +1 -0
  18. package/bin/service/action.js +48 -0
  19. package/bin/service/action.js.map +1 -0
  20. package/bin/service/ai/ai-service.d.ts +36 -60
  21. package/bin/service/ai/ai-service.d.ts.map +1 -1
  22. package/bin/service/ai/ai-service.js +194 -120
  23. package/bin/service/ai/ai-service.js.map +1 -1
  24. package/bin/service/ai/provider.d.ts +24 -58
  25. package/bin/service/ai/provider.d.ts.map +1 -1
  26. package/bin/service/ai/provider.js +20 -41
  27. package/bin/service/ai/provider.js.map +1 -1
  28. package/bin/service/ai/types.d.ts +57 -35
  29. package/bin/service/ai/types.d.ts.map +1 -1
  30. package/bin/service/ai/types.js +1 -1
  31. package/bin/service/env/env-service.d.ts +0 -4
  32. package/bin/service/env/env-service.d.ts.map +1 -1
  33. package/bin/service/env/env-service.js +15 -25
  34. package/bin/service/env/env-service.js.map +1 -1
  35. package/bin/service/hook.d.ts +8 -5
  36. package/bin/service/hook.d.ts.map +1 -1
  37. package/bin/service/hook.js +11 -14
  38. package/bin/service/hook.js.map +1 -1
  39. package/bin/service/plugin.d.ts +20 -96
  40. package/bin/service/plugin.d.ts.map +1 -1
  41. package/bin/service/plugin.js +24 -61
  42. package/bin/service/plugin.js.map +1 -1
  43. package/bin/service/products/products-service.d.ts +0 -5
  44. package/bin/service/products/products-service.d.ts.map +1 -1
  45. package/bin/service/products/products-service.js +19 -25
  46. package/bin/service/products/products-service.js.map +1 -1
  47. package/bin/service/service.d.ts +76 -65
  48. package/bin/service/service.d.ts.map +1 -1
  49. package/bin/service/service.js +47 -80
  50. package/bin/service/service.js.map +1 -1
  51. package/bin/service/types.d.ts +2 -8
  52. package/bin/service/types.d.ts.map +1 -1
  53. package/bin/store/db.d.ts +5 -4
  54. package/bin/store/db.d.ts.map +1 -1
  55. package/bin/store/db.js +3 -2
  56. package/bin/store/db.js.map +1 -1
  57. package/package.json +8 -9
@@ -1,130 +1,59 @@
1
1
  /**
2
2
  * Plugin 桥接模块。
3
3
  *
4
- * 提供 Plugin 基类,将旧的 Plugin API(install/route/table/hook)
5
- * 桥接到新的 Service API。方便现有插件平滑迁移。
6
- *
4
+ * 提供 Plugin 基类,将旧 Plugin API 桥接到新 Service.action() API。
7
5
  * Plugin = Service + install(ctx) 生命周期。
8
6
  */
9
- import { Service, type RouteAuth } from "./service.js";
7
+ import { Service, type Context, type EnvRequirement } from "./service.js";
8
+ import { Hook } from "./hook.js";
10
9
  import type { BaseTableApi } from "../store/table-api.js";
11
10
  import type { CreateUserTokenInput, UserTokenIssueResult, RuntimeUser } from "../core/auth/types.js";
12
- /**
13
- * Plugin 安装上下文。
14
- *
15
- * 与 Service 不同,Plugin 通过 install() 手动注册路由和 hook,
16
- * 而不是在构造函数中用 this.get()/this.post()。
17
- */
18
11
  export interface BasePluginContext {
19
- /**
20
- * 获取指定名称的数据库表 API。
21
- */
22
12
  table<TRow extends Record<string, unknown> = Record<string, unknown>>(name: string): BaseTableApi<TRow>;
23
- /**
24
- * 注册一个路由。
25
- */
26
13
  route(config: {
27
14
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
28
15
  path: string;
29
- auth?: RouteAuth;
30
- /** 使用属性签名(非 method),避免 TypeScript 将 this 绑定到 config 对象 */
16
+ auth?: Array<"user" | "admin">;
31
17
  handler: (ctx: PluginRouteContext) => Promise<Response> | Response;
32
18
  }): void;
33
- /**
34
- * 生命周期 hook。
35
- */
36
19
  hook: {
37
- /** 请求前 */
38
- before(fn: (ctx: ServiceContext) => Promise<void> | void): void;
39
- /** 请求后 */
40
- after(fn: (ctx: ServiceContext) => Promise<void> | void): void;
41
- /** 请求出错 */
42
- onError(fn: (ctx: ServiceContext) => Promise<void> | void): void;
20
+ before(fn: (ctx: Context) => Promise<void> | void): void;
21
+ after(fn: (ctx: Context) => Promise<void> | void): void;
22
+ onError(fn: (ctx: Context) => Promise<void> | void): void;
43
23
  };
44
- /**
45
- * 签发 user_token。
46
- */
47
24
  createUserToken(input: CreateUserTokenInput): Promise<UserTokenIssueResult>;
48
- /**
49
- * 读取环境变量。
50
- */
51
25
  env(key: string): string | undefined;
52
26
  }
53
- /**
54
- * 路由 handler 的上下文。
55
- */
56
27
  export interface PluginRouteContext {
57
- /** 当前用户 */
58
- user: RuntimeUser;
59
- /** 当前 Product */
60
- product: {
28
+ /** 当前 user_token 解析出的用户;免登录或 admin 请求时可能为空 */
29
+ user?: RuntimeUser;
30
+ /** 当前 user_token 对应的 product;免登录或 admin 请求时可能为空 */
31
+ product?: {
61
32
  product_id: string;
62
33
  status: string;
63
34
  };
64
- /** 原始 Request */
35
+ /** 原始 HTTP 请求 */
65
36
  request: Request;
66
- /** JSON body 解析 */
37
+ /** 读取已解析 JSON 请求体 */
67
38
  json<T extends Record<string, unknown> = Record<string, unknown>>(): Promise<T>;
68
- /** 文本 body 读取 */
39
+ /** 读取原始文本请求体 */
69
40
  text(): Promise<string>;
70
- /** JSON 响应 */
41
+ /** 快速返回 JSON Response */
71
42
  jsonResponse(body: unknown, status?: number): Response;
72
43
  }
73
- /**
74
- * Service hook 上下文。
75
- */
76
- export interface ServiceContext {
77
- user: RuntimeUser;
78
- product: {
79
- product_id: string;
80
- status: string;
81
- };
82
- service: string;
83
- model?: {
84
- id: string;
85
- name: string;
86
- meta?: Record<string, unknown>;
87
- };
88
- resolved_model_id?: string;
89
- input: Record<string, unknown>;
90
- started_at: Date;
91
- ended_at?: Date;
92
- error?: unknown;
93
- }
94
- /**
95
- * Plugin 基类。
96
- *
97
- * 扩展自 Service,新增 install() 生命周期。
98
- * 用法:
99
- * ```ts
100
- * class MyPlugin extends Plugin {
101
- * install(ctx: BasePluginContext): void {
102
- * ctx.route({ method: "GET", path: "/hello", handler: async (c) => c.jsonResponse({ ok: true }) });
103
- * ctx.hook.before(async (sc) => { ... });
104
- * }
105
- * }
106
- * ```
107
- */
108
44
  export declare abstract class Plugin extends Service {
109
- /**
110
- * 插件 schema(与 Service.tables 等价,提供别名兼容)。
111
- *
112
- * 子类通过 readonly schema = { ... } 定义,
113
- * _onInit 中自动同步到 this.tables。
114
- */
115
45
  readonly schema?: Record<string, any>;
116
- constructor();
117
46
  /**
118
- * 安装回调。
47
+ * 插件级全局 hook。
119
48
  *
120
- * Base 初始化时自动调用,此时 _db/_client/_authenticator/_env 已就绪。
49
+ * 通过 BasePluginContext.hook 注册,Base 会在所有 Service Action
50
+ * 执行时统一触发。插件自己的路由仍然通过 Service.action() 暴露。
121
51
  */
52
+ readonly globalHook: Hook;
53
+ constructor(env?: EnvRequirement[]);
122
54
  abstract install(ctx: BasePluginContext): void;
123
55
  _onInit(): Promise<void>;
124
56
  }
125
- /**
126
- * 函数式 Plugin(简化版,不需要 class)。
127
- */
128
57
  export type BasePlugin = {
129
58
  id: string;
130
59
  name?: string;
@@ -132,10 +61,5 @@ export type BasePlugin = {
132
61
  schema?: Record<string, unknown>;
133
62
  install(ctx: BasePluginContext): void;
134
63
  };
135
- /**
136
- * 将函数式 BasePlugin 包装为 Plugin 类实例。
137
- *
138
- * Base.use() 内部调用此函数,使 Service 和 BasePlugin 都可传入。
139
- */
140
64
  export declare function asPlugin(bp: BasePlugin): Plugin;
141
65
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/service/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/service/plugin.ts"],"names":[],"mappings":"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"}
@@ -1,44 +1,28 @@
1
1
  /**
2
2
  * Plugin 桥接模块。
3
3
  *
4
- * 提供 Plugin 基类,将旧的 Plugin API(install/route/table/hook)
5
- * 桥接到新的 Service API。方便现有插件平滑迁移。
6
- *
4
+ * 提供 Plugin 基类,将旧 Plugin API 桥接到新 Service.action() API。
7
5
  * Plugin = Service + install(ctx) 生命周期。
8
6
  */
9
7
  import { Service } from "./service.js";
8
+ import { Hook } from "./hook.js";
10
9
  import { TableApi } from "../store/table-api.js";
11
10
  // ===========================================================================
12
11
  // Plugin 基类
13
12
  // ===========================================================================
14
- /**
15
- * Plugin 基类。
16
- *
17
- * 扩展自 Service,新增 install() 生命周期。
18
- * 用法:
19
- * ```ts
20
- * class MyPlugin extends Plugin {
21
- * install(ctx: BasePluginContext): void {
22
- * ctx.route({ method: "GET", path: "/hello", handler: async (c) => c.jsonResponse({ ok: true }) });
23
- * ctx.hook.before(async (sc) => { ... });
24
- * }
25
- * }
26
- * ```
27
- */
28
13
  export class Plugin extends Service {
14
+ schema;
29
15
  /**
30
- * 插件 schema(与 Service.tables 等价,提供别名兼容)。
16
+ * 插件级全局 hook。
31
17
  *
32
- * 子类通过 readonly schema = { ... } 定义,
33
- * _onInit 中自动同步到 this.tables。
18
+ * 通过 BasePluginContext.hook 注册,Base 会在所有 Service Action
19
+ * 执行时统一触发。插件自己的路由仍然通过 Service.action() 暴露。
34
20
  */
35
- schema;
36
- constructor() {
37
- // 占位 id 子类的 readonly 字段初始化后会覆盖
38
- super({ id: "plugin" });
21
+ globalHook = new Hook();
22
+ constructor(env) {
23
+ super({ id: "plugin", env });
39
24
  }
40
25
  async _onInit() {
41
- // 同步 schema → tables(兼容旧插件用 schema 而非 tables)
42
26
  if (this.schema && !this.tables) {
43
27
  this.tables = this.schema;
44
28
  }
@@ -53,38 +37,25 @@ export class Plugin extends Service {
53
37
  return new TableApi(self._db, table);
54
38
  },
55
39
  route(config) {
56
- const handler = async (svcCtx) => {
57
- const result = await config.handler({
58
- user: svcCtx.user ?? { user_id: "", metadata: {} },
59
- product: svcCtx.product ?? { product_id: "", status: "active" },
60
- request: svcCtx.request,
61
- json: async () => {
62
- return svcCtx.input;
63
- },
64
- text: async () => JSON.stringify(svcCtx.input),
40
+ // 去掉前导 /,与 client ServiceClient.action() normalizeName 对齐
41
+ const actionId = config.path.replace(/^\/+/, "");
42
+ self.action(actionId, async (svcCtx) => {
43
+ return await config.handler({
44
+ user: svcCtx.user,
45
+ product: svcCtx.product,
46
+ request: svcCtx.request ?? new Request("http://local"),
47
+ json: async () => svcCtx.input,
48
+ text: async () => svcCtx.raw_body ?? JSON.stringify(svcCtx.input),
65
49
  jsonResponse: (body, status) => new Response(JSON.stringify(body), {
66
- status,
67
- headers: { "content-type": "application/json" },
50
+ status, headers: { "content-type": "application/json" },
68
51
  }),
69
52
  });
70
- return result;
71
- };
72
- const methodMap = {
73
- GET: self.get.bind(self),
74
- POST: self.post.bind(self),
75
- PUT: self.put.bind(self),
76
- PATCH: self.patch.bind(self),
77
- DELETE: self.delete.bind(self),
78
- };
79
- const register = methodMap[config.method];
80
- if (register) {
81
- register(config.path, handler, { auth: config.auth });
82
- }
53
+ }, { method: config.method, auth: config.auth });
83
54
  },
84
55
  hook: {
85
- before(fn) { self.hook.before(fn); },
86
- after(fn) { self.hook.after(fn); },
87
- onError(fn) { self.hook.onError(fn); },
56
+ before(fn) { self.globalHook.before(fn); },
57
+ after(fn) { self.globalHook.after(fn); },
58
+ onError(fn) { self.globalHook.onError(fn); },
88
59
  },
89
60
  async createUserToken(input) {
90
61
  if (!self._authenticator)
@@ -98,17 +69,9 @@ export class Plugin extends Service {
98
69
  this.install(ctx);
99
70
  }
100
71
  }
101
- // ===========================================================================
102
- // 将 BasePlugin 包装为 Plugin 实例
103
- // ===========================================================================
104
- /**
105
- * 将函数式 BasePlugin 包装为 Plugin 类实例。
106
- *
107
- * Base.use() 内部调用此函数,使 Service 和 BasePlugin 都可传入。
108
- */
109
72
  export function asPlugin(bp) {
110
73
  return new (class extends Plugin {
111
- constructor() {
74
+ constructor(env) {
112
75
  super();
113
76
  this.id = bp.id;
114
77
  if (bp.name)
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/service/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/service/plugin.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,11 @@
1
1
  /**
2
2
  * products 内置服务。
3
- *
4
- * 通过 _onInit() 自初始化 ProductStore,Base 不需要知道 ProductStore 的存在。
5
3
  */
6
4
  import { Service } from "../service.js";
7
5
  export declare class ProductsService extends Service {
8
6
  private store;
9
7
  private auth;
10
8
  constructor();
11
- /**
12
- * Base 调用,传入 DB 和 Auth。Service 自行创建 Store 并种子数据。
13
- */
14
9
  _onInit(): Promise<void>;
15
10
  }
16
11
  //# sourceMappingURL=products-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"products-service.d.ts","sourceRoot":"","sources":["../../../src/service/products/products-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,qBAAa,eAAgB,SAAQ,OAAO;IAC1C,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,IAAI,CAAiB;;IAmC7B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}
1
+ {"version":3,"file":"products-service.d.ts","sourceRoot":"","sources":["../../../src/service/products/products-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,qBAAa,eAAgB,SAAQ,OAAO;IAC1C,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,IAAI,CAAiB;;IAmCvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAS/B"}
@@ -1,7 +1,5 @@
1
1
  /**
2
2
  * products 内置服务。
3
- *
4
- * 通过 _onInit() 自初始化 ProductStore,Base 不需要知道 ProductStore 的存在。
5
3
  */
6
4
  import { Service } from "../service.js";
7
5
  import { ProductStore } from "./product-store.js";
@@ -12,37 +10,33 @@ export class ProductsService extends Service {
12
10
  auth;
13
11
  constructor() {
14
12
  super({ id: "products", name: "Products", tables: { products: sqliteProducts } });
15
- this.get("/", async () => ({ items: await this.store.list() }), { auth: "admin" });
16
- this.post("/create", async ({ input }) => {
17
- return await this.store.create({ name: String(input.name ?? "") });
18
- }, { auth: "admin" });
19
- this.post("/pause", async ({ input }) => {
20
- return await this.store.setStatus(String(input.product_id ?? ""), "paused");
21
- }, { auth: "admin" });
22
- this.post("/activate", async ({ input }) => {
23
- return await this.store.setStatus(String(input.product_id ?? ""), "active");
24
- }, { auth: "admin" });
25
- this.post("/remove", async ({ input }) => {
26
- await this.store.remove(String(input.product_id ?? ""));
13
+ this.action("list", async () => ({ items: await this.store.list() }), { method: "GET", auth: ["admin"] });
14
+ this.action("create", async (ctx) => {
15
+ return await this.store.create({ name: String(ctx.input.name ?? "") });
16
+ }, { auth: ["admin"] });
17
+ this.action("pause", async (ctx) => {
18
+ return await this.store.setStatus(String(ctx.input.product_id ?? ""), "paused");
19
+ }, { auth: ["admin"] });
20
+ this.action("activate", async (ctx) => {
21
+ return await this.store.setStatus(String(ctx.input.product_id ?? ""), "active");
22
+ }, { auth: ["admin"] });
23
+ this.action("remove", async (ctx) => {
24
+ await this.store.remove(String(ctx.input.product_id ?? ""));
27
25
  return { success: true };
28
- }, { auth: "admin" });
29
- this.post("/tokens/apply", async ({ input }) => {
26
+ }, { auth: ["admin"] });
27
+ this.action("tokens/apply", async (ctx) => {
30
28
  const result = await this.auth.createToken({
31
- product_id: String(input.product_id ?? ""),
32
- user_id: String(input.user_id ?? ""),
33
- metadata: input.metadata,
34
- ttl: input.ttl,
29
+ product_id: String(ctx.input.product_id ?? ""),
30
+ user_id: String(ctx.input.user_id ?? ""),
31
+ metadata: ctx.input.metadata,
32
+ ttl: ctx.input.ttl,
35
33
  });
36
34
  return { user_token: result.user_token };
37
- }, { auth: "admin" });
35
+ }, { auth: ["admin"] });
38
36
  }
39
- /**
40
- * Base 调用,传入 DB 和 Auth。Service 自行创建 Store 并种子数据。
41
- */
42
37
  async _onInit() {
43
38
  this.store = new ProductStore(new TableApi(this._db, sqliteProducts));
44
39
  this.auth = this._authenticator;
45
- // 种子默认 Product
46
40
  const existing = await this.store.get("prod_visiblebase");
47
41
  if (!existing) {
48
42
  await this.store.create({ product_id: "prod_visiblebase", name: "VisibleBase" });
@@ -1 +1 @@
1
- {"version":3,"file":"products-service.js","sourceRoot":"","sources":["../../../src/service/products/products-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"products-service.js","sourceRoot":"","sources":["../../../src/service/products/products-service.ts"],"names":[],"mappings":"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"}
@@ -1,118 +1,129 @@
1
1
  /**
2
2
  * Service — SDK 核心单元。
3
3
  *
4
- * 每个 Service = 路由 + 数据库表 + hook + 自初始化。
5
- * 只有一个 Context 类型,所有 handler 共用。
4
+ * 每个 Service = 一组 Action + 数据库表 + hook
5
+ * Action Service 的一等能力单元,可独立被 client 调用。
6
6
  * Service 需要的基础设施(DB、Auth、Env)由 Base 直接设为属性。
7
7
  */
8
8
  import type { AnySQLiteTable } from "drizzle-orm/sqlite-core";
9
9
  import type { AnyPgTable } from "drizzle-orm/pg-core";
10
10
  import { Hook } from "./hook.js";
11
+ import { Action, type ActionFn } from "./action.js";
11
12
  import type { BaseTableApi } from "../store/table-api.js";
12
13
  import type { Database, DbClient } from "../store/db.js";
13
14
  import type { RuntimeUser } from "../core/auth/types.js";
14
15
  import type { Authenticator } from "../core/auth/authenticator.js";
15
- export type RouteAuth = "public" | "user" | "admin";
16
+ /** 当前请求最终解析出的身份。 */
17
+ export type RouteIdentity = "guest" | "user" | "admin";
18
+ /** Action 可声明的可访问身份。空数组表示免登录。 */
19
+ export type RouteAuth = Array<Exclude<RouteIdentity, "guest">>;
16
20
  export interface Context {
21
+ /** 请求参数(来自 client 的 input) */
17
22
  input: Record<string, unknown>;
18
- db: Record<string, BaseTableApi>;
23
+ /** 原始 HTTP Request,插件 webhook 等需要读取 header 时使用 */
24
+ request?: Request;
25
+ /** 原始请求 body 文本,插件 webhook 等需要验签时使用 */
26
+ raw_body?: string;
27
+ /** Action 执行结果(after 阶段可用) */
28
+ output?: unknown;
29
+ /** 当前用户(user_token 解析成功时可用) */
19
30
  user?: RuntimeUser;
31
+ /** 当前请求身份 */
32
+ identity?: {
33
+ kind: RouteIdentity;
34
+ };
35
+ /** 所属 product */
20
36
  product?: {
21
37
  product_id: string;
22
38
  status: string;
23
39
  };
24
- request: Request;
25
- env(key: string): string | undefined;
26
- /** AI 模型信息(AIService 设置,其他 Service 为 undefined) */
27
- model?: {
40
+ /** 当前解析的 variant(如 AI model、翻译语言对等)。由 Service 自行注入 */
41
+ variant?: {
28
42
  id: string;
29
43
  name: string;
44
+ meta?: Record<string, unknown>;
45
+ };
46
+ /** Action 开始时间(框架自动填充) */
47
+ started_at?: Date;
48
+ /** Action 结束时间(框架自动填充) */
49
+ ended_at?: Date;
50
+ /** 异常对象(onError hook 可用,框架自动填充) */
51
+ error?: Error;
52
+ /** 当前 Service */
53
+ service?: {
54
+ id: string;
55
+ name: string;
56
+ };
57
+ /** 当前 Action */
58
+ action?: {
59
+ id: string;
30
60
  };
61
+ /** 数据表(框架注入) */
62
+ db: Record<string, BaseTableApi>;
63
+ /** 读环境变量(框架注入) */
64
+ env(key: string): string | undefined;
31
65
  }
32
- export type Handler = (ctx: Context) => unknown | Response | Promise<unknown | Response>;
33
66
  export interface EnvRequirement {
34
67
  key: string;
35
68
  description: string;
36
69
  required: boolean;
37
70
  }
38
- type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
39
- interface RouteDef {
40
- method: HttpMethod;
41
- path: string;
42
- auth: RouteAuth;
43
- handler(ctx: RouteContext): Promise<Response> | Response;
44
- }
45
- /** 内部桥接上下文(Base 构造,wrapHandler 消费,不对外导出) */
46
- export interface RouteContext {
47
- request: Request;
48
- url: URL;
49
- service_id: string;
50
- route: RouteDef;
51
- user?: RuntimeUser;
52
- product?: {
53
- product_id: string;
54
- status: string;
55
- };
56
- json<T extends object = Record<string, unknown>>(): Promise<T>;
57
- text(): Promise<string>;
58
- jsonResponse(body: unknown, status?: number): Response;
59
- table(name: string): Promise<BaseTableApi>;
60
- env(key: string): string | undefined;
71
+ export interface ActionOptions {
72
+ /** HTTP 方法,默认 POST */
73
+ method?: "GET" | "POST";
74
+ /** 允许访问该 action 的身份集合;默认 `["user"]`,传 `[]` 表示免登录 */
75
+ auth?: RouteAuth;
61
76
  }
77
+ /**
78
+ * 归一化 action 鉴权配置。
79
+ *
80
+ * 关键说明(中文)
81
+ * - 默认值仍然是 `["user"]`
82
+ * - `[]` 表示 guest / user / admin 都可访问
83
+ * - 返回值会去重,方便 Base 在路由层统一处理
84
+ */
85
+ export declare function normalizeRouteAuth(auth?: RouteAuth): RouteAuth;
62
86
  export declare class Service {
63
87
  readonly id: string;
64
88
  readonly name: string;
89
+ /** Service 级 hook,该 Service 下所有 Action 共享 */
65
90
  readonly hook: Hook;
66
91
  readonly tables?: Record<string, AnySQLiteTable | AnyPgTable>;
67
92
  readonly env?: EnvRequirement[];
68
- /**
69
- * 数据库查询接口(Base 初始化后设置)。
70
- */
93
+ /** Action 注册表 */
94
+ private actionMap;
71
95
  _db?: Database;
72
- /** 数据库底层连接,用于 DDL(Base 初始化后设置) */
73
96
  _client?: {
74
97
  $client: DbClient;
75
98
  };
76
- /**
77
- * 鉴权器(Base 初始化后设置)。
78
- */
79
99
  _authenticator?: Authenticator;
80
- /**
81
- * Runtime 环境变量(Base 初始化后设置)。
82
- */
83
100
  _env?: {
84
101
  get(key: string): string | undefined;
85
102
  };
86
- private routes;
103
+ /** 原始数据库实例(better-sqlite3 / D1 等) */
104
+ _raw?: unknown;
105
+ /** 服务公网 URL */
106
+ _baseURL?: string;
87
107
  constructor(options: {
88
108
  id: string;
89
109
  name?: string;
90
110
  tables?: Record<string, AnySQLiteTable | AnyPgTable>;
91
111
  env?: EnvRequirement[];
92
112
  });
113
+ _onInit(): Promise<void>;
93
114
  /**
94
- * 初始化回调(可选)。Base 在设置 _database/_client/_authenticator/_env 后调用。
95
- * Service 在此创建自己的 Store、种子数据等。默认空实现。
115
+ * 注册一个 Action(默认 POST,auth=["user"])。
96
116
  */
97
- _onInit(): Promise<void>;
98
- get(path: string, handler: Handler, opts?: {
99
- auth?: RouteAuth;
100
- }): this;
101
- post(path: string, handler: Handler, opts?: {
102
- auth?: RouteAuth;
103
- }): this;
104
- put(path: string, handler: Handler, opts?: {
105
- auth?: RouteAuth;
106
- }): this;
107
- patch(path: string, handler: Handler, opts?: {
108
- auth?: RouteAuth;
109
- }): this;
110
- delete(path: string, handler: Handler, opts?: {
111
- auth?: RouteAuth;
112
- }): this;
113
- _listRoutes(): RouteDef[];
114
- private _add;
117
+ action(id: string, fn: ActionFn, opts?: ActionOptions): Action;
118
+ /** 获取已注册的 Action */
119
+ get(id: string): Action | undefined;
120
+ /** 列出所有已注册的 Action */
121
+ list(): Action[];
122
+ /** 列出 Action 及其元数据(Base 内部使用) */
123
+ _listActionDefs(): Array<{
124
+ action: Action;
125
+ method: "GET" | "POST";
126
+ auth: RouteAuth;
127
+ }>;
115
128
  }
116
- export declare function serviceRouteFullPath(serviceId: string, route: RouteDef): string;
117
- export {};
118
129
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":"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"}