@lark-base-open/base-database-app-sdk 0.0.0-stage → 0.0.1-alpha.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.
Files changed (61) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +42 -2
  3. package/capabilities.json +114 -0
  4. package/development-pairing.json +11 -0
  5. package/dist/capabilities-56e403e7.d.ts +22 -0
  6. package/dist/chunk-3JX3FIBG.js +1 -0
  7. package/dist/chunk-5XIFZ4AH.js +1 -0
  8. package/dist/chunk-OHPYKFCM.js +1 -0
  9. package/dist/chunk-ZKBZAK4L.js +1 -0
  10. package/dist/codegen.cjs +15 -0
  11. package/dist/codegen.d.cts +43 -0
  12. package/dist/codegen.d.ts +43 -0
  13. package/dist/codegen.js +15 -0
  14. package/dist/components.d.ts +6 -0
  15. package/dist/components.js +1 -0
  16. package/dist/index-64557073.d.ts +306 -0
  17. package/dist/page.d.ts +138 -0
  18. package/dist/page.js +1 -0
  19. package/dist/server.cjs +1 -0
  20. package/dist/server.d.cts +79 -0
  21. package/dist/server.d.ts +79 -0
  22. package/dist/server.js +1 -0
  23. package/dist/shared.cjs +1 -0
  24. package/dist/shared.d.cts +115 -0
  25. package/dist/shared.d.ts +115 -0
  26. package/dist/shared.js +1 -0
  27. package/dist/testing.d.ts +74 -0
  28. package/dist/testing.js +1 -0
  29. package/dist/theme.css +168 -0
  30. package/dist/vite.d.ts +15 -0
  31. package/dist/vite.js +3 -0
  32. package/docs/README.md +16 -0
  33. package/docs/capabilities.md +42 -0
  34. package/docs/codegen.md +28 -0
  35. package/docs/compat.md +36 -0
  36. package/docs/components.md +34 -0
  37. package/docs/exports.md +45 -0
  38. package/docs/page.md +101 -0
  39. package/docs/server.md +92 -0
  40. package/docs/shared.md +21 -0
  41. package/docs/start-base-app.md +47 -0
  42. package/docs/testing.md +57 -0
  43. package/docs/upgrade.md +44 -0
  44. package/examples/capabilities.ts +7 -0
  45. package/examples/codegen.ts +13 -0
  46. package/examples/compat.ts +21 -0
  47. package/examples/components.tsx +11 -0
  48. package/examples/contract-types.ts +41 -0
  49. package/examples/development-context.ts +17 -0
  50. package/examples/http.ts +12 -0
  51. package/examples/link.ts +10 -0
  52. package/examples/mock.ts +8 -0
  53. package/examples/msw.ts +5 -0
  54. package/examples/page.ts +6 -0
  55. package/examples/server.ts +57 -0
  56. package/examples/shared.ts +10 -0
  57. package/examples/start-base-app.tsx +8 -0
  58. package/examples/upgrade.ts +7 -0
  59. package/examples/upload.ts +18 -0
  60. package/examples/vite.ts +2 -0
  61. package/package.json +119 -4
