@lark-base-open/base-database-app-sdk 0.0.0-stage → 0.0.1-alpha.0
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/LICENSE +6 -0
- package/README.md +30 -2
- package/capabilities.json +75 -0
- package/development-pairing.json +11 -0
- package/dist/capabilities-56e403e7.d.ts +22 -0
- package/dist/chunk-3JX3FIBG.js +1 -0
- package/dist/chunk-HEMWSWXI.js +1 -0
- package/dist/chunk-OHPYKFCM.js +1 -0
- package/dist/chunk-YDAVA3BB.js +1 -0
- package/dist/components.d.ts +5 -0
- package/dist/components.js +1 -0
- package/dist/index-64557073.d.ts +306 -0
- package/dist/page.d.ts +137 -0
- package/dist/page.js +1 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +78 -0
- package/dist/server.d.ts +78 -0
- package/dist/server.js +1 -0
- package/dist/shared.cjs +1 -0
- package/dist/shared.d.cts +177 -0
- package/dist/shared.d.ts +177 -0
- package/dist/shared.js +1 -0
- package/dist/testing.d.ts +73 -0
- package/dist/testing.js +1 -0
- package/dist/theme.css +168 -0
- package/dist/vite.d.ts +15 -0
- package/dist/vite.js +3 -0
- package/docs/README.md +16 -0
- package/docs/capabilities.md +59 -0
- package/docs/compat.md +36 -0
- package/docs/components.md +34 -0
- package/docs/exports.md +39 -0
- package/docs/page.md +101 -0
- package/docs/server.md +92 -0
- package/docs/shared.md +21 -0
- package/docs/start-base-app.md +47 -0
- package/docs/testing.md +57 -0
- package/docs/upgrade.md +44 -0
- package/examples/capabilities.ts +7 -0
- package/examples/compat.ts +21 -0
- package/examples/components.tsx +11 -0
- package/examples/contract-types.ts +41 -0
- package/examples/development-context.ts +17 -0
- package/examples/http.ts +12 -0
- package/examples/link.ts +10 -0
- package/examples/mock.ts +8 -0
- package/examples/msw.ts +5 -0
- package/examples/page.ts +6 -0
- package/examples/server.ts +57 -0
- package/examples/shared.ts +10 -0
- package/examples/start-base-app.tsx +8 -0
- package/examples/upgrade.ts +7 -0
- package/examples/upload.ts +18 -0
- package/examples/vite.ts +2 -0
- package/package.json +105 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
©Lark Technologies Pte. Ltd. All rights reserved. Use is subject to the Legal Agreements outlined here:
|
|
2
|
+
[Feishu User Terms of Service](https://www.feishu.cn/terms)
|
|
3
|
+
[Feishu Privacy Policy](https://www.feishu.cn/privacy)
|
|
4
|
+
[Feishu Open Platform App Service Provider Security Management Specifications](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/management-practice/app-service-provider-security-management-specifications)
|
|
5
|
+
[Lark User Terms of Service](https://www.larksuite.com/user-terms-of-service)
|
|
6
|
+
[Lark Privacy Policy](https://www.larksuite.com/privacy-policy)
|
package/README.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @lark-base-open/base-database-app-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
用于开发以飞书多维表格为数据后端的 Base Database 应用,提供页面与服务端运行时、平台组件、版本化能力查询与测试工具。
|
|
4
|
+
|
|
5
|
+
安装:`npm install @lark-base-open/base-database-app-sdk@0.0.1-alpha.0`。
|
|
6
|
+
|
|
7
|
+
运行环境需支持 ES2022;页面 API 需要 Base Database 页面宿主,服务端 API 用于 Node.js / FaaS。组件需要 React 与 React DOM 19.2,页面查询能力使用 @tanstack/react-query 5.104.1;npm 会安装声明的依赖与必需 peer。底层通信依赖 base-site-channel 0.1.5。
|
|
8
|
+
|
|
9
|
+
server/shared 同时提供 ESM 和 CJS;page/components/testing/vite 仅 ESM。
|
|
10
|
+
|
|
11
|
+
公开入口:`page` 页面 API;`server` [`defineFunction`](docs/exports.md#server) 与 records;`shared` 能力及诊断类型/[`SDKError`](docs/exports.md#page);`testing` 测试宿主与 MSW 工厂。另有 components 平台组件、vite 开发插件及 page/styles.css 样式入口。没有根入口,不支持私有源码路径。
|
|
12
|
+
|
|
13
|
+
文档:[完整索引](docs/README.md)、[导出清单](docs/exports.md)、[page](docs/page.md)、[server(defineFunction / ctx.records / 结果语义)](docs/server.md)、[shared](docs/shared.md)、[testing](docs/testing.md)、[components](docs/components.md)、[start-base-app](docs/start-base-app.md)、[capabilities](docs/capabilities.md)、[compat](docs/compat.md)、[upgrade](docs/upgrade.md)。
|
|
14
|
+
所有示例在 examples/,由 npm test 做编译与文档一致性校验。
|
|
15
|
+
|
|
16
|
+
<!-- example: page.ts -->
|
|
17
|
+
```ts
|
|
18
|
+
import { siteRuntime, installLinkGuard, classifyRuntimeError } from '@lark-base-open/base-database-app-sdk/page';
|
|
19
|
+
export function mountPage() {
|
|
20
|
+
const cleanup = installLinkGuard({ onDiagnostic: diagnostic => console.warn(diagnostic) });
|
|
21
|
+
void siteRuntime.ready().catch(error => console.warn(classifyRuntimeError(error)));
|
|
22
|
+
return cleanup;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`page` 不包含 Node、凭据或 testing;`server/shared` 不含 React、DOM 或 channel 的传递依赖。
|
|
27
|
+
测试需要额外安装可选 peer `msw@2.11.6`。生产只导入 page/server/shared 时不需要 MSW。
|
|
28
|
+
|
|
29
|
+
平台启动与组件:见 [startBaseApp](docs/start-base-app.md) 与 [组件](docs/components.md)。
|
|
30
|
+
|
|
31
|
+
SDK 文档说明本版本 API、组件、兼容语义与可编译示例。业务规则、服务端契约、Mutation 结果、CLI 命令与发布流程,请查阅 [@lark-base-open/base-database-cli](https://www.npmjs.com/package/@lark-base-open/base-database-cli) 随包安装的 lark-base-database Skill 及其 references。升级 CLI 时以该版本随包 Skill 为准。
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"sdkVersion": "0.0.1-alpha.0",
|
|
4
|
+
"capabilities": {
|
|
5
|
+
"runtime.context": {
|
|
6
|
+
"kind": "critical",
|
|
7
|
+
"hostBaseline84afb07": true
|
|
8
|
+
},
|
|
9
|
+
"http.request": {
|
|
10
|
+
"kind": "critical",
|
|
11
|
+
"hostBaseline84afb07": true
|
|
12
|
+
},
|
|
13
|
+
"http.binary": {
|
|
14
|
+
"kind": "critical",
|
|
15
|
+
"hostBaseline84afb07": true
|
|
16
|
+
},
|
|
17
|
+
"http.cancel": {
|
|
18
|
+
"kind": "optional",
|
|
19
|
+
"hostBaseline84afb07": true
|
|
20
|
+
},
|
|
21
|
+
"function.invoke": {
|
|
22
|
+
"kind": "critical",
|
|
23
|
+
"hostBaseline84afb07": true
|
|
24
|
+
},
|
|
25
|
+
"runtime.user": {
|
|
26
|
+
"kind": "optional",
|
|
27
|
+
"hostBaseline84afb07": true
|
|
28
|
+
},
|
|
29
|
+
"runtime.logout": {
|
|
30
|
+
"kind": "optional",
|
|
31
|
+
"hostBaseline84afb07": true
|
|
32
|
+
},
|
|
33
|
+
"runtime.requestEdit": {
|
|
34
|
+
"kind": "optional",
|
|
35
|
+
"hostBaseline84afb07": true
|
|
36
|
+
},
|
|
37
|
+
"attachment.upload": {
|
|
38
|
+
"kind": "critical",
|
|
39
|
+
"hostBaseline84afb07": true
|
|
40
|
+
},
|
|
41
|
+
"attachment.cancel": {
|
|
42
|
+
"kind": "optional",
|
|
43
|
+
"hostBaseline84afb07": true
|
|
44
|
+
},
|
|
45
|
+
"chatbot.stream": {
|
|
46
|
+
"kind": "critical",
|
|
47
|
+
"hostBaseline84afb07": true
|
|
48
|
+
},
|
|
49
|
+
"ai.function.stream": {
|
|
50
|
+
"kind": "critical",
|
|
51
|
+
"hostBaseline84afb07": true
|
|
52
|
+
},
|
|
53
|
+
"runtime.lifecycle": {
|
|
54
|
+
"kind": "optional",
|
|
55
|
+
"hostBaseline84afb07": true
|
|
56
|
+
},
|
|
57
|
+
"runtime.mode": {
|
|
58
|
+
"kind": "optional",
|
|
59
|
+
"hostBaseline84afb07": true
|
|
60
|
+
},
|
|
61
|
+
"attachment.progress": {
|
|
62
|
+
"kind": "optional",
|
|
63
|
+
"hostBaseline84afb07": true
|
|
64
|
+
},
|
|
65
|
+
"link.open": {
|
|
66
|
+
"kind": "optional",
|
|
67
|
+
"hostBaseline84afb07": true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"baseline": {
|
|
71
|
+
"name": "host-baseline-84afb07",
|
|
72
|
+
"repository": "base-site-web",
|
|
73
|
+
"commit": "84afb07a7a4c05c09f7791cb67c4fe82bac23df8"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tokenEnv": "BASE_APP_DEV_PAIRING_TOKEN",
|
|
3
|
+
"endpoint": "/__base_app/dev-pair",
|
|
4
|
+
"proofPrefix": "base-app-dev-pair.v1",
|
|
5
|
+
"pairApi": "site.v1.development.pair",
|
|
6
|
+
"pairedEvent": "site.v1.development.paired",
|
|
7
|
+
"host": "127.0.0.1",
|
|
8
|
+
"portMin": 43100,
|
|
9
|
+
"portMax": 43109,
|
|
10
|
+
"secretBytes": 32
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SiteRuntimeContext as SiteRuntimeContext$1 } from '@lark-base-open/base-site-channel/runtime';
|
|
2
|
+
import { CapabilityContext, RuntimeCapabilities, CapabilityQueryResult } from './shared.js';
|
|
3
|
+
|
|
4
|
+
/** 仅独立开发入口提供;不含身份凭据或服务端会话。 */
|
|
5
|
+
type SiteRuntimeContext = SiteRuntimeContext$1 & CapabilityContext & {
|
|
6
|
+
development?: {
|
|
7
|
+
localOrigin: string;
|
|
8
|
+
projectEnv: "preview";
|
|
9
|
+
artifactVersion: string | null;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
interface RuntimeContextReader {
|
|
13
|
+
getRuntimeContext(): Promise<SiteRuntimeContext>;
|
|
14
|
+
}
|
|
15
|
+
declare function readCapabilities(context: CapabilityContext): RuntimeCapabilities;
|
|
16
|
+
declare function hasCapability(context: CapabilityContext, name: string, minimumVersion?: number): boolean;
|
|
17
|
+
declare function getCapabilities(runtime?: RuntimeContextReader): Promise<RuntimeCapabilities>;
|
|
18
|
+
declare const getRuntimeCapabilities: typeof getCapabilities;
|
|
19
|
+
declare function queryCapability(name: string, minVersion?: number, runtime?: RuntimeContextReader): Promise<CapabilityQueryResult>;
|
|
20
|
+
declare function requireCapability(name: string, minVersion?: number, runtime?: RuntimeContextReader): Promise<void>;
|
|
21
|
+
|
|
22
|
+
export { RuntimeContextReader as R, SiteRuntimeContext as S, getRuntimeCapabilities as a, requireCapability as b, getCapabilities as g, hasCapability as h, queryCapability as q, readCapabilities as r };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Symbol.for("@lark-base-open/base-database-app-sdk/SDKError/v1"),t=class extends Error{constructor(e,n,o,s){super(n);this.code=e;this.name="SDKError",this.safeMessage=n;let r=typeof o=="object"?o:{};this.upstreamCode=typeof o=="string"?o:void 0,this.wireCode=Number.isSafeInteger(r.wireCode)&&r.wireCode!==0?r.wireCode:e==="SDK_TIMEOUT"?504:e==="SDK_CANCELLED"?499:e==="SDK_INPUT_INVALID"?400:500,this.retryable=r.retryable??s??!1,this.outcome=r.outcome??"failed",this.paths=r.paths??[]}[a]=!0;static[Symbol.hasInstance](e){return this!==t?Function.prototype[Symbol.hasInstance].call(this,e):e!==null&&typeof e=="object"&&e[a]===!0}wireCode;safeMessage;retryable;outcome;paths;upstreamCode};export{t as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as Oe,b as Y,c as Fe}from"./chunk-YDAVA3BB.js";import{a as me}from"./chunk-3JX3FIBG.js";import{a as N}from"./chunk-OHPYKFCM.js";import{createContext as qt,useContext as et}from"react";import{createContext as Mt,useContext as Ot,useEffect as Ft,useSyncExternalStore as Nt}from"react";import*as P from"@lark-base-open/base-site-channel/runtime";import{SITE_RUNTIME_PROTOCOL_VERSION as Un,SiteRuntimeApi as E,SiteRuntimeEvent as Sn,SiteRuntimeFunction as oe,SiteRuntimeErrorCode as Pn,readSiteAITextDelta as xn,isValidSiteFunctionName as An}from"@lark-base-open/base-site-channel/runtime-contract";var G=()=>{throw new me(Y.ContextInvalid,"\u5BBF\u4E3B\u80FD\u529B\u5B57\u6BB5\u65E0\u6548")};function fe(e){if(!e||typeof e!="object")return G();if(e.capabilities===void 0)return Object.fromEntries(Object.entries(Oe).filter(([,o])=>o.hostBaseline84afb07).map(([o])=>[o,{version:1}]));let t=e.capabilities;if(!t||typeof t!="object"||Array.isArray(t))return G();let n=Object.entries(t);return n.some(([,o])=>!o||typeof o!="object"||Array.isArray(o)||!Number.isSafeInteger(o.version)||o.version<=0)?G():Object.fromEntries(n.map(([o,r])=>[o,{version:r.version}]))}function vt(e,t,n=1){if(!Number.isSafeInteger(n)||n<1)return G();let o=fe(e);return Object.prototype.hasOwnProperty.call(o,t)&&o[t].version>=n}async function Ct(e=U){return fe(await e.getRuntimeContext())}var _n=Ct;async function Rt(e,t=1,n=U){let o=await n.getRuntimeContext(),r=fe(o),s=vt(o,e,t),a=o.capabilityUnavailable;if(a!==void 0&&(!a||typeof a!="object"||Array.isArray(a)))return G();let i=a&&Object.prototype.hasOwnProperty.call(a,e)?a[e]:void 0;return i!==void 0&&(!i||typeof i!="object"||!["permission-denied","region-unavailable","temporarily-unavailable"].includes(i.reason)||typeof i.retryable!="boolean")?G():{name:e,requiredVersion:t,version:Object.prototype.hasOwnProperty.call(r,e)?r[e].version:null,supported:s,source:o.capabilities===void 0?"host-baseline-84afb07":"advertised",availability:s?i?.reason??"unknown":"unsupported"}}async function Ne(e,t=1,n=U){let o=await n.getRuntimeContext(),r=await Rt(e,t,{getRuntimeContext:async()=>o});if(!r.supported)throw new Fe(e,t);let s={"permission-denied":Y.PermissionDenied,"region-unavailable":Y.RegionUnavailable,"temporarily-unavailable":Y.TemporarilyUnavailable};if(r.availability in s)throw new me(s[r.availability],"\u5BBF\u4E3B\u660E\u786E\u62D2\u7EDD\u6B64\u80FD\u529B",void 0,o.capabilityUnavailable?.[e]?.retryable)}function je(e,t){let n,o=!1,r,s=new Promise(a=>{r=a});return e.registerApi(N.pairApi,async a=>{if(!a||!/^[A-Za-z0-9_-]{43}$/.test(a.challenge))throw new Error("INVALID_PAIRING_CHALLENGE");n=a.challenge;let i=n;o&&(o=!1,s=new Promise(u=>{r=u}));let c=await t(N.endpoint,{method:"POST",credentials:"omit",cache:"no-store",redirect:"error",headers:{"Content-Type":"application/json"},body:JSON.stringify({challenge:i})});if(!c.ok)throw new Error("DEVELOPMENT_PAIRING_FAILED");let d=await c.json();if(!/^[A-Za-z0-9_-]{43}$/.test(d.proof))throw new Error("INVALID_PAIRING_PROOF");return{proof:d.proof}}),e.subscribeEvent(N.pairedEvent,a=>{n&&a?.challenge===n&&(o=!0,r())}),{reset:()=>{n=void 0,o&&(o=!1,s=new Promise(a=>{r=a}))},wait:async()=>{let a;do a=s,await a;while(a!==s)}}}var Be=typeof window<"u"&&window.location.protocol==="http:"&&window.location.hostname===N.host&&Number(window.location.port)>=N.portMin&&Number(window.location.port)<=N.portMax;var $e=P.siteRuntime,_=$e.getChannel?.()??$e.channel,Et=Be&&typeof window<"u"&&window.parent!==window?je(_,globalThis.fetch.bind(globalThis)):void 0,Ut=(e,t)=>e===E.RuntimeContext?[]:e===E.HttpRequest?["http.request",...t?.init?.responseType==="arrayBuffer"?["http.binary"]:[]]:e===E.FunctionInvoke?["function.invoke",...{[oe.GetCurrentUser]:["runtime.user"],[oe.Logout]:["runtime.logout"],[oe.RequestEdit]:["runtime.requestEdit"]}[t?.functionName]??[]]:{[E.HttpRequestCancel]:["http.cancel"],[E.AttachmentUpload]:["attachment.upload"],[E.AttachmentUploadCancel]:["attachment.cancel"],[E.OpenLink]:["link.open"],[E.StreamOpen]:["chatbot.stream"],[E.StreamClose]:["chatbot.stream"],"site.v1.ai.function.stream.open":["ai.function.stream"],"site.v1.ai.function.stream.close":["ai.function.stream"],"site.v1.lifecycle.ready":["runtime.lifecycle"],"site.v1.lifecycle.load-failed":["runtime.lifecycle"]}[e]??[];function He(e,t=async()=>{}){let n=new Map,o=async(r,s)=>{await t();for(let a of Ut(r,s))try{await Ne(a,1,{getRuntimeContext:()=>e.invokeApi(E.RuntimeContext,void 0)})}catch(i){throw i instanceof Error&&"code"in i?Object.assign(new P.SiteRuntimeInvocationError(String(i.code),i.message),i):i}};return{subscribeEvent:(r,s)=>e.subscribeEvent(r,s),emitEvent:async(r,s)=>(await o(r,s),e.emitEvent(r,s)),invokeApi:async(r,s,a)=>{let i=s?.requestId??s?.subscriptionId??s?.uploadId,c=r===E.HttpRequestCancel||r===E.AttachmentUploadCancel||r.endsWith(".close");if(c&&i&&n.has(i)){n.get(i).canceled=!0;return}let d={canceled:!1};!c&&i&&n.set(i,d);try{if(await o(r,s),d.canceled)throw new DOMException("The operation was aborted","AbortError");return i&&n.delete(i),await e.invokeApi(r,s,a)}finally{i&&n.get(i)===d&&n.delete(i)}}}}var St={invokeApi:_.invokeApi.bind(_),emitEvent:_.emitEvent.bind(_),subscribeEvent:_.subscribeEvent.bind(_)},he=He(St,async()=>{if(typeof window<"u"&&window.parent===window)throw new P.SiteRuntimeInvocationError("CHANNEL_UNAVAILABLE","\u9875\u9762\u672A\u8FDE\u63A5\u5BBF\u4E3B channel");await Et?.wait()});_.invokeApi=he.invokeApi;_.emitEvent=he.emitEvent;var ge=class extends P.SiteRuntimeClient{constructor(t){super(t?He(t):he)}},Nn=e=>new ge(e),U=P.siteRuntime,{invokeHttp:re,invokeApi:jn,getCurrentUser:W,logout:be,requestEdit:Pt,uploadAttachment:Bn,openLink:ae}=U,xt=(e=U,t)=>P.createSiteRuntimeFetch(e,t),D=xt();var At=re,kt=/^\/?(preview\/)?app\/([^/]+)(\/|$)/,qe=/^[A-Za-z0-9_-]+$/,ze="/space/api/bitable/site/v1",Tt="/space/api/box/file/temporary_download_url",J="preview",Z=null;function _t(){let t=(typeof globalThis.location>"u"?void 0:globalThis.location)?.ancestorOrigins?.[0];if(t)return t;let n=typeof globalThis.document>"u"?"":globalThis.document.referrer;if(!n)return"";try{return new URL(n).origin}catch{return""}}function ye(){let e=typeof globalThis.location>"u"?"":globalThis.location.pathname,t=kt.exec(e),n=_t();return t?{env:t[1]?J:"prod",gatewayOrigin:n,token:decodeURIComponent(t[2]??"")}:{env:"prod",gatewayOrigin:n,token:""}}function X(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Lt(e){return e===J||e==="prod"}function Dt(e){if(!X(e))return{};let t=typeof e.siteToken=="string"?e.siteToken.trim():"";return{...t?{token:t}:{},...Lt(e.env)?{env:e.env}:{}}}async function j(){return Z||(Z=(async()=>{let e=ye(),t={};try{t=Dt(await U.getRuntimeContext())}catch(o){console.warn("Could not read the host Runtime context; inferring it from the artifact path",o)}let n={env:t.env??e.env,gatewayOrigin:e.gatewayOrigin,token:t.token??e.token};return n.token||console.error("Cannot determine the app token: the host did not provide siteToken and the current path does not match an artifact path"),n})().catch(e=>{throw Z=null,e}),Z)}function we(e){return!!(e.tableId.trim()&&e.fieldId.trim()&&e.recordId.trim()&&e.fileToken.trim())}function Ve(e,t){return JSON.stringify({bitablePerm:{tableId:t.tableId,attachments:{[t.fieldId]:{[t.recordId]:[t.fileToken]}},siteToken:e.token,siteEnv:e.env}})}function Ge(e,t){if(t instanceof Error)return t;let n=X(t)?t.code:void 0,o=typeof n=="string"||typeof n=="number"?String(n):"",r=o==="REQUEST_TIMEOUT"||o==="10005"?`${e} timed out`:`${e} failed`;return Object.assign(new Error(`${r}${o?` (code ${o})`:""}`),{cause:t,...o?{code:o}:{}})}async function Je(e,t=360,n={}){if(n.signal?.throwIfAborted(),!we(e)||!Number.isFinite(t)||t<=0)throw new Error("Attachment location or image size is invalid");let o=await j();if(n.signal?.throwIfAborted(),!o.token)throw new Error("Cannot load the attachment image without an app token");let r=[120,360,720,1280].find(c=>c>=t)??1280,s=new URLSearchParams({extra:Ve(o,e),width:String(r),height:String(r),policy:"allow_up",fallback_source:"1"}),a=await At({url:`/space/api/box/stream/download/v2/cover/${encodeURIComponent(e.fileToken)}?${s}`,init:{method:"GET",responseType:"arrayBuffer",timeoutMs:45e3},signal:n.signal}).catch(c=>{throw Ge("Attachment image request",c)});if(!a.ok){let c=a.headers.get("x-tt-logid");throw new Error(`Failed to load attachment image: HTTP ${a.status}${c?`, LogID ${c}`:""}`)}let i=await a.blob();if(!i.size||!i.type.startsWith("image/"))throw new Error("The host did not return a valid image");return i}async function It(e,t){if(!e.token)throw new Error("Cannot get an attachment download URL without an app token");if(!we(t))throw new Error("Cannot get an attachment download URL: the attachment location is incomplete");let n=await D(Tt,{body:JSON.stringify({extra:Ve(e,t),file_token:t.fileToken}),headers:{"content-type":"application/json"},method:"POST"}).catch(i=>{throw Ge("Attachment download URL request",i)}),o=n.headers?.get("x-tt-logid")?.trim(),r;try{r=await n.json()}catch{throw new Error(n.ok?`Attachment download URL response is not valid JSON${o?`, LogID ${o}`:""}`:`Failed to get attachment download URL: HTTP ${n.status}${o?`, LogID ${o}`:""}`)}let s=X(r)?r.code:void 0;if(typeof s=="number"&&s!==0||typeof s=="string"&&s.trim()!==""&&s.trim()!=="0"){let i=new Error(`Attachment service could not provide a download URL (code ${String(s)}${o?`, LogID ${o}`:""})`);throw Object.assign(i,{code:String(s),cause:r})}if(!n.ok)throw new Error(`Failed to get attachment download URL: HTTP ${n.status}${o?`, LogID ${o}`:""}`);let a=X(r)&&X(r.data)&&typeof r.data.url=="string"?r.data.url.trim():"";if(!a)throw new Error(`Attachment download URL response is missing data.url${o?`, LogID ${o}`:""}`);return a}function Ke(e){let t=new URLSearchParams;e.env===J&&t.set("env",J);let n=t.toString(),o=`${ze}/${encodeURIComponent(e.token)}/invoke_get`;return n?`${o}?${n}`:o}function Qe(e,t){if(!qe.test(t))throw new TypeError(`functionId ${t} does not match the required pattern ${String(qe)}`);let n=`${ze}/${encodeURIComponent(e.token)}/functions/${encodeURIComponent(t)}/invoke`;return e.env===J?`${n}?env=${encodeURIComponent(J)}`:n}async function qn(...[e,t]){let n=await j();if(!n.token)throw new Error(`Cannot invoke Function ${e} without an app token`);let o=await re({url:Qe(n,e),init:{body:JSON.stringify({params:t}),headers:{"content-type":"application/json"},method:"POST"}});if(!o.ok)throw new Error(`Function ${e} request failed: HTTP ${o.status}`);return await o.json()}async function zn(e,t){if(!Array.isArray(t)||t.length<1||t.length>200||t.some(r=>r===null||typeof r!="object"||Array.isArray(r)))throw new TypeError("Mutation batch requires 1 to 200 named parameter objects");let n=await j();if(!n.token)throw new Error("\u5E94\u7528 token \u672A\u786E\u5B9A\uFF0C\u65E0\u6CD5\u8C03\u7528 Mutation");let o=await re({url:Qe(n,e),init:{body:JSON.stringify({batch:t.map(r=>({params:r}))}),headers:{"content-type":"application/json"},method:"POST"}});if(!o.ok)throw new Error(`Mutation \u8C03\u7528\u5931\u8D25\uFF1AHTTP ${o.status}`);return await o.json()}async function Vn(e,t){let n=await It(e,t);if(!(await ae(n)).opened)throw new Error("The host did not open the attachment download link")}function Gn(e,t,n=360){if(!e.gatewayOrigin||!e.token||!we(t))return"";let o=[120,360,720,1280].find(s=>s>=n)??1280,r=new URLSearchParams({extra:JSON.stringify({bitablePerm:{tableId:t.tableId,attachments:{[t.fieldId]:{[t.recordId]:[t.fileToken]}},baseAppToken:e.token}}),width:String(o),height:String(o),policy:"allow_up",fallback_source:"1"});return`${e.gatewayOrigin}/space/api/box/stream/download/v2/cover/${encodeURIComponent(t.fileToken)}?${r.toString()}`}var Ee=Mt(void 0),We=[{id:"en",locale:"en-US",match:/^en(?:-|$)/},{id:"zh",locale:"zh-CN",match:/^zh(?:-|$)/},{id:"ja",locale:"ja-JP",match:/^ja(?:-|$)/}],Ce=new Set,Ze,ve=null;function Re(e){if(typeof e!="string")return;let t=e.trim().replace(/_/g,"-").toLowerCase();return We.find(({match:n})=>n.test(t))?.id}function jt(){return typeof navigator>"u"?void 0:navigator.language}function Bt(e,t){return Re(e)??Re(t)??"en"}function B(){return Ze??Bt(void 0,jt())}function Ue(e=B()){return We.find(({id:t})=>t===e)?.locale??"en-US"}function $t(e){return Ce.add(e),()=>Ce.delete(e)}function Ye(e){Ze=Re(e);let t=B();Xe(t);for(let n of Ce)n();return t}function Xe(e){typeof document<"u"&&(document.documentElement.lang=Ue(e))}function Ht(){return ve||(Xe(B()),ve=U.getRuntimeContext().then(e=>Ye(e?.locale)).catch(()=>Ye(void 0))),ve}function x(){let e=Ot(Ee),t=Nt($t,B,()=>"en");return Ft(()=>{e||Ht()},[e]),e??t}import{jsx as Se}from"react/jsx-runtime";var Pe=qt(null);function to({children:e,...t}){return Se(Pe.Provider,{value:t,children:Se(Ee.Provider,{value:t.locale,children:Se("div",{className:"base-app-platform","data-theme":t.theme,children:e})})})}function no(){let e=et(Pe);if(!e)throw new Error("BASE_APP_PROVIDER_REQUIRED");return e}function ie(){return et(Pe)}import{useState as ee,useEffect as ot}from"react";import{QueryClient as zt}from"@tanstack/react-query";var xe=new zt({defaultOptions:{queries:{retry:!1,staleTime:3e4,gcTime:3e4}}});function se(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ce(e,t){let n=e[t];return typeof n=="string"?n.trim():""}function Vt(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function $(){return{baseBindings:[],name:"",description:"",isOwner:!1,allowEdit:!1,organization:""}}function Gt(){let e=document.querySelector('meta[name="description"]');return e instanceof HTMLMetaElement?e:null}function Jt(e){if(e.name&&(document.title=e.name),e.description){let t=Gt();t&&(t.content=e.description)}}function Kt(e){return Array.isArray(e)?e.reduce((t,n)=>{if(!se(n))return t;let o=ce(n,"baseToken");return o&&t.push({baseToken:o,tableIds:Vt(n.tableIds)}),t},[]):[]}function Qt(e){if(!se(e)||e.code!==0)return $();let t=e.data;if(!se(t))return $();let n=t.site;return se(n)?{baseBindings:Kt(n.baseBindings),description:ce(n,"description"),name:ce(n,"name"),isOwner:t.isOwner===!0,allowEdit:n.allowEdit===void 0?t.isOwner===!0:n.allowEdit===!0,organization:ce(n,"organization")}:$()}async function tt(e){try{let t=await D(Ke(e),{method:"GET"});if(!t.ok)return $();let n=await t.json(),o=Qt(n);return Jt(o),o}catch{return $()}}async function K(){let e=await j();if(!e.token)return $();let t=await W().catch(()=>null);return t?.userId?xe.fetchQuery({queryKey:["project-meta",e.token,e.env,t.userId],queryFn:()=>tt(e)}):tt(e)}var Yt="https://feishu.cn/base/site/detail/overview";async function nt(){try{await U.requestEdit();return}catch{let{token:e}=await j(),t=new URL(Yt);if(t.searchParams.set("token",e),!(await ae(t.toString())).opened)throw new Error("Management page was not opened")}}import{jsx as H,jsxs as rt}from"react/jsx-runtime";var Wt={en:{openFailed:"Unable to open the management page. Please try again.",editSite:"Edit and manage your apps",hidePanel:"Hide until next visit",hiddenConfirmation:"Edit button hidden until you reopen the app",dismissNotification:"Dismiss notification"},zh:{openFailed:"\u65E0\u6CD5\u6253\u5F00\u7BA1\u7406\u9875\u9762\uFF0C\u8BF7\u91CD\u8BD5",editSite:"\u7F16\u8F91\u4E0E\u7BA1\u7406\u5E94\u7528",hidePanel:"\u9690\u85CF\u9762\u677F",hiddenConfirmation:"\u7F16\u8F91\u6309\u94AE\u5DF2\u9690\u85CF\uFF0C\u76F4\u81F3\u4E0B\u6B21\u91CD\u65B0\u6253\u5F00\u5E94\u7528",dismissNotification:"\u5173\u95ED\u63D0\u793A"},ja:{openFailed:"\u7BA1\u7406\u30DA\u30FC\u30B8\u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002",editSite:"\u30A2\u30D7\u30EA\u3092\u7DE8\u96C6\u30FB\u7BA1\u7406",hidePanel:"\u6B21\u56DE\u306E\u30A2\u30AF\u30BB\u30B9\u307E\u3067\u975E\u8868\u793A",hiddenConfirmation:"\u7DE8\u96C6\u30DC\u30BF\u30F3\u3092\u975E\u8868\u793A\u306B\u3057\u307E\u3057\u305F\u3002\u30A2\u30D7\u30EA\u3092\u518D\u5EA6\u958B\u304F\u3068\u8868\u793A\u3055\u308C\u307E\u3059",dismissNotification:"\u901A\u77E5\u3092\u9589\u3058\u308B"}};function wo({position:e="bottom-right",className:t="",slots:n={}}){let o=Wt[x()],[r,s]=ee(!1),[a,i]=ee(!1),[c,d]=ee(!1),[u,p]=ee(!1),[g,f]=ee(!1);ot(()=>{let b=!0;return K().then(O=>{b&&s(O.allowEdit&&ye().env==="prod")}).catch(()=>{}),()=>{b=!1}},[]),ot(()=>{if(!c)return;let b=setTimeout(()=>d(!1),3e3);return()=>clearTimeout(b)},[c]);let m=n.trigger,v=n.tooltip;return r?a?c?rt("div",{className:"base-app-platform base-app-notice",role:"status",children:[o.hiddenConfirmation,H("button",{"aria-label":o.dismissNotification,onClick:()=>d(!1),children:"\xD7"})]}):null:rt("div",{className:`base-app-platform base-app-floating ${t}`,"data-position":e,children:[u?H("div",{role:"alert",children:o.openFailed}):null,g?H("div",{role:"tooltip",children:v?H(v,{text:o.editSite}):o.editSite}):null,H("button",{"aria-label":o.editSite,onFocus:()=>f(!0),onBlur:()=>f(!1),onMouseEnter:()=>f(!0),onMouseLeave:()=>f(!1),onClick:()=>{p(!1),nt().catch(()=>p(!0))},children:m?H(m,{}):"\u270E"}),H("button",{"aria-label":o.hidePanel,onClick:()=>{i(!0),d(!0)},children:"\xD7"})]}):null}var Ae=new Set;function at(e){return Ae.add(e),()=>{Ae.delete(e)}}function it(){for(let e of Ae)e()}import{useEffect as Zt,useState as ct}from"react";import*as I from"@radix-ui/react-popover";async function st(){try{let e=await W();if(typeof e?.name=="string"&&e.name)return{name:e.name,avatarUrl:typeof e.avatarUrl=="string"?e.avatarUrl:"",tenantName:""}}catch{}try{let e=await D("/space/api/user/",{headers:{accept:"application/json"}});if(!e.ok)return null;let n=(await e.json()).data;return!n||typeof n.name!="string"||!n.name?null:{name:n.name,avatarUrl:typeof n.avatar_url=="string"?n.avatar_url:"",tenantName:typeof n.tenant_name=="string"?n.tenant_name:""}}catch{return null}}import{Fragment as en,jsx as A,jsxs as ke}from"react/jsx-runtime";var Xt={en:{account:"Account",logout:"Log out"},zh:{account:"\u8D26\u53F7",logout:"\u9000\u51FA\u767B\u5F55"},ja:{account:"\u30A2\u30AB\u30A6\u30F3\u30C8",logout:"\u30ED\u30B0\u30A2\u30A6\u30C8"}};function Do({audience:e="enterprise",align:t="right",side:n="down",showName:o=!0,className:r="",slots:s={}}){let[a,i]=ct(null),[c,d]=ct(""),u=ie(),p=Xt[x()];if(Zt(()=>{if(e!=="enterprise")return;let m=!0;return Promise.all([st(),K().catch(()=>null)]).then(([v,b])=>{m&&(i(v),d(v?.tenantName||b?.organization||""))}),()=>{m=!1}},[e]),e!=="enterprise"||!a)return null;let g=s.trigger,f=s.organization;return ke(I.Root,{children:[A(I.Trigger,{asChild:!0,children:A("button",{className:`base-app-platform base-app-user-menu ${r}`,"aria-label":p.account,children:g?A(g,{user:a}):ke(en,{children:[a.avatarUrl?A("img",{src:a.avatarUrl,alt:"",referrerPolicy:"no-referrer"}):A("span",{children:a.name.slice(0,1)}),o?a.name:null]})})}),A(I.Portal,{children:ke(I.Content,{"data-theme":u?.theme,className:"base-app-platform base-app-popover",align:t==="right"?"end":"start",side:n==="up"?"top":"bottom",sideOffset:8,collisionPadding:8,children:[A("strong",{children:a.name}),f?A(f,{name:c}):A("p",{children:c}),A("button",{onClick:()=>{it(),xe.clear(),be().catch(()=>{for(let m of["base-site-session","session","sl_session"])document.cookie=`${m}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;window.location.reload()})},children:p.logout})]})})]})}import{useEffect as le,useRef as pt,useState as z}from"react";import{Command as te}from"cmdk";import{QueryClient as pn,useQuery as mn}from"@tanstack/react-query";var tn="/space/api/mention/recommend.v2/",nn="8",on="4",rn="0",an=20,lt={en:{businessError:e=>`Could not search members (error code ${e})`,httpError:e=>`Member search request failed: HTTP ${e}`,invalidResponse:"Member search response has an invalid structure",noBoundBase:"Cannot search members: the application is not bound to a Base"},zh:{businessError:e=>`\u641C\u7D22\u6210\u5458\u5931\u8D25\uFF08\u9519\u8BEF\u7801 ${e}\uFF09`,httpError:e=>`\u641C\u7D22\u6210\u5458\u8BF7\u6C42\u5931\u8D25\uFF1AHTTP ${e}`,invalidResponse:"\u6210\u5458\u641C\u7D22\u54CD\u5E94\u7ED3\u6784\u65E0\u6548",noBoundBase:"\u65E0\u6CD5\u641C\u7D22\u6210\u5458\uFF1A\u5E94\u7528\u5C1A\u672A\u7ED1\u5B9A\u591A\u7EF4\u8868\u683C"},ja:{businessError:e=>`\u30E1\u30F3\u30D0\u30FC\u3092\u691C\u7D22\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u30A8\u30E9\u30FC\u30B3\u30FC\u30C9 ${e}\uFF09`,httpError:e=>`\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF1AHTTP ${e}`,invalidResponse:"\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u306E\u5FDC\u7B54\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093",noBoundBase:"\u30E1\u30F3\u30D0\u30FC\u3092\u691C\u7D22\u3067\u304D\u307E\u305B\u3093\uFF1A\u30A2\u30D7\u30EA\u306BBase\u304C\u95A2\u9023\u4ED8\u3051\u3089\u308C\u3066\u3044\u307E\u305B\u3093"}};async function ut(e,t,n){let o=t??B(),r=lt[o],a=(await K()).baseBindings[0]?.baseToken;if(!a)throw new Error(r.noBoundBase);let i=new URLSearchParams({config_source:"0",obj_type:nn,source:on,token:a,type:rn,user_type:"0",content:e.trim().slice(0,50)}).toString(),c=await D(tn,{signal:n,body:i,headers:{"content-type":"application/x-www-form-urlencoded"},method:"POST"});if(!c.ok)throw new Error(r.httpError(c.status));let d=await c.json();return{code:0,msg:"ok",data:sn(d,o)}}function sn(e,t=B()){let n=Ue(t),o=lt[t],r=cn(e,o);if(!r)throw new Error(o.invalidResponse);let s=r.entities,a=q(s)?s.users:void 0;if(!q(a)||!Array.isArray(r.result_list))throw new Error(o.invalidResponse);let i=[],c=new Set;for(let d of r.result_list){if(!q(d)||Number(d.type)!==0)continue;let u=h(d.token);if(!u)continue;let p=a[u];if(!q(p))continue;let g=h(p.user_id)||h(p.id)||u,f=ln(p,n);if(!g||!f||c.has(g))continue;c.add(g);let m=h(p.avatar_url),v=h(p.open_id);if(i.push({avatar:{avatar_72:m,avatar_240:m,avatar_640:m,avatar_origin:m},department_ids:dn(p.department_ids),description:un(p,n),is_external:p.is_external===!0,name:f,user_id:g,...v?{open_id:v}:{}}),i.length>=an)break}return{users:i}}function cn(e,t){if(q(e)){if(typeof e.code=="number"&&e.code!==0){let n=h(e.msg);throw Object.assign(new Error(n||t.businessError(e.code)),{code:String(e.code),cause:e})}return"entities"in e&&"result_list"in e?e:q(e.data)?e.data:void 0}}function ln(e,t){return dt(e.display_name,t)||(t.toLowerCase().startsWith("zh")?h(e.cn_name):h(e.en_name))||h(e.name)||h(e.en_name)||h(e.cn_name)}function un(e,t){let n=e.is_external===!0?e.i18n_tenant:e.i18n_department;return dt(n,t)||h(e.department)}function dt(e,t){if(typeof e=="string")return e.trim();if(!q(e))return"";let n=t.toLowerCase().replace("-","_"),o=n.split("_")[0]??"",r=o==="zh"?h(e.zh_cn)||h(e.en_us):h(e.en_us)||h(e.zh_cn);return h(e[n])||h(e[o])||r}function h(e){return typeof e=="string"?e.trim():""}function dn(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function q(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}import{Fragment as ft,jsx as R,jsxs as Te}from"react/jsx-runtime";var gt={en:{invalidResponse:"Member search response has an invalid structure",loading:"Loading...",memberList:"Member list",noMatches:"No matching members. Try another search term.",noRecommendations:"No recommended members yet",recordCreator:"Add the person who created this record",searchFailed:"Member search failed",searchFailedCode:e=>`Could not search members (error code ${e})`,searchMembers:"Search members"},zh:{invalidResponse:"\u6210\u5458\u641C\u7D22\u54CD\u5E94\u7ED3\u6784\u65E0\u6548",loading:"\u52A0\u8F7D\u4E2D...",memberList:"\u6210\u5458\u5217\u8868",noMatches:"\u6CA1\u6709\u5339\u914D\u7684\u6210\u5458\uFF0C\u8BF7\u6362\u4E2A\u5173\u952E\u8BCD",noRecommendations:"\u6682\u65E0\u63A8\u8350\u6210\u5458",recordCreator:"\u6DFB\u52A0\u6B64\u8BB0\u5F55\u7684\u4EBA\u5458",searchFailed:"\u641C\u7D22\u6210\u5458\u5931\u8D25",searchFailedCode:e=>`\u641C\u7D22\u6210\u5458\u5931\u8D25\uFF08\u9519\u8BEF\u7801 ${e}\uFF09`,searchMembers:"\u641C\u7D22\u6210\u5458"},ja:{invalidResponse:"\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u306E\u5FDC\u7B54\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093",loading:"\u8AAD\u307F\u8FBC\u307F\u4E2D...",memberList:"\u30E1\u30F3\u30D0\u30FC\u4E00\u89A7",noMatches:"\u4E00\u81F4\u3059\u308B\u30E1\u30F3\u30D0\u30FC\u304C\u3044\u307E\u305B\u3093\u3002\u5225\u306E\u30AD\u30FC\u30EF\u30FC\u30C9\u3067\u691C\u7D22\u3057\u3066\u304F\u3060\u3055\u3044\u3002",noRecommendations:"\u304A\u3059\u3059\u3081\u306E\u30E1\u30F3\u30D0\u30FC\u304C\u3044\u307E\u305B\u3093",recordCreator:"\u3053\u306E\u30EC\u30B3\u30FC\u30C9\u306E\u4F5C\u6210\u8005\u3092\u8FFD\u52A0",searchFailed:"\u30E1\u30F3\u30D0\u30FC\u306E\u691C\u7D22\u306B\u5931\u6557\u3057\u307E\u3057\u305F",searchFailedCode:e=>`\u30E1\u30F3\u30D0\u30FC\u3092\u691C\u7D22\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u30A8\u30E9\u30FC\u30B3\u30FC\u30C9 ${e}\uFF09`,searchMembers:"\u30E1\u30F3\u30D0\u30FC\u3092\u691C\u7D22"}};function ue(e){let[t,n]=z(!1),[o,r]=z(!1);le(()=>r(!0),[]);let s=x(),a=gt[s],[i]=z(()=>new pn({defaultOptions:{queries:{retry:!1,staleTime:3e4,gcTime:3e4}}}));le(()=>{let l=at(()=>{n(!0),i.clear()});return()=>{l(),i.clear()}},[i]);let c=Object.prototype.hasOwnProperty.call(e,"value"),d=pt(c);le(()=>{c!==d.current&&console.warn("UserSelectorPanel controlled mode changed")},[c]);let[u,p]=z(e.defaultValue),g=c?e.value:u,f=Array.isArray(g)?g:g?[g]:[],[m,v]=z(""),[b,O]=z(""),[k,Q]=z(!1),F=pt(!1);le(()=>{if(k)return;let l=setTimeout(()=>O(m.trim()),m.trim()?400:0);return()=>clearTimeout(l)},[m,k]);let y=mn({queryKey:["members",s,b],queryFn:async({signal:l})=>{let C=await ut(b,s,l);return fn(C,s)},enabled:!t&&o&&!k&&m.trim()===b},i),w=e.loading||y.isFetching||m.trim()!==b,T=!t&&!w&&!y.error&&y.data?[...y.data.users,...f.filter(l=>!y.data.users.some(C=>C.user_id===l.user_id))]:[],S=(l,C)=>{v(l),e.onSearch?.(l,{action:C})},de=()=>{S("","AutoClear"),e.onClose?.()},wt=l=>{if(F.current)return;let C=f.some(pe=>pe.user_id===l.user_id),ne=e.mode==="multiple"?C?f.filter(pe=>pe.user_id!==l.user_id):[...f,l]:C?void 0:l;c||p(ne),e.onChange?.(ne,{option:l,action:C?"Remove":"Select"}),C||e.onSelect?.(l,{option:l}),e.mode==="multiple"?S("","AutoClear"):de()},Le=e.slots?.empty,De=e.slots?.loading,Ie=e.slots?.option,Me=e.slots?.footer;return Te(te,{shouldFilter:!1,loop:!0,className:`base-app-platform base-app-selector ${e.className??""}`,label:a.memberList,children:[R(te.Input,{autoFocus:!0,placeholder:a.searchMembers,"aria-label":a.searchMembers,value:m,onValueChange:l=>S(l,"Input"),onCompositionStart:()=>{F.current=!0,Q(!0)},onCompositionEnd:()=>{F.current=!1,Q(!1)},onKeyDown:l=>{if(e.onKeyDown?.(l),l.defaultPrevented){l.stopPropagation();return}if(F.current||gn(l)){l.stopPropagation();return}l.key==="Escape"&&(l.preventDefault(),de())}}),R(te.List,{"aria-label":a.memberList,"aria-multiselectable":e.mode==="multiple"||void 0,children:w?R("div",{role:"status",children:De?R(De,{}):a.loading}):y.error?R("div",{role:"alert",children:a.searchFailed}):Te(ft,{children:[e.onSelectRecordCreator?R(te.Item,{value:"record-creator",onSelect:()=>{e.onSelectRecordCreator?.(),de()},children:a.recordCreator}):null,T.map(l=>{let C=f.some(ne=>ne.user_id===l.user_id);return R(te.Item,{value:l.user_id,onSelect:()=>wt(l),"data-checked":C,children:Ie?R(Ie,{user:l,selected:C}):Te(ft,{children:[R("span",{children:l.name}),R("small",{children:e.getUserDescription?.(l)??l.description}),C?R("span",{"aria-label":"selected",children:"\u2713"}):null]})},l.user_id)}),!T.length&&!e.onSelectRecordCreator?R("div",{role:"status",children:Le?R(Le,{}):m.trim()?a.noMatches:a.noRecommendations}):null]})}),Me?R(Me,{}):null]})}function fn(e,t){let n=gt[t];if(!mt(e)||typeof e.code!="number")throw new Error(n.invalidResponse);if(e.code!==0){let o=typeof e.msg=="string"?e.msg.trim():"";throw Object.assign(new Error(o||n.searchFailedCode(e.code)),{code:String(e.code),cause:e})}if(!mt(e.data)||!Array.isArray(e.data.users))throw new Error(n.invalidResponse);return{users:e.data.users}}function mt(e){return typeof e=="object"&&e!==null}function gn(e){return e.nativeEvent?.isComposing===!0||e.keyCode===229}import{useState as hn,useRef as bn}from"react";import*as M from"@radix-ui/react-popover";import{jsx as L,jsxs as ht}from"react/jsx-runtime";var yn={en:{clearSelected:"Clear selected members",removeMember:e=>`Remove member ${e}`,selectMembers:"Select members"},zh:{clearSelected:"\u6E05\u9664\u5DF2\u9009\u6210\u5458",removeMember:e=>`\u79FB\u9664\u6210\u5458 ${e}`,selectMembers:"\u9009\u62E9\u6210\u5458"},ja:{clearSelected:"\u9078\u629E\u3057\u305F\u30E1\u30F3\u30D0\u30FC\u3092\u30AF\u30EA\u30A2",removeMember:e=>`\u30E1\u30F3\u30D0\u30FC ${e} \u3092\u524A\u9664`,selectMembers:"\u30E1\u30F3\u30D0\u30FC\u3092\u9078\u629E"}};function bt(e){let t=bn(null),n=ie(),o=yn[x()],[r,s]=hn(!1),a=Array.isArray(e.value)?e.value:e.value?[e.value]:[],i=u=>{s(u),u!==r&&e.onDropdownVisibleChange?.(u)},c=e.slots?.trigger,d=e.slots?.chip;return ht(M.Root,{open:r,onOpenChange:i,children:[ht("div",{ref:t,className:`base-app-platform base-app-editor ${e.className??""}`,onClickCapture:u=>{u.target.closest("[data-base-app-trigger]")&&e.onClick?.(u)},children:[L(M.Trigger,{asChild:!0,children:L("button",{type:"button","data-base-app-trigger":"","aria-label":o.selectMembers,onFocus:e.onFocus,onBlur:e.onBlur,children:c?L(c,{value:e.value}):a.length?a.map(u=>L("span",{children:d?L(d,{user:u}):u.name},u.user_id)):o.selectMembers})}),a.map(u=>L("button",{type:"button","aria-label":e.mode==="multiple"?o.removeMember(u.name):o.clearSelected,onClick:p=>{p.stopPropagation(),e.onChange?.(e.mode==="multiple"?a.filter(g=>g.user_id!==u.user_id):void 0),e.mode==="multiple"?e.onRemove?.(u):e.onClear?.()},children:"\xD7"},u.user_id))]}),L(M.Portal,{container:e.portalContainer??t.current?.closest("dialog")??void 0,children:L(M.Content,{"data-theme":n?.theme,className:"base-app-platform base-app-popover",sideOffset:4,collisionPadding:8,children:L(ue,{...e,slots:void 0,onChange:(u,p)=>{e.onChange?.(u),p.action==="Remove"&&p.option&&e.onRemove?.(p.option)},onClose:()=>i(!1)})})})]})}import{useEffect as yt,useRef as wn,useState as _e}from"react";import{jsx as V,jsxs as Cn}from"react/jsx-runtime";var vn={en:{decodeFailed:"Image could not be decoded",loadFailed:"Failed to load image",loading:"Loading image",retry:"Retry image"},zh:{decodeFailed:"\u56FE\u7247\u65E0\u6CD5\u89E3\u7801",loadFailed:"\u56FE\u7247\u52A0\u8F7D\u5931\u8D25",loading:"\u56FE\u7247\u52A0\u8F7D\u4E2D",retry:"\u91CD\u8BD5\u56FE\u7247"},ja:{decodeFailed:"\u753B\u50CF\u3092\u8868\u793A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F",loadFailed:"\u753B\u50CF\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F",loading:"\u753B\u50CF\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D",retry:"\u753B\u50CF\u3092\u518D\u8AAD\u307F\u8FBC\u307F"}};function ar({attachment:e,size:t=360,alt:n,className:o,slots:r={}}){let s=x(),a=vn[s],i=wn(null),[c,d]=_e(!1),[u,p]=_e(0),[g,f]=_e({key:"",url:"",error:""}),{tableId:m,fieldId:v,recordId:b,fileToken:O}=e,k=JSON.stringify([m,v,b,O,t,u]);yt(()=>{if(typeof IntersectionObserver>"u"){d(!0);return}let w=new IntersectionObserver(T=>{T.some(S=>S.isIntersecting)&&(d(!0),w.disconnect())},{rootMargin:"200px"});return i.current&&w.observe(i.current),()=>w.disconnect()},[]),yt(()=>{if(!c)return;let w=new AbortController,T="";return Je({tableId:m,fieldId:v,recordId:b,fileToken:O},t,{signal:w.signal}).then(S=>{w.signal.aborted||(T=URL.createObjectURL(S),f({key:k,url:T,error:""}))}).catch(S=>{w.signal.aborted||f({key:k,url:"",error:S instanceof Error?S.message:"",localError:S instanceof Error?void 0:"loadFailed"})}),()=>{w.abort(),T&&URL.revokeObjectURL(T)}},[c,k,m,v,b,O,t]);let Q=r.loading,F=r.error,y=g.key===k?g:void 0;return V("span",{ref:i,className:`base-app-platform base-app-attachment ${o??""}`,"aria-busy":!y,children:y?.url?V("img",{src:y.url,alt:n,onError:()=>f({key:k,url:"",error:"",localError:"decodeFailed"})}):y?.error||y?.localError?F?V(F,{code:"ATTACHMENT_LOAD_FAILED",retry:()=>p(w=>w+1)}):Cn("span",{children:[V("span",{role:"status",children:y.localError?a[y.localError]:y.error}),V("button",{type:"button",onClick:()=>p(w=>w+1),children:a.retry})]}):V("span",{role:"status",children:Q?V(Q,{}):a.loading})})}export{Un as a,E as b,Sn as c,oe as d,Pn as e,xn as f,An as g,He as h,he as i,ge as j,Nn as k,U as l,re as m,jn as n,W as o,be as p,Pt as q,Bn as r,ae as s,xt as t,D as u,fe as v,vt as w,Ct as x,_n as y,Rt as z,Ne as A,ye as B,j as C,Je as D,It as E,Ke as F,Qe as G,qn as H,zn as I,Vn as J,Gn as K,Ee as L,Bt as M,B as N,Ue as O,Ht as P,x as Q,to as R,no as S,ie as T,xe as U,wo as V,Do as W,ue as X,bt as Y,ar as Z};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i={tokenEnv:"BASE_APP_DEV_PAIRING_TOKEN",endpoint:"/__base_app/dev-pair",proofPrefix:"base-app-dev-pair.v1",pairApi:"site.v1.development.pair",pairedEvent:"site.v1.development.paired",host:"127.0.0.1",portMin:43100,portMax:43109,secretBytes:32};export{i as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as r}from"./chunk-3JX3FIBG.js";var p={"runtime.context":{kind:"critical",hostBaseline84afb07:!0},"http.request":{kind:"critical",hostBaseline84afb07:!0},"http.binary":{kind:"critical",hostBaseline84afb07:!0},"http.cancel":{kind:"optional",hostBaseline84afb07:!0},"function.invoke":{kind:"critical",hostBaseline84afb07:!0},"runtime.user":{kind:"optional",hostBaseline84afb07:!0},"runtime.logout":{kind:"optional",hostBaseline84afb07:!0},"runtime.requestEdit":{kind:"optional",hostBaseline84afb07:!0},"attachment.upload":{kind:"critical",hostBaseline84afb07:!0},"attachment.cancel":{kind:"optional",hostBaseline84afb07:!0},"chatbot.stream":{kind:"critical",hostBaseline84afb07:!0},"ai.function.stream":{kind:"critical",hostBaseline84afb07:!0},"runtime.lifecycle":{kind:"optional",hostBaseline84afb07:!0},"runtime.mode":{kind:"optional",hostBaseline84afb07:!0},"attachment.progress":{kind:"optional",hostBaseline84afb07:!0},"link.open":{kind:"optional",hostBaseline84afb07:!0}},e={HostUnsupported:"CAPABILITY_HOST_UNSUPPORTED",PermissionDenied:"CAPABILITY_PERMISSION_DENIED",RegionUnavailable:"CAPABILITY_REGION_UNAVAILABLE",TemporarilyUnavailable:"CAPABILITY_TEMPORARILY_UNAVAILABLE",ContextInvalid:"CAPABILITY_CONTEXT_INVALID",UnavailableUnknown:"CAPABILITY_UNAVAILABLE_UNKNOWN"},s=class extends r{constructor(t,a){super(e.HostUnsupported,`\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301 ${t} v${a}`);this.capability=t;this.minimumVersion=a;this.name="CapabilityUnavailableError"}};function c(o){let i=o&&typeof o=="object"?o:{},t=typeof i.code=="string"||typeof i.code=="number"?String(i.code):"UNKNOWN",a=e.UnavailableUnknown,n="unknown";[e.HostUnsupported,"10004","PROTOCOL_MISMATCH","ATTACHMENT_UNAVAILABLE","HTTP_RESPONSE_TYPE_UNSUPPORTED"].includes(t)?(a=e.HostUnsupported,n="host-unsupported"):[e.PermissionDenied,"403","PERMISSION_DENIED","FORBIDDEN","FUNCTION_NOT_ALLOWED"].includes(t)?(a=e.PermissionDenied,n="permission-denied"):[e.RegionUnavailable,"REGION_UNAVAILABLE","REGION_NOT_SUPPORTED"].includes(t)?(a=e.RegionUnavailable,n="region-unavailable"):[e.TemporarilyUnavailable,"REQUEST_TIMEOUT","10003","10005","HTTP_REQUEST_FAILED","FUNCTION_REQUEST_FAILED","STREAM_DISCONNECTED","STREAM_HEALTH_TIMEOUT","ATTACHMENT_UPLOAD_STALLED"].includes(t)?(a=e.TemporarilyUnavailable,n="temporary"):t===e.ContextInvalid&&(a=e.ContextInvalid,n="protocol");let l={"host-unsupported":"\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301\u6B64\u80FD\u529B","permission-denied":"\u5F53\u524D\u8EAB\u4EFD\u6216\u53D1\u5E03\u6E05\u5355\u4E0D\u5141\u8BB8\u6B64\u64CD\u4F5C","region-unavailable":"\u5BBF\u4E3B\u660E\u786E\u5F53\u524D\u533A\u57DF\u4E0D\u53EF\u7528",temporary:"\u8C03\u7528\u6682\u65F6\u5931\u8D25\uFF0C\u8BF7\u6838\u5BF9\u7ED3\u679C\u540E\u51B3\u5B9A\u662F\u5426\u91CD\u8BD5",protocol:"\u5BBF\u4E3B\u80FD\u529B\u5B57\u6BB5\u65E0\u6548",unknown:"\u8C03\u7528\u5931\u8D25\uFF0C\u539F\u56E0\u672A\u660E\u786E"};return{source:"sdk",code:a,upstreamCode:i.upstreamCode??t,category:n,retryable:n==="temporary"&&i.retryable!==!1,message:l[n],redaction:"\u539F\u59CB\u9519\u8BEF\u6D88\u606F\u548C\u4E1A\u52A1\u53C2\u6570\u5DF2\u7701\u7565"}}export{p as a,e as b,s as c,c as d};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { X as AttachmentImage, M as BaseAppContextValue, N as BaseAppProvider, T as DatabaseAudience, W as DatabaseUserMenu, V as DatabaseUserMenuProps, R as FloatingButton, Q as FloatingButtonProps, U as UiLanguage, Y as UiLanguageContext, C as User, H as UserSelectorAction, J as UserSelectorEditor, K as UserSelectorEditorProps, L as UserSelectorEditorValue, G as UserSelectorMode, A as UserSelectorPanel, B as UserSelectorPanelProps, I as UserSelectorSearchAction, E as UserSelectorValue, _ as getUiLanguage, $ as getUiLocale, a0 as initializeUiLanguage, Z as selectUiLanguage, O as useBaseApp, P as useOptionalBaseApp, a1 as useUiLanguage } from './index-64557073.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '@lark-base-open/base-site-channel/runtime';
|
|
4
|
+
import './capabilities-56e403e7.js';
|
|
5
|
+
import './shared.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{L as a,M as b,N as c,O as d,P as e,Q as f,R as g,S as h,T as i,V as j,W as k,X as l,Y as m,Z as n}from"./chunk-HEMWSWXI.js";import"./chunk-YDAVA3BB.js";import"./chunk-3JX3FIBG.js";import"./chunk-OHPYKFCM.js";export{n as AttachmentImage,g as BaseAppProvider,k as DatabaseUserMenu,j as FloatingButton,a as UiLanguageContext,m as UserSelectorEditor,l as UserSelectorPanel,c as getUiLanguage,d as getUiLocale,e as initializeUiLanguage,b as selectUiLanguage,h as useBaseApp,i as useOptionalBaseApp,f as useUiLanguage};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { KeyboardEventHandler, MouseEventHandler, FocusEventHandler, ComponentType } from 'react';
|
|
3
|
+
import * as channelRuntime from '@lark-base-open/base-site-channel/runtime';
|
|
4
|
+
import { FunctionMap, RuntimeChannel, SiteProjectEnv } from '@lark-base-open/base-site-channel/runtime';
|
|
5
|
+
import { S as SiteRuntimeContext } from './capabilities-56e403e7.js';
|
|
6
|
+
import { RuntimeDiagnostic } from './shared.js';
|
|
7
|
+
|
|
8
|
+
declare class SiteRuntimeClient<Map = FunctionMap> extends channelRuntime.SiteRuntimeClient<Map> {
|
|
9
|
+
constructor(channel?: RuntimeChannel);
|
|
10
|
+
}
|
|
11
|
+
declare const createSiteRuntimeClient: <Map = FunctionMap>(channel?: RuntimeChannel) => SiteRuntimeClient<Map>;
|
|
12
|
+
declare const siteRuntime: {
|
|
13
|
+
getRuntimeContext(): Promise<SiteRuntimeContext>;
|
|
14
|
+
} & typeof channelRuntime.siteRuntime;
|
|
15
|
+
declare const invokeHttp: (request: channelRuntime.SiteHttpRequestOptions) => Promise<Response>;
|
|
16
|
+
declare const invokeApi: <Name extends never>(functionName: Name, params: channelRuntime.FunctionMap[Name] extends channelRuntime.SiteFunctionDefinition<infer Params, unknown> ? Params : never) => Promise<channelRuntime.FunctionMap[Name] extends channelRuntime.SiteFunctionDefinition<unknown, infer Result> ? Result : never>;
|
|
17
|
+
declare const getCurrentUser: () => Promise<channelRuntime.SiteRuntimeUserInfo>;
|
|
18
|
+
declare const logout: () => Promise<void>;
|
|
19
|
+
declare const requestEdit: () => Promise<void>;
|
|
20
|
+
declare const uploadAttachment: ({ onProgress, ...request }: channelRuntime.SiteAttachmentUploadOptions) => Promise<channelRuntime.SiteAttachmentUploadResult>;
|
|
21
|
+
declare const openLink: (url: string) => Promise<channelRuntime.SiteOpenLinkResult>;
|
|
22
|
+
declare const createSiteRuntimeFetch: typeof channelRuntime.createSiteRuntimeFetch;
|
|
23
|
+
declare const fetch: typeof globalThis.fetch;
|
|
24
|
+
|
|
25
|
+
/** 工程生成代码通过 page 模块扩充,未生成时拒绝任意函数名。 */
|
|
26
|
+
interface DatabaseFunctionInputMap extends FunctionInputMap {
|
|
27
|
+
}
|
|
28
|
+
interface FunctionInputMap {
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 应用产物在 BaseApp 页面 iframe 中的运行上下文。 */
|
|
32
|
+
interface DatabaseContext {
|
|
33
|
+
env: DatabaseEnv;
|
|
34
|
+
gatewayOrigin: string;
|
|
35
|
+
token: string;
|
|
36
|
+
}
|
|
37
|
+
/** 附件在底表里的位置。四个值都来自 catalog.json 与 Database Function 结果。 */
|
|
38
|
+
interface DatabaseAttachmentRef {
|
|
39
|
+
tableId: string;
|
|
40
|
+
fieldId: string;
|
|
41
|
+
recordId: string;
|
|
42
|
+
fileToken: string;
|
|
43
|
+
}
|
|
44
|
+
/** 产物环境沿用 site.v1 协议的规范类型,避免两侧各自声明后漂移。 */
|
|
45
|
+
type DatabaseEnv = SiteProjectEnv;
|
|
46
|
+
/** Function 调用的统一响应包裹结构,与运行态接口一致。 */
|
|
47
|
+
interface DatabaseFunctionResponse<Data = unknown> {
|
|
48
|
+
code: number;
|
|
49
|
+
data?: Data;
|
|
50
|
+
msg?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 从产物托管路径推断当前应用 token 与运行环境。
|
|
54
|
+
*
|
|
55
|
+
* 这是宿主未下发上下文时的兜底:BaseApp 形态下 site 与 BaseApp 共用同一个 token,
|
|
56
|
+
* 线上产物挂在 /app/{token}/、预览产物挂在 /preview/app/{token}/。
|
|
57
|
+
* 该推断依赖部署侧的 CDN 路径约定,优先级低于宿主下发值。
|
|
58
|
+
*
|
|
59
|
+
* @returns 应用 token、运行环境与业务网关 origin;无法推断的值为空字符串。
|
|
60
|
+
*/
|
|
61
|
+
declare function getDatabaseContext(): DatabaseContext;
|
|
62
|
+
/** 解析当前应用上下文,宿主下发值优先、产物路径推断兜底。
|
|
63
|
+
*
|
|
64
|
+
* 结果按会话缓存;解析失败时清空缓存,允许后续调用重试。
|
|
65
|
+
*
|
|
66
|
+
* @returns 应用 token、运行环境与业务网关 origin。
|
|
67
|
+
*/
|
|
68
|
+
declare function resolveDatabaseContext(): Promise<DatabaseContext>;
|
|
69
|
+
/** 宿主用当前访问者身份同源取图,返回可创建本地 URL 的图片字节。
|
|
70
|
+
* 调用方在替换或卸载时取消请求并释放自己创建的 Blob URL。
|
|
71
|
+
*/
|
|
72
|
+
declare function fetchAttachmentCover(ref: DatabaseAttachmentRef, size?: number, options?: {
|
|
73
|
+
signal?: AbortSignal;
|
|
74
|
+
}): Promise<Blob>;
|
|
75
|
+
/** 经父页面 bridge 取短时效自证链接;原文件由浏览器下载,不进入页面 JavaScript。
|
|
76
|
+
* 下载链接不代表附件增删已完成,也不提供并发或重试保证。
|
|
77
|
+
*
|
|
78
|
+
* @returns 短时效下载链接;用户下载请调用 openAttachmentDownload,由宿主打开。
|
|
79
|
+
*/
|
|
80
|
+
declare function fetchAttachmentDownloadUrl(context: DatabaseContext, ref: DatabaseAttachmentRef): Promise<string>;
|
|
81
|
+
/** 构造运行态读取应用信息的统一网关地址。
|
|
82
|
+
*
|
|
83
|
+
* @param context 当前应用上下文。
|
|
84
|
+
* @returns GetInvokeProject 的同源相对路径。
|
|
85
|
+
*/
|
|
86
|
+
declare function buildDatabaseInvokeGetPath(context: DatabaseContext): string;
|
|
87
|
+
/** 构造运行态调用函数的统一网关地址。
|
|
88
|
+
*
|
|
89
|
+
* token 与 function_id 是 path 参数,env 走 query(prod 为服务端缺省,不显式下传)。
|
|
90
|
+
*
|
|
91
|
+
* @param context 当前应用上下文。
|
|
92
|
+
* @param functionId Base Database Function ID。
|
|
93
|
+
* @returns InvokeFunction 的同源相对路径。
|
|
94
|
+
* @throws functionId 不满足命名约束时抛出 TypeError。
|
|
95
|
+
*/
|
|
96
|
+
declare function buildDatabaseInvokeFunctionPath(context: DatabaseContext, functionId: string): string;
|
|
97
|
+
/** 调用应用 Function。
|
|
98
|
+
*
|
|
99
|
+
* 请求经父页面同源代理发往统一网关;整个请求体即 payload,业务参数包在 params 下。
|
|
100
|
+
* 目标环境由 query 参数 env 指定,不重复添加环境 Header。
|
|
101
|
+
* 4xx/5xx 直接抛错,业务码由调用方按 operation 契约校验一次顶层 code。
|
|
102
|
+
*
|
|
103
|
+
* @param functionId Base Database Function ID。
|
|
104
|
+
* @param params 函数入参:Database Function、Mutation 与 FaaS 使用按声明名称构造的对象。
|
|
105
|
+
* @returns 统一包裹的函数响应。
|
|
106
|
+
*/
|
|
107
|
+
type DatabaseFunctionInvocation<Inputs extends object> = [
|
|
108
|
+
Extract<keyof Inputs, string>
|
|
109
|
+
] extends [never] ? [functionId: never, params: never] : {
|
|
110
|
+
[FunctionId in Extract<keyof Inputs, string>]: [
|
|
111
|
+
functionId: FunctionId,
|
|
112
|
+
params: Inputs[FunctionId]
|
|
113
|
+
];
|
|
114
|
+
}[Extract<keyof Inputs, string>];
|
|
115
|
+
declare function invokeDatabaseFunction<Data = unknown>(...[functionId, params]: DatabaseFunctionInvocation<DatabaseFunctionInputMap>): Promise<DatabaseFunctionResponse<Data>>;
|
|
116
|
+
/** 每组参数应用同一份已发布 Mutation 声明;总记录数最多 200。 */
|
|
117
|
+
declare function invokeDatabaseMutationBatch<Data = unknown>(functionId: string, parameterGroups: Record<string, unknown>[]): Promise<DatabaseFunctionResponse<Data>>;
|
|
118
|
+
/** 每次点击重新取短效 URL,经宿主打开;不代表浏览器已完成落盘。 */
|
|
119
|
+
declare function openAttachmentDownload(context: DatabaseContext, ref: DatabaseAttachmentRef): Promise<void>;
|
|
120
|
+
/** 旧模板的纯 URL 构造兼容接口:同步、无网络/宿主调用。
|
|
121
|
+
* 保留旧 extra.baseAppToken 与尺寸匹配语义;新业务取封面使用 fetchAttachmentCover,
|
|
122
|
+
* 其实际请求经统一调用边界。构造地址不能证明附件存在、权限或写入成功。
|
|
123
|
+
*/
|
|
124
|
+
declare function buildAttachmentCoverUrl(context: DatabaseContext, ref: DatabaseAttachmentRef, size?: number): string;
|
|
125
|
+
|
|
126
|
+
declare const UiLanguageContext: React.Context<"en" | "zh" | "ja" | undefined>;
|
|
127
|
+
declare const LANGUAGES: readonly [{
|
|
128
|
+
readonly id: "en";
|
|
129
|
+
readonly locale: "en-US";
|
|
130
|
+
readonly match: RegExp;
|
|
131
|
+
}, {
|
|
132
|
+
readonly id: "zh";
|
|
133
|
+
readonly locale: "zh-CN";
|
|
134
|
+
readonly match: RegExp;
|
|
135
|
+
}, {
|
|
136
|
+
readonly id: "ja";
|
|
137
|
+
readonly locale: "ja-JP";
|
|
138
|
+
readonly match: RegExp;
|
|
139
|
+
}];
|
|
140
|
+
type UiLanguage = (typeof LANGUAGES)[number]["id"];
|
|
141
|
+
/** Supported host locale wins; otherwise use the browser, then English. */
|
|
142
|
+
declare function selectUiLanguage(hostLocale: unknown, fallbackLocale: unknown): UiLanguage;
|
|
143
|
+
declare function getUiLanguage(): UiLanguage;
|
|
144
|
+
declare function getUiLocale(language?: "en" | "zh" | "ja"): string;
|
|
145
|
+
/** The Channel waits for the host handshake. All components share one request. */
|
|
146
|
+
declare function initializeUiLanguage(): Promise<UiLanguage>;
|
|
147
|
+
declare function useUiLanguage(): UiLanguage;
|
|
148
|
+
|
|
149
|
+
interface BaseAppContextValue {
|
|
150
|
+
runtime: typeof siteRuntime;
|
|
151
|
+
theme: "host" | "light" | "dark";
|
|
152
|
+
locale: UiLanguage;
|
|
153
|
+
mode?: string;
|
|
154
|
+
onDiagnostic?: (record: RuntimeDiagnostic) => void;
|
|
155
|
+
}
|
|
156
|
+
declare function BaseAppProvider({ children, ...value }: BaseAppContextValue & {
|
|
157
|
+
children?: React__default.ReactNode;
|
|
158
|
+
}): React__default.JSX.Element;
|
|
159
|
+
declare function useBaseApp(): BaseAppContextValue;
|
|
160
|
+
declare function useOptionalBaseApp(): BaseAppContextValue | null;
|
|
161
|
+
|
|
162
|
+
interface FloatingButtonProps {
|
|
163
|
+
position?: "bottom-right" | "bottom-left";
|
|
164
|
+
className?: string;
|
|
165
|
+
slots?: {
|
|
166
|
+
trigger?: React__default.ComponentType;
|
|
167
|
+
tooltip?: React__default.ComponentType<{
|
|
168
|
+
text: string;
|
|
169
|
+
}>;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
declare function FloatingButton({ position, className, slots, }: FloatingButtonProps): React__default.JSX.Element | null;
|
|
173
|
+
|
|
174
|
+
/** 浮层菜单展示用的当前登录用户信息。 */
|
|
175
|
+
interface CurrentUser {
|
|
176
|
+
name: string;
|
|
177
|
+
avatarUrl: string;
|
|
178
|
+
/** 组织名。协议的 getCurrentUser 不含该字段,仅宿主用户接口回落路径提供。 */
|
|
179
|
+
tenantName: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
type DatabaseAudience = "enterprise" | "personal";
|
|
183
|
+
interface DatabaseUserMenuProps {
|
|
184
|
+
/** 默认 enterprise:拿不准时宁可多显示一个头像,也不要让用户找不到退出登录。 */
|
|
185
|
+
slots?: {
|
|
186
|
+
trigger?: React__default.ComponentType<{
|
|
187
|
+
user: CurrentUser;
|
|
188
|
+
}>;
|
|
189
|
+
organization?: React__default.ComponentType<{
|
|
190
|
+
name: string;
|
|
191
|
+
}>;
|
|
192
|
+
};
|
|
193
|
+
audience?: DatabaseAudience;
|
|
194
|
+
/** 弹层相对触发器的对齐方向,默认 right(触发器在右上角时用)。 */
|
|
195
|
+
align?: "left" | "right";
|
|
196
|
+
/** 弹层展开方向,默认 down(触发器在顶部时用);侧边栏底部的入口用 up。 */
|
|
197
|
+
side?: "up" | "down";
|
|
198
|
+
/** 是否在头像右侧显示姓名。窄侧栏或顶栏空间紧张时传 false。 */
|
|
199
|
+
showName?: boolean;
|
|
200
|
+
className?: string;
|
|
201
|
+
}
|
|
202
|
+
declare function DatabaseUserMenu({ audience, align, side, showName, className, slots, }: DatabaseUserMenuProps): React__default.JSX.Element | null;
|
|
203
|
+
|
|
204
|
+
interface UserAvatar {
|
|
205
|
+
avatar_72: string;
|
|
206
|
+
avatar_240: string;
|
|
207
|
+
avatar_640: string;
|
|
208
|
+
avatar_origin: string;
|
|
209
|
+
}
|
|
210
|
+
interface User {
|
|
211
|
+
avatar: UserAvatar;
|
|
212
|
+
department_ids: string[];
|
|
213
|
+
description?: string;
|
|
214
|
+
is_external?: boolean;
|
|
215
|
+
name: string;
|
|
216
|
+
user_id: string;
|
|
217
|
+
open_id?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
type UserSelectorAction = "Select" | "Remove" | "Clear";
|
|
221
|
+
type UserSelectorMode = "multiple";
|
|
222
|
+
type UserSelectorSearchAction = "Input" | "AutoClear";
|
|
223
|
+
type UserSelectorValue = User | User[];
|
|
224
|
+
interface UserSelectorPanelProps {
|
|
225
|
+
className?: string;
|
|
226
|
+
slots?: {
|
|
227
|
+
empty?: React__default.ComponentType;
|
|
228
|
+
loading?: React__default.ComponentType;
|
|
229
|
+
option?: React__default.ComponentType<{
|
|
230
|
+
user: User;
|
|
231
|
+
selected: boolean;
|
|
232
|
+
}>;
|
|
233
|
+
footer?: React__default.ComponentType;
|
|
234
|
+
};
|
|
235
|
+
value?: UserSelectorValue | null;
|
|
236
|
+
defaultValue?: UserSelectorValue;
|
|
237
|
+
onChange?: (value: UserSelectorValue | undefined, meta: {
|
|
238
|
+
option: User | undefined;
|
|
239
|
+
action: UserSelectorAction;
|
|
240
|
+
}) => void;
|
|
241
|
+
onSelect?: (user: User, meta: {
|
|
242
|
+
option: User;
|
|
243
|
+
}) => void;
|
|
244
|
+
onClose?: () => void;
|
|
245
|
+
onSelectRecordCreator?: () => void;
|
|
246
|
+
getUserDescription?: (user: User) => string | undefined;
|
|
247
|
+
onSearch?: (value: string, meta: {
|
|
248
|
+
action: UserSelectorSearchAction;
|
|
249
|
+
}) => void;
|
|
250
|
+
loading?: boolean;
|
|
251
|
+
mode?: UserSelectorMode;
|
|
252
|
+
onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
|
|
253
|
+
}
|
|
254
|
+
declare function UserSelectorPanel(props: UserSelectorPanelProps): React__default.JSX.Element;
|
|
255
|
+
|
|
256
|
+
type UserSelectorEditorValue = UserSelectorValue;
|
|
257
|
+
|
|
258
|
+
interface UserSelectorEditorProps {
|
|
259
|
+
className?: string;
|
|
260
|
+
portalContainer?: HTMLElement;
|
|
261
|
+
slots?: {
|
|
262
|
+
trigger?: React__default.ComponentType<{
|
|
263
|
+
value: UserSelectorEditorValue | null | undefined;
|
|
264
|
+
}>;
|
|
265
|
+
chip?: React__default.ComponentType<{
|
|
266
|
+
user: User;
|
|
267
|
+
}>;
|
|
268
|
+
};
|
|
269
|
+
value: UserSelectorEditorValue | null | undefined;
|
|
270
|
+
loading?: boolean;
|
|
271
|
+
mode?: UserSelectorMode;
|
|
272
|
+
onClick?: MouseEventHandler<HTMLDivElement>;
|
|
273
|
+
onChange?: (value: UserSelectorEditorValue | undefined) => void;
|
|
274
|
+
onSelect?: (user: User, meta: {
|
|
275
|
+
option: User;
|
|
276
|
+
}) => void;
|
|
277
|
+
onClear?: () => void;
|
|
278
|
+
onRemove?: (user: User) => void;
|
|
279
|
+
onSelectRecordCreator?: () => void;
|
|
280
|
+
getUserDescription?: (user: User) => string | undefined;
|
|
281
|
+
onDropdownVisibleChange?: (visible: boolean) => void;
|
|
282
|
+
onSearch?: (value: string, meta: {
|
|
283
|
+
action: UserSelectorSearchAction;
|
|
284
|
+
}) => void;
|
|
285
|
+
onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
|
|
286
|
+
onFocus?: FocusEventHandler<HTMLButtonElement>;
|
|
287
|
+
onBlur?: FocusEventHandler<HTMLButtonElement>;
|
|
288
|
+
}
|
|
289
|
+
declare function UserSelectorEditor(props: UserSelectorEditorProps): React__default.JSX.Element;
|
|
290
|
+
|
|
291
|
+
/** 缩略图与大图共用;只在靠近可见区域时加载,组件持有并释放本地图片 URL。 */
|
|
292
|
+
declare function AttachmentImage({ attachment, size, alt, className, slots, }: {
|
|
293
|
+
slots?: {
|
|
294
|
+
loading?: ComponentType;
|
|
295
|
+
error?: ComponentType<{
|
|
296
|
+
code: string;
|
|
297
|
+
retry: () => void;
|
|
298
|
+
}>;
|
|
299
|
+
};
|
|
300
|
+
attachment: DatabaseAttachmentRef;
|
|
301
|
+
size?: number;
|
|
302
|
+
alt: string;
|
|
303
|
+
className?: string;
|
|
304
|
+
}): React.JSX.Element;
|
|
305
|
+
|
|
306
|
+
export { getUiLocale as $, UserSelectorPanel as A, UserSelectorPanelProps as B, User as C, DatabaseContext as D, UserSelectorValue as E, FunctionInputMap as F, UserSelectorMode as G, UserSelectorAction as H, UserSelectorSearchAction as I, UserSelectorEditor as J, UserSelectorEditorProps as K, UserSelectorEditorValue as L, BaseAppContextValue as M, BaseAppProvider as N, useBaseApp as O, useOptionalBaseApp as P, FloatingButtonProps as Q, FloatingButton as R, SiteRuntimeClient as S, DatabaseAudience as T, UiLanguage as U, DatabaseUserMenuProps as V, DatabaseUserMenu as W, AttachmentImage as X, UiLanguageContext as Y, selectUiLanguage as Z, getUiLanguage as _, getDatabaseContext as a, initializeUiLanguage as a0, useUiLanguage as a1, resolveDatabaseContext as b, fetchAttachmentCover as c, buildAttachmentCoverUrl as d, fetchAttachmentDownloadUrl as e, fetch as f, getCurrentUser as g, buildDatabaseInvokeGetPath as h, invokeHttp as i, buildDatabaseInvokeFunctionPath as j, invokeDatabaseFunction as k, logout as l, invokeDatabaseMutationBatch as m, DatabaseAttachmentRef as n, openAttachmentDownload as o, DatabaseEnv as p, DatabaseFunctionResponse as q, requestEdit as r, siteRuntime as s, DatabaseFunctionInvocation as t, DatabaseFunctionInputMap as u, createSiteRuntimeClient as v, createSiteRuntimeFetch as w, invokeApi as x, uploadAttachment as y, openLink as z };
|