@@ -0,0 +1,17 @@
1
+ import type { SiteRuntimeContext } from "@lark-base-open/base-database-app-sdk/page";
2
+ export function localAddress(context: SiteRuntimeContext): string | undefined {
3
+ const development = context.development;
4
+ if (!development) return undefined;
5
+ const env: "preview" = development.projectEnv;
6
+ const version: string | null = development.artifactVersion;
7
+ // @ts-expect-error 轻量上下文没有服务端会话 ID。
8
+ development.sessionId;
9
+ // @ts-expect-error 轻量上下文没有服务端租约。
10
+ development.expiresAt;
11
+ return `${development.localOrigin} (${env}, ${version ?? "local"})`;
12
+ }
13
+
14
+ import { siteRuntime } from "@lark-base-open/base-database-app-sdk/page";
15
+ export async function readDevelopmentOrigin() {
16
+ return (await siteRuntime.getRuntimeContext()).development?.localOrigin;
17
+ }
@@ -0,0 +1,12 @@
1
+ import { invokeHttp, fetch as hostFetch } from '@lark-base-open/base-database-app-sdk/page';
2
+ export async function loadUser(signal: AbortSignal) {
3
+ const response = await invokeHttp({ url: '/space/api/user', signal });
4
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
5
+ const data: unknown = await response.json();
6
+ return data;
7
+ }
8
+ export async function loadWithFetch() {
9
+ const response = await hostFetch('/space/api/user');
10
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
11
+ return response.json() as Promise<unknown>;
12
+ }
@@ -0,0 +1,10 @@
1
+ import { siteRuntime, hasCapability, openLink } from '@lark-base-open/base-database-app-sdk/page';
2
+ import type { SiteRuntimeContext } from '@lark-base-open/base-database-app-sdk/page';
3
+ export async function canOpenLink() {
4
+ const context: SiteRuntimeContext = await siteRuntime.getRuntimeContext();
5
+ return hasCapability(context, 'link.open');
6
+ }
7
+ // 在点击之前查询能力。用户点击时立即调用,避免因等待查询失去用户激活。
8
+ export function onSupportedLinkClick(url: string) {
9
+ return openLink(url);
10
+ }
@@ -0,0 +1,8 @@
1
+ import { createMockHost } from '@lark-base-open/base-database-app-sdk/testing';
2
+ import { createSiteRuntimeClient } from '@lark-base-open/base-database-app-sdk/page';
3
+ export async function testUser() {
4
+ const host = createMockHost({ capabilities: { 'function.invoke': { version: 1 } } });
5
+ const runtime = createSiteRuntimeClient(host.channel);
6
+ try { return await runtime.getCurrentUser(); }
7
+ finally { host.dispose(); }
8
+ }
@@ -0,0 +1,5 @@
1
+ import { createHttpHandlers } from '@lark-base-open/base-database-app-sdk/testing';
2
+ export const handlers = createHttpHandlers([
3
+ { method: 'post', url: 'https://service.example/items', status: 201, body: { id: 'item-1' } },
4
+ ]);
5
+ // 交给 MSW setupServer(...handlers) 或 setupWorker(...handlers)。
@@ -0,0 +1,6 @@
1
+ import { siteRuntime, installLinkGuard, classifyRuntimeError } from '@lark-base-open/base-database-app-sdk/page';
2
+ export function mountPage() {
3
+ const cleanup = installLinkGuard({ onDiagnostic: diagnostic => console.warn(diagnostic) });
4
+ void siteRuntime.ready().catch(error => console.warn(classifyRuntimeError(error)));
5
+ return cleanup;
6
+ }
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ import {
3
+ defineFunction,
4
+ bindFunctionRuntime,
5
+ } from "@lark-base-open/base-database-app-sdk/server";
6
+ // 实际工程将 input/output 放独立 contract.ts,CLI 只提取 Schema 依赖图。
7
+ const input = z.object({ title: z.string().min(1) });
8
+ const ignored = z.object({
9
+ id: z.string(),
10
+ name: z.string(),
11
+ reason: z.string(),
12
+ });
13
+ const output = z.discriminatedUnion("status", [
14
+ z.object({
15
+ status: z.literal("success"),
16
+ appliedIds: z.array(z.string()),
17
+ notFoundIds: z.tuple([]),
18
+ ignoredFields: z.tuple([]),
19
+ attachments: z.json().optional(),
20
+ noop: z.boolean().optional(),
21
+ }),
22
+ z.object({
23
+ status: z.literal("partial"),
24
+ appliedIds: z.array(z.string()),
25
+ notFoundIds: z.array(z.string()),
26
+ ignoredFields: z.array(ignored),
27
+ attachments: z.json().optional(),
28
+ }),
29
+ z.object({
30
+ status: z.literal("failed"),
31
+ code: z.string(),
32
+ upstreamCode: z.number().optional(),
33
+ retryable: z.literal(false),
34
+ appliedIds: z.tuple([]),
35
+ }),
36
+ z.object({
37
+ status: z.literal("unknown"),
38
+ code: z.string(),
39
+ retryable: z.literal(false),
40
+ requestedIds: z.array(z.string()).optional(),
41
+ logid: z.string().optional(),
42
+ }),
43
+ ]);
44
+ const handler = defineFunction({
45
+ input,
46
+ output,
47
+ handler: (params, ctx) =>
48
+ ctx.records.create(
49
+ { baseToken: "baseFromCatalog", tableId: "tblFromCatalog" },
50
+ [{ title: params.title }],
51
+ ),
52
+ });
53
+ // 此绑定入口由 CLI 生成;业务 handler 不选择区域、不持有身份凭据。
54
+ export default bindFunctionRuntime(handler, {
55
+ platformEnv: "online",
56
+ brand: "feishu",
57
+ });
@@ -0,0 +1,10 @@
1
+ import { classifyRuntimeError, type WriteResult } from '@lark-base-open/base-database-app-sdk/shared';
2
+ export function writeMessage(result: WriteResult): string {
3
+ switch (result.status) {
4
+ case 'success': return `已写入 ${result.appliedIds.length} 条`;
5
+ case 'partial': return '部分完成,请检查缺失记录和忽略字段';
6
+ case 'failed': return '请求未发送,请修正输入或运行环境';
7
+ case 'unknown': return '结果待核对,请勿直接重试';
8
+ }
9
+ }
10
+ export const describeError = classifyRuntimeError;
@@ -0,0 +1,8 @@
1
+ import { startBaseApp } from '@lark-base-open/base-database-app-sdk/page';
2
+ import '@lark-base-open/base-database-app-sdk/page/styles.css';
3
+ function App() { return <main>订单工作台</main>; }
4
+ export function mountApp() {
5
+ const app = startBaseApp({ app: App, locale: 'zh', theme: 'host' });
6
+ void app.ready.catch(() => console.warn('应用启动失败'));
7
+ return () => app.dispose(); // 卸载或 HMR 时调用。
8
+ }
@@ -0,0 +1,7 @@
1
+ // 模板 1 可先迁移 helper 导入;切换启动入口与模板 2 是独立的手动步骤。
2
+ import { installLinkGuard, siteRuntime, classifyRuntimeError } from '@lark-base-open/base-database-app-sdk/page';
3
+ export function initializeRuntime() {
4
+ const uninstall = installLinkGuard();
5
+ void siteRuntime.ready().catch(error => console.warn(classifyRuntimeError(error)));
6
+ return uninstall;
7
+ }
@@ -0,0 +1,18 @@
1
+ import { requireCapability, siteRuntime } from '@lark-base-open/base-database-app-sdk/page';
2
+ export async function upload(baseToken: string, tableId: string, file: File) {
3
+ await requireCapability('attachment.upload');
4
+ let dimensions: { image_width: number; image_height: number } | undefined;
5
+ if (!file.type) throw new Error('无法识别文件类型');
6
+ if (file.type.startsWith('image/')) {
7
+ const url = URL.createObjectURL(file);
8
+ try {
9
+ const image = new Image(); image.src = url; await image.decode();
10
+ if (image.naturalWidth <= 0 || image.naturalHeight <= 0) throw new Error('无法读取图片尺寸');
11
+ dimensions = { image_width: image.naturalWidth, image_height: image.naturalHeight };
12
+ } finally { URL.revokeObjectURL(url); }
13
+ }
14
+ const result = await siteRuntime.uploadAttachment({ baseToken, tableId, file,
15
+ onProgress: ({ loaded, total }) => console.info(`${loaded}/${total}`) });
16
+ return { file_token: result.fileToken, ...dimensions };
17
+ // 下一步经业务 FaaS 挂载;上传成功不代表单元格写入成功。
18
+ }
@@ -0,0 +1,2 @@
1
+ import { baseAppDevelopmentPairingPlugin } from '@lark-base-open/base-database-app-sdk/vite';
2
+ export const plugins = [baseAppDevelopmentPairingPlugin()];
package/package.json CHANGED
@@ -1,6 +1,121 @@
1
1
  {
2
2
  "name": "@lark-base-open/base-database-app-sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.0.1-alpha.1",
4
+ "description": "Base Database 页面与服务端 SDK、平台组件及测试工具",
5
+ "type": "module",
6
+ "sideEffects": [
7
+ "**/*.css"
8
+ ],
9
+ "exports": {
10
+ "./page": {
11
+ "types": "./dist/page.d.ts",
12
+ "import": "./dist/page.js"
13
+ },
14
+ "./server": {
15
+ "import": {
16
+ "types": "./dist/server.d.ts",
17
+ "default": "./dist/server.js"
18
+ },
19
+ "require": {
20
+ "types": "./dist/server.d.cts",
21
+ "default": "./dist/server.cjs"
22
+ }
23
+ },
24
+ "./shared": {
25
+ "import": {
26
+ "types": "./dist/shared.d.ts",
27
+ "default": "./dist/shared.js"
28
+ },
29
+ "require": {
30
+ "types": "./dist/shared.d.cts",
31
+ "default": "./dist/shared.cjs"
32
+ }
33
+ },
34
+ "./testing": {
35
+ "types": "./dist/testing.d.ts",
36
+ "import": "./dist/testing.js"
37
+ },
38
+ "./components": {
39
+ "types": "./dist/components.d.ts",
40
+ "import": "./dist/components.js"
41
+ },
42
+ "./page/styles.css": "./dist/theme.css",
43
+ "./vite": {
44
+ "types": "./dist/vite.d.ts",
45
+ "import": "./dist/vite.js"
46
+ },
47
+ "./development-pairing.json": "./development-pairing.json",
48
+ "./codegen": {
49
+ "import": {
50
+ "types": "./dist/codegen.d.ts",
51
+ "default": "./dist/codegen.js"
52
+ },
53
+ "require": {
54
+ "types": "./dist/codegen.d.cts",
55
+ "default": "./dist/codegen.cjs"
56
+ }
57
+ }
58
+ },
59
+ "files": [
60
+ "dist",
61
+ "docs",
62
+ "examples",
63
+ "README.md",
64
+ "LICENSE",
65
+ "capabilities.json",
66
+ "development-pairing.json"
67
+ ],
68
+ "scripts": {
69
+ "build": "node scripts/sync-capabilities.mjs && tsup && tsup --config tsup.cjs.config.ts && cp src/page/theme.css dist/theme.css",
70
+ "test": "node scripts/sync-capabilities.mjs --check && npm run build && node --import tsx --test test/*.test.ts && npm run test:types && npm run test:components",
71
+ "test:types": "tsc -p tsconfig.examples.json && tsc -p tsconfig.server.json && tsc -p tsconfig.cjs.json",
72
+ "test:browser": "node test/browser/verify.mjs && node test/browser/ui-verify.mjs",
73
+ "test:components": "vitest run",
74
+ "docs:exports": "node scripts/doc-exports.mjs"
75
+ },
76
+ "dependencies": {
77
+ "@lark-base-open/base-site-channel": "0.1.6",
78
+ "@radix-ui/react-popover": "1.2.0",
79
+ "@standard-schema/spec": "1.0.0",
80
+ "cmdk": "1.1.1",
81
+ "json-schema-to-typescript": "16.0.0"
82
+ },
83
+ "peerDependencies": {
84
+ "@tanstack/react-query": "5.104.1",
85
+ "msw": "2.11.6",
86
+ "react": "^19.2.0",
87
+ "react-dom": "^19.2.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "msw": {
91
+ "optional": true
92
+ }
93
+ },
94
+ "devDependencies": {
95
+ "@testing-library/react": "16.3.0",
96
+ "@types/node": "22.15.0",
97
+ "@types/react": "19.2.17",
98
+ "@types/react-dom": "19.2.3",
99
+ "jsdom": "26.1.0",
100
+ "msw": "2.11.6",
101
+ "pngjs": "7.0.0",
102
+ "tsup": "6.7.0",
103
+ "tsx": "4.20.3",
104
+ "typescript": "5.8.3",
105
+ "vitest": "3.2.4",
106
+ "zod": "4.2.1"
107
+ },
108
+ "typesVersions": {
109
+ "*": {
110
+ "server": [
111
+ "dist/server.d.cts"
112
+ ],
113
+ "shared": [
114
+ "dist/shared.d.cts"
115
+ ],
116
+ "codegen": [
117
+ "dist/codegen.d.cts"
118
+ ]
119
+ }
120
+ }
121
+ }