@openviking/react 0.0.0-stage → 0.1.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.
- package/README.md +82 -2
- package/dist/3~0.js +8 -0
- package/dist/a~0.js +21 -0
- package/dist/client/client.d.ts +12 -0
- package/dist/client/errors.d.ts +30 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/options.d.ts +101 -0
- package/dist/client/provider.d.ts +52 -0
- package/dist/client/types.d.ts +160 -0
- package/dist/client.js +239 -0
- package/dist/components/agent-connect/agent-connect.d.ts +4 -0
- package/dist/components/agent-connect/index.d.ts +1 -0
- package/dist/components/agent-connect/style.css +16 -0
- package/dist/components/agent-connect/style.js +0 -0
- package/dist/components/agent-connect/types.d.ts +175 -0
- package/dist/components/agent-connect.js +1 -0
- package/dist/components/file-preview/file-preview-body.d.ts +15 -0
- package/dist/components/file-preview/file-preview-header.d.ts +16 -0
- package/dist/components/file-preview/file-preview-icons.d.ts +2 -0
- package/dist/components/file-preview/file-preview-labels.d.ts +5 -0
- package/dist/components/file-preview/file-preview-operations.d.ts +1 -0
- package/dist/components/file-preview/file-preview.d.ts +17 -0
- package/dist/components/file-preview/index.d.ts +1 -0
- package/dist/components/file-preview/style.css +285 -0
- package/dist/components/file-preview/style.js +0 -0
- package/dist/components/file-preview/types.d.ts +435 -0
- package/dist/components/file-preview/use-file-preview-editing.d.ts +13 -0
- package/dist/components/file-preview.js +442 -0
- package/dist/components/file-tree/file-tree-body.d.ts +14 -0
- package/dist/components/file-tree/file-tree-dom.d.ts +4 -0
- package/dist/components/file-tree/file-tree-entry-row.d.ts +6 -0
- package/dist/components/file-tree/file-tree-icons.d.ts +8 -0
- package/dist/components/file-tree/file-tree-keyboard.d.ts +10 -0
- package/dist/components/file-tree/file-tree-labels.d.ts +5 -0
- package/dist/components/file-tree/file-tree-row-context.d.ts +24 -0
- package/dist/components/file-tree/file-tree-rows.d.ts +12 -0
- package/dist/components/file-tree/file-tree-tooltip.d.ts +11 -0
- package/dist/components/file-tree/file-tree.d.ts +4 -0
- package/dist/components/file-tree/index.d.ts +1 -0
- package/dist/components/file-tree/style.css +244 -0
- package/dist/components/file-tree/style.js +0 -0
- package/dist/components/file-tree/types.d.ts +406 -0
- package/dist/components/file-tree/use-file-tree-actions.d.ts +10 -0
- package/dist/components/file-tree.js +1 -0
- package/dist/components/scope-switcher/index.d.ts +1 -0
- package/dist/components/scope-switcher/scope-keyboard.d.ts +2 -0
- package/dist/components/scope-switcher/scope-panel.d.ts +5 -0
- package/dist/components/scope-switcher/scope-selector.d.ts +2 -0
- package/dist/components/scope-switcher/scope-switcher.d.ts +6 -0
- package/dist/components/scope-switcher/style.css +248 -0
- package/dist/components/scope-switcher/style.js +0 -0
- package/dist/components/scope-switcher/types.d.ts +367 -0
- package/dist/components/scope-switcher.js +3 -0
- package/dist/components/style.css +811 -0
- package/dist/components/style.js +0 -0
- package/dist/components/tui/index.d.ts +1 -0
- package/dist/components/tui/style.css +16 -0
- package/dist/components/tui/style.js +0 -0
- package/dist/components/tui/tui.d.ts +3 -0
- package/dist/components/tui/types.d.ts +485 -0
- package/dist/components/tui.js +1 -0
- package/dist/f~0.js +284 -0
- package/dist/icons/index.d.ts +23 -0
- package/dist/icons.js +25 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +8 -0
- package/dist/i~0.js +21 -0
- package/dist/lk~0.js +220 -0
- package/dist/l~0.js +44 -0
- package/dist/modules/console/console.d.ts +4 -0
- package/dist/modules/console/index.d.ts +1 -0
- package/dist/modules/console/style.css +29 -0
- package/dist/modules/console/style.js +0 -0
- package/dist/modules/console/types.d.ts +101 -0
- package/dist/modules/console.js +1 -0
- package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +10 -0
- package/dist/modules/file-browser/file-browser.d.ts +6 -0
- package/dist/modules/file-browser/index.d.ts +1 -0
- package/dist/modules/file-browser/style.css +75 -0
- package/dist/modules/file-browser/style.js +0 -0
- package/dist/modules/file-browser/types.d.ts +101 -0
- package/dist/modules/file-browser.js +1 -0
- package/dist/modules/scope-cascade/controller.d.ts +6 -0
- package/dist/modules/scope-cascade/index.d.ts +3 -0
- package/dist/modules/scope-cascade/scope-cascade.d.ts +3 -0
- package/dist/modules/scope-cascade/style.css +250 -0
- package/dist/modules/scope-cascade/style.js +0 -0
- package/dist/modules/scope-cascade/types.d.ts +39 -0
- package/dist/modules/scope-cascade/use-scope-cascade.d.ts +5 -0
- package/dist/modules/scope-cascade.js +1 -0
- package/dist/modules/style.css +385 -0
- package/dist/modules/style.js +0 -0
- package/dist/modules/task-center/columns.d.ts +129 -0
- package/dist/modules/task-center/index.d.ts +1 -0
- package/dist/modules/task-center/style.css +29 -0
- package/dist/modules/task-center/style.js +0 -0
- package/dist/modules/task-center/task-center.d.ts +4 -0
- package/dist/modules/task-center/types.d.ts +168 -0
- package/dist/modules/task-center.js +1 -0
- package/dist/n~0.js +499 -0
- package/dist/style.css +1198 -0
- package/dist/style.js +0 -0
- package/dist/u~0.js +8 -0
- package/package.json +103 -4
package/README.md
CHANGED
|
@@ -1,3 +1,83 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @openviking/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English / [中文](README_CN.md)
|
|
4
|
+
|
|
5
|
+
React foundations for OpenViking AI application interfaces: build tooling, documentation, layered directories, and scoped styles. FileTree and FilePreview provide placeholder views, alongside five file-type icons. Three business module placeholders support early layout integration; ScopeCascade provides a working cascade Hook and composition.
|
|
6
|
+
|
|
7
|
+
This package inherits the repository's AGPL-3.0-only license. The release workflow publishes it to npm when a `react@<version>` tag matches the version in this package's manifest.
|
|
8
|
+
|
|
9
|
+
## Module map
|
|
10
|
+
|
|
11
|
+
| Source directory | Public entry | Responsibility |
|
|
12
|
+
| ---------------------------------------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
13
|
+
| [components/file-tree](./src/components/file-tree/README.md) | `@openviking/react/components/file-tree` | Directory tree rendering, expansion, selection and event callbacks; view is a placeholder |
|
|
14
|
+
| [components/file-preview](./src/components/file-preview/README.md) | `@openviking/react/components/file-preview` | Read-only preview state and extension tabs; view is a placeholder |
|
|
15
|
+
| [components/tui](./src/components/tui/README.md) | `@openviking/react/components/tui` | Reviewed command record, result and input types; view is a placeholder |
|
|
16
|
+
| [components/scope-switcher](./src/components/scope-switcher/README.md) | `@openviking/react/components/scope-switcher` | Stateless scope layout and independent ScopeSelector options, panels and search |
|
|
17
|
+
| [components/agent-connect](./src/components/agent-connect/README.md) | `@openviking/react/components/agent-connect` | Agent connection tab, list and detail contract; view is a placeholder |
|
|
18
|
+
| [modules](./src/modules/README.md) | `@openviking/react/modules/<module>` | ScopeCascade Hooks and composition, plus three placeholder business modules |
|
|
19
|
+
| [client](./src/client/index.ts) | `@openviking/react/client` | Framework-neutral request client: `createOvClient`, `OvClient`, `OvClientError` |
|
|
20
|
+
| [hooks](./src/hooks/README.md), [utils](./src/utils/README.md) | Internal only | Cross-module Hooks and pure utilities |
|
|
21
|
+
|
|
22
|
+
Components implement their reviewed contracts incrementally. FileTree renders every documented row type with keyboard interaction; FilePreview implements the tab shell, header actions and the plain-text preview and editing foundation, with its body not yet wired to FileViewer. ScopeSwitcher is a stateless layout container; independently rendered ScopeSelector children own visibility, with host-owned per-level data subscriptions, search and requests. Tui and AgentConnect render a fixed-size shell only. Limits are described in each component's own docs. The package also ships five file-type icons.
|
|
23
|
+
|
|
24
|
+
Components receive view data and state through props and express user intent through callbacks, following the [component directory conventions](./src/components/AGENTS.md). [modules](./src/modules/README.md) plan Hooks and views per business capability: Hooks load data, hold state and expose operations, and composite views wire them into components. Full pages and product-specific flows belong to the host; the admin console is out of scope for this phase. `file-browser`, `console` and `task-center` currently ship placeholder components, base Props / Labels types and styles so hosts can integrate layout first; business Hooks, data loading and cross-component coordination are not implemented yet.
|
|
25
|
+
|
|
26
|
+
Modules consume the native OpenViking API through a shared Client by default, with the Provider supplying `baseURL`, headers and other configuration, and modules or standalone Hooks overriding individual fields through `requestOptions`. Standard integration needs no per-module Adapter; nonstandard gateways are adapted at the host's request boundary. The request contract — `OvRequestOptions`, `OvClient` and `OvClientError` — comes from the `@openviking/react/client` subpath, which ships a `fetch`-based `createOvClient`; the Provider is exported from the same subpath; these native API module Hooks are not implemented yet. ScopeCascade instead accepts three host API adapters and needs no Provider. See [request conventions](./src/modules/README.md#request-conventions-and-default-configuration).
|
|
27
|
+
|
|
28
|
+
### Props conventions
|
|
29
|
+
|
|
30
|
+
The same props are consumed by different hosts. Hosts differ in flows and interfaces while matching in interaction and UI, so:
|
|
31
|
+
|
|
32
|
+
- Components receive **already adapted data**: file entries, tabs and content sources are mapped into package types by module Hooks or the host, and components reference no host data model.
|
|
33
|
+
- State is expressed with controlled fields, and callbacks only report intent without returning business data.
|
|
34
|
+
- Copy is passed through labels, defaulting to English; hosts map i18next or Starling in their integration layer.
|
|
35
|
+
- Icons, extension tabs, extra fields and toolbar actions come in as slots or nodes; components bind to no third-party UI library.
|
|
36
|
+
- List components render the rows or items the caller has already expanded; paging, loading, error and empty states come from module Hooks or the host.
|
|
37
|
+
|
|
38
|
+
## Public entries and styles
|
|
39
|
+
|
|
40
|
+
- The root entry exports each component and each business module placeholder with its main Props type (`<Component>Props`) only — currently `FileTree`, `Tui`, `ScopeSwitcher`, `ScopeSelector`, `ScopeCascade`, `AgentConnect` and the three business module placeholders. Row types, option types, handles and label bags come from the `components/<component>` and `modules/<module>` subpaths. `FilePreview` is not on the root entry: its types reference the optional `@ark-design/ui`, and putting it there would make that peer required. ScopeCascade exports a working three-level composition and per-level subscription Hooks from `modules/scope-cascade`; other business modules remain placeholders. No aggregate `@openviking/react/components` or `@openviking/react/modules` JavaScript entry. Package exports are listed explicitly and internal files stay closed.
|
|
41
|
+
- Components expose only the explicitly listed layered subpaths, with no legacy path aliases.
|
|
42
|
+
- JS entries share implementations and never load CSS implicitly. Whole-package, component-set and single-module stylesheets are built from the same source, so import the scope you need.
|
|
43
|
+
|
|
44
|
+
| Scope | CSS entry |
|
|
45
|
+
| ---------------------- | ------------------------------------------------- |
|
|
46
|
+
| Whole package | `@openviking/react/style.css` |
|
|
47
|
+
| Component set | `@openviking/react/components/style.css` |
|
|
48
|
+
| Single component | `@openviking/react/components/<module>/style.css` |
|
|
49
|
+
| Business module set | `@openviking/react/modules/style.css` |
|
|
50
|
+
| Single business module | `@openviking/react/modules/<module>/style.css` |
|
|
51
|
+
|
|
52
|
+
Each CSS entry works standalone, and the whole-package CSS already includes module placeholder styles. Once real capability lands, module CSS must also include the composite view and the styles of the components it uses; using a module Hook alone needs no CSS. Cross-module public Hooks open `@openviking/react/hooks` only after a real implementation; module-specific public Hooks are exported from their module entry, and private Hooks and utilities stay out of public exports.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { FileBrowser } from '@openviking/react/modules/file-browser';
|
|
56
|
+
import '@openviking/react/modules/file-browser/style.css';
|
|
57
|
+
|
|
58
|
+
<FileBrowser
|
|
59
|
+
labels={{ title: 'File browser', description: 'Placeholder component.' }}
|
|
60
|
+
/>;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The other modules export `Console` and `TaskCenter`; all currently accept `className`, `style` and `labels`, and need no Provider or request configuration.
|
|
64
|
+
|
|
65
|
+
Experience dashboards belong to preview extensions; task progress starts inside its owning module; API Key display controls are reused on demand while credential creation and management belong to the host. No separate modules are added for these now.
|
|
66
|
+
|
|
67
|
+
## Icons
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { PdfIcon } from '@openviking/react/icons';
|
|
71
|
+
|
|
72
|
+
<PdfIcon width={20} height={20} className="file-icon" alt="PDF" />;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Icons render as 16 × 16 images by default. Decorative icons can keep the empty `alt`, while icons that convey file type can provide a description. SVGs are inlined into the build output, and hosts consume them directly from the package exports.
|
|
76
|
+
|
|
77
|
+
React and ReactDOM are peer dependencies (`^18.2.0 || ^19.0.0`), automatically externalized by Rslib. Rslib emits shared ESM JavaScript and declarations, plus independently built CSS entries. The public `@openviking/react/style.css` entry resolves to `dist/style.css`. Styles are scoped and do not reset application styles.
|
|
78
|
+
|
|
79
|
+
From `frontend/`, run `npm run build:lib` to generate `packages/react/dist/`. See the [workspace README](../../README.md) for documentation development and deployment.
|
|
80
|
+
|
|
81
|
+
### ScopeCascade
|
|
82
|
+
|
|
83
|
+
Pass three stable API adapter functions to `useScopeCascade({ loadLibraries, loadSpaces, loadUsers })`, then render `<ScopeCascade controller={controller} />`. Adapters return `{ id, label }` options and receive an `AbortSignal`. The module handles dependent requests, descendant resets, loading, errors, retries and stale responses. Each selector subscribes independently; the Hook caller does not subscribe to request state. Import the Hook and composition from `@openviking/react/modules/scope-cascade` and its CSS from the corresponding `/style.css` entry.
|
package/dist/3~0.js
ADDED
package/dist/a~0.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
function Console({ className, style, labels }) {
|
|
3
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
4
|
+
className: [
|
|
5
|
+
'ov-module-placeholder',
|
|
6
|
+
className
|
|
7
|
+
].filter(Boolean).join(' '),
|
|
8
|
+
style: style,
|
|
9
|
+
children: [
|
|
10
|
+
/*#__PURE__*/ jsx("p", {
|
|
11
|
+
className: "ov-module-placeholder__title",
|
|
12
|
+
children: labels?.conversation ?? 'Console'
|
|
13
|
+
}),
|
|
14
|
+
/*#__PURE__*/ jsx("p", {
|
|
15
|
+
className: "ov-module-placeholder__description",
|
|
16
|
+
children: labels?.description ?? 'Placeholder. Functionality is not available yet.'
|
|
17
|
+
})
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export { Console };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OvClient, OvClientOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 用 `fetch` 实现 {@link OvClient}。这是库自带的默认传输层,调用方只需给服务
|
|
4
|
+
* 地址和身份字段;要换传输方式(例如复用宿主已有的 axios 实例)时才需要自己
|
|
5
|
+
* 实现 {@link OvClient}。
|
|
6
|
+
*
|
|
7
|
+
* Implements {@link OvClient} with `fetch`. This is the library's default
|
|
8
|
+
* transport, so a caller supplies only the service address and identity fields.
|
|
9
|
+
* Implement {@link OvClient} yourself only to replace the transport, for example
|
|
10
|
+
* to reuse the host's existing axios instance.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createOvClient(options?: OvClientOptions): OvClient;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 请求失败的统一错误。区分 HTTP 失败与原生响应里的 `status: 'error'`,
|
|
3
|
+
* 保留服务端错误码、状态与请求标识。
|
|
4
|
+
* The single error a failed request raises. It distinguishes an HTTP failure
|
|
5
|
+
* from a native `status: 'error'` response and keeps the server error code,
|
|
6
|
+
* status and request identifier.
|
|
7
|
+
*/
|
|
8
|
+
export declare class OvClientError extends Error {
|
|
9
|
+
/** 服务端错误码,HTTP 失败时为 `HTTP_<status>` 或 `NETWORK_ERROR`。 */
|
|
10
|
+
readonly code: string;
|
|
11
|
+
/** HTTP 状态码;请求未到达服务端时省略。 */
|
|
12
|
+
readonly statusCode?: number;
|
|
13
|
+
/** 服务端返回的附加信息。 */
|
|
14
|
+
readonly details?: unknown;
|
|
15
|
+
/** 服务端请求标识,便于与服务端日志对应。 */
|
|
16
|
+
readonly requestId?: string;
|
|
17
|
+
/** 原始响应体,便于诊断无法归一的响应。 */
|
|
18
|
+
readonly responseBody?: unknown;
|
|
19
|
+
constructor(options: {
|
|
20
|
+
code: string;
|
|
21
|
+
message: string;
|
|
22
|
+
statusCode?: number;
|
|
23
|
+
details?: unknown;
|
|
24
|
+
requestId?: string;
|
|
25
|
+
responseBody?: unknown;
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** 判断一个值是否为 {@link OvClientError}。 */
|
|
30
|
+
export declare function isOvClientError(value: unknown): value is OvClientError;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createOvClient } from './client.js';
|
|
2
|
+
export { OvClientError, isOvClientError } from './errors.js';
|
|
3
|
+
export { OpenVikingProvider, type OpenVikingProviderProps, } from './provider.js';
|
|
4
|
+
export type { OvClient, OvClientOptions, OvErrorEnvelope, OvIdentityValue, OvQueryValue, OvRequestOptions, OvRequestSpec, OvResolvedOptions, OvSuccessEnvelope, } from './types.js';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { OvClientOptions, OvIdentityValue, OvQueryValue, OvRequestOptions, OvResolvedOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 身份字段到请求头的映射。宿主传字段值,Client 负责组装,不暴露 header 名称。
|
|
4
|
+
* Mapping from identity fields to request headers. A host passes field values and
|
|
5
|
+
* the Client assembles the headers, so header names stay internal.
|
|
6
|
+
*/
|
|
7
|
+
export declare const IDENTITY_HEADERS: {
|
|
8
|
+
readonly apiKey: 'X-API-Key';
|
|
9
|
+
readonly accountId: 'X-OpenViking-Account';
|
|
10
|
+
readonly userId: 'X-OpenViking-User';
|
|
11
|
+
readonly resourceId: 'V-Resource-Id';
|
|
12
|
+
};
|
|
13
|
+
export type OvIdentityField = keyof typeof IDENTITY_HEADERS;
|
|
14
|
+
/**
|
|
15
|
+
* 求值一层身份字段,保留空字符串,以便区分「未提供」与「显式清除」。
|
|
16
|
+
* Evaluates one identity layer, keeping empty strings so that "absent" and
|
|
17
|
+
* "explicitly cleared" stay distinguishable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveIdentityLayer(options: OvRequestOptions | undefined): Promise<OvIdentityLayer>;
|
|
20
|
+
/**
|
|
21
|
+
* 合并两层身份字段:近的一层覆盖远的一层,近层显式传空字符串即清除该字段。
|
|
22
|
+
* Merges two identity layers: the nearer one wins, and an explicit empty string
|
|
23
|
+
* in it clears the field.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergeIdentityLayers(far: OvIdentityLayer, near: OvIdentityLayer): OvIdentityLayer;
|
|
26
|
+
/**
|
|
27
|
+
* 把身份字段转成请求头。空字符串表示清除,不发送对应请求头。
|
|
28
|
+
* Turns identity fields into headers. An empty string means cleared, so that
|
|
29
|
+
* header is not sent.
|
|
30
|
+
*/
|
|
31
|
+
export declare function toHeaders(layer: OvIdentityLayer): Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* 解析客户端级配置。`baseURL` 缺省为空字符串,表示浏览器同源请求。
|
|
34
|
+
*
|
|
35
|
+
* 身份层由调用方求值后传入:函数形式的身份字段每次请求只应求值一次,父层配置
|
|
36
|
+
* 与请求覆盖必须复用同一份结果,否则会重复刷新凭证并可能发出旧值。
|
|
37
|
+
*
|
|
38
|
+
* Resolves client-level configuration. A missing `baseURL` is an empty string,
|
|
39
|
+
* meaning a same-origin browser request.
|
|
40
|
+
*
|
|
41
|
+
* The caller passes an already-evaluated identity layer: a function-form
|
|
42
|
+
* identity field must be evaluated once per request, and both the parent
|
|
43
|
+
* configuration and the request override must reuse that one result. Evaluating
|
|
44
|
+
* twice would refresh a credential twice and could send the older value.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveClientOptions(options: OvClientOptions, identity: OvIdentityLayer): OvResolvedOptions;
|
|
47
|
+
/**
|
|
48
|
+
* 在已解析的客户端配置上叠加一次请求的覆盖。`baseURL` 传空字符串表示同源,
|
|
49
|
+
* 只有 `undefined` 才继承。
|
|
50
|
+
*
|
|
51
|
+
* Applies one request's override on top of resolved client configuration. An
|
|
52
|
+
* empty `baseURL` means same origin; only `undefined` inherits.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveRequestOptions(local: OvRequestOptions | undefined, parent: OvResolvedOptions, mergedLayer: OvIdentityLayer): OvResolvedOptions;
|
|
55
|
+
/**
|
|
56
|
+
* 拼接服务地址与接口路径。拼接只在这里做:`/gateway/ov` 加 `/api/v1/fs/ls`
|
|
57
|
+
* 得到 `/gateway/ov/api/v1/fs/ls`,接口路径以 `/` 开头也不会丢掉前缀。
|
|
58
|
+
*
|
|
59
|
+
* Joins the service address and the API path. Joining happens only here:
|
|
60
|
+
* `/gateway/ov` plus `/api/v1/fs/ls` yields `/gateway/ov/api/v1/fs/ls`, and a
|
|
61
|
+
* leading `/` in the path never drops the prefix.
|
|
62
|
+
*/
|
|
63
|
+
export declare function joinUrl(baseURL: string, path: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* 把查询参数序列化为查询串,跳过 `undefined` 与 `null`,数组按键重复。
|
|
66
|
+
* Serialises query parameters, skipping `undefined` and `null`; arrays repeat
|
|
67
|
+
* the key.
|
|
68
|
+
*/
|
|
69
|
+
export declare function buildQuery(query: Readonly<Record<string, OvQueryValue>> | undefined): string;
|
|
70
|
+
/**
|
|
71
|
+
* 一层已求值的身份字段:`undefined` 表示未提供,空字符串表示显式清除,其余
|
|
72
|
+
* 为要发送的值。
|
|
73
|
+
* One evaluated identity layer: `undefined` means absent, an empty string means
|
|
74
|
+
* explicitly cleared, anything else is the value to send.
|
|
75
|
+
*/
|
|
76
|
+
export type OvIdentityLayer = Partial<Record<OvIdentityField, string>>;
|
|
77
|
+
/**
|
|
78
|
+
* 一层未求值的身份字段,供 Provider 逐层合并。函数形式原样保留,由客户端在
|
|
79
|
+
* 每次请求时求值。
|
|
80
|
+
* One unevaluated identity layer for Provider merging. Function values are kept
|
|
81
|
+
* as-is so the client evaluates them per request.
|
|
82
|
+
*/
|
|
83
|
+
export type OvIdentityConfig = Partial<Record<OvIdentityField, OvIdentityValue>>;
|
|
84
|
+
/** Provider 已解析的配置,供嵌套 Provider 继续继承。 */
|
|
85
|
+
export interface OvProviderBase {
|
|
86
|
+
baseURL?: string;
|
|
87
|
+
credentials?: RequestCredentials;
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
/** 传输层覆盖。内层未声明时继承外层,否则内层会丢掉外层的自定义 fetch。 */
|
|
90
|
+
fetch?: typeof globalThis.fetch;
|
|
91
|
+
identity: OvIdentityConfig;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 把本层配置叠加到父层之上。只覆盖本层显式声明的字段:`undefined` 表示继承,
|
|
95
|
+
* 空字符串表示清除继承到的值。
|
|
96
|
+
*
|
|
97
|
+
* Applies one layer of configuration on top of its parent. Only fields this
|
|
98
|
+
* layer declares are overridden: `undefined` inherits, and an empty string
|
|
99
|
+
* clears the inherited value.
|
|
100
|
+
*/
|
|
101
|
+
export declare function mergeProviderConfig(inherited: OvProviderBase | undefined, local: OvClientOptions): OvProviderBase;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { OvClient, OvClientOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* {@link OpenVikingProvider} 的属性。字段与 {@link OvClientOptions} 同形:
|
|
5
|
+
* 服务地址、身份与作用域、Cookie 策略,都按字段传值。
|
|
6
|
+
* Props of {@link OpenVikingProvider}, the same shape as {@link OvClientOptions}:
|
|
7
|
+
* the service address, identity and scope, and the cookie policy are all passed
|
|
8
|
+
* as fields.
|
|
9
|
+
*/
|
|
10
|
+
export interface OpenVikingProviderProps extends OvClientOptions {
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 向子树下发请求配置。模块通过内部的 `useOvClient` 取用,宿主只需在应用根部
|
|
15
|
+
* 配置一次服务地址与身份字段,不必自己组装请求头。
|
|
16
|
+
*
|
|
17
|
+
* 开源版传 `apiKey`、`accountId`、`userId`;商业版由浏览器 Cookie 鉴权,只传
|
|
18
|
+
* `accountId`、`userId`、`resourceId`,并按需把 `credentials` 设为 `include`。
|
|
19
|
+
*
|
|
20
|
+
* 嵌套时内层只覆盖自己声明的字段,其余继承外层:外层配好服务地址与凭证后,
|
|
21
|
+
* 内层可以只改 `userId`。显式传空字符串表示清除继承到的值。
|
|
22
|
+
*
|
|
23
|
+
* 不传 `baseURL` 时按浏览器同源请求。挂载本身不发请求,也不读取浏览器里保存
|
|
24
|
+
* 的凭证。
|
|
25
|
+
*
|
|
26
|
+
* Provides request configuration to a subtree. Modules read it through the
|
|
27
|
+
* internal `useOvClient`, so a host configures the service address and identity
|
|
28
|
+
* fields once at the application root and never assembles headers itself.
|
|
29
|
+
*
|
|
30
|
+
* The open-source edition passes `apiKey`, `accountId` and `userId`; the
|
|
31
|
+
* commercial edition authenticates with a browser cookie, so it passes
|
|
32
|
+
* `accountId`, `userId` and `resourceId`, and sets `credentials` to `include`
|
|
33
|
+
* where needed.
|
|
34
|
+
*
|
|
35
|
+
* Nesting overrides only the fields the inner Provider declares and inherits the
|
|
36
|
+
* rest, so an outer Provider can own the service address and credential while an
|
|
37
|
+
* inner one changes only `userId`. An explicit empty string clears an inherited
|
|
38
|
+
* value.
|
|
39
|
+
*
|
|
40
|
+
* Without `baseURL` it targets the browser's own origin. Mounting it sends no
|
|
41
|
+
* request and reads no credential stored in the browser.
|
|
42
|
+
*/
|
|
43
|
+
export declare function OpenVikingProvider({ baseURL, apiKey, accountId, userId, resourceId, credentials, signal, fetch, children, }: OpenVikingProviderProps): import("react").JSX.Element;
|
|
44
|
+
/**
|
|
45
|
+
* 读取最近的 Provider 提供的客户端。仅供模块内部使用,不从包入口导出:
|
|
46
|
+
* 调用方不需要知道该发什么请求,也就不会直接用它。
|
|
47
|
+
*
|
|
48
|
+
* Reads the client from the nearest Provider. Internal to modules and not
|
|
49
|
+
* exported from the package: a caller does not need to know which requests to
|
|
50
|
+
* send, so it has no reason to use this directly.
|
|
51
|
+
*/
|
|
52
|
+
export declare function useOvClient(): OvClient | null;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一个身份字段的取值:字符串,或每次请求重新求值的函数。
|
|
3
|
+
* Value of one identity field: a string, or a function re-evaluated per request.
|
|
4
|
+
*/
|
|
5
|
+
export type OvIdentityValue = string | (() => string | Promise<string>);
|
|
6
|
+
/**
|
|
7
|
+
* 一次请求的身份与作用域。字段省略表示继承上层配置;显式传空字符串表示移除
|
|
8
|
+
* 该字段继承到的值,请求里不再发送对应请求头。
|
|
9
|
+
*
|
|
10
|
+
* 这些字段一一对应 OpenViking 的请求头,宿主传值即可,不需要自己组装 header:
|
|
11
|
+
* `apiKey` → `X-API-Key`,`accountId` → `X-OpenViking-Account`,`userId` →
|
|
12
|
+
* `X-OpenViking-User`,`resourceId` → `V-Resource-Id`。
|
|
13
|
+
*
|
|
14
|
+
* Identity and scope of one request. An omitted field inherits from the layer
|
|
15
|
+
* above; an explicit empty string removes the inherited value so the header is
|
|
16
|
+
* not sent.
|
|
17
|
+
*
|
|
18
|
+
* The fields map one to one onto OpenViking's request headers, so a host passes
|
|
19
|
+
* values instead of assembling headers: `apiKey` → `X-API-Key`, `accountId` →
|
|
20
|
+
* `X-OpenViking-Account`, `userId` → `X-OpenViking-User`, `resourceId` →
|
|
21
|
+
* `V-Resource-Id`.
|
|
22
|
+
*/
|
|
23
|
+
export interface OvRequestOptions {
|
|
24
|
+
/**
|
|
25
|
+
* 服务地址及可选网关前缀,不含原生接口的 `/api/v1`。省略时继承上层配置,
|
|
26
|
+
* 空字符串表示同源请求。
|
|
27
|
+
*
|
|
28
|
+
* Service address with an optional gateway prefix, excluding the native
|
|
29
|
+
* `/api/v1`. Omitted inherits the layer above; an empty string means a
|
|
30
|
+
* same-origin request.
|
|
31
|
+
*/
|
|
32
|
+
baseURL?: string;
|
|
33
|
+
/**
|
|
34
|
+
* 凭证。开源版为 `X-API-Key` 的取值;商业版由浏览器 Cookie 承载,无需传入。
|
|
35
|
+
* 函数形式每次请求重新求值,可读取轮换后的凭证。
|
|
36
|
+
*
|
|
37
|
+
* Credential. In the open-source edition it becomes `X-API-Key`; the
|
|
38
|
+
* commercial edition carries it in the browser cookie, so it is omitted
|
|
39
|
+
* there. A function is re-evaluated on every request, so it can read a rotated
|
|
40
|
+
* credential.
|
|
41
|
+
*/
|
|
42
|
+
apiKey?: OvIdentityValue;
|
|
43
|
+
/**
|
|
44
|
+
* OpenViking 账号 ID,对应数据空间。
|
|
45
|
+
* OpenViking account ID, which corresponds to the data space.
|
|
46
|
+
*/
|
|
47
|
+
accountId?: OvIdentityValue;
|
|
48
|
+
/**
|
|
49
|
+
* 账号内的用户 ID。
|
|
50
|
+
* User ID within the account.
|
|
51
|
+
*/
|
|
52
|
+
userId?: OvIdentityValue;
|
|
53
|
+
/**
|
|
54
|
+
* 当前库 ID。数据面接口需要它确定请求落在哪个库。
|
|
55
|
+
* Current library ID. Data-plane requests need it to know which library they
|
|
56
|
+
* address.
|
|
57
|
+
*/
|
|
58
|
+
resourceId?: OvIdentityValue;
|
|
59
|
+
/**
|
|
60
|
+
* 调用方中止请求的信号。
|
|
61
|
+
* Signal the caller uses to abort the request.
|
|
62
|
+
*/
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 创建客户端时的配置。在 {@link OvRequestOptions} 之上增加 Cookie 策略与传输层
|
|
67
|
+
* 设置。
|
|
68
|
+
* Configuration when creating a client: {@link OvRequestOptions} plus the cookie
|
|
69
|
+
* policy and transport settings.
|
|
70
|
+
*/
|
|
71
|
+
export interface OvClientOptions extends OvRequestOptions {
|
|
72
|
+
/**
|
|
73
|
+
* 是否携带浏览器 Cookie。商业版的数据面与控制面接口都依赖 Cookie 鉴权,
|
|
74
|
+
* 跨源调用时需要设为 `include`。
|
|
75
|
+
*
|
|
76
|
+
* Whether browser cookies are sent. The commercial edition authenticates both
|
|
77
|
+
* data-plane and control-plane requests with a cookie, so a cross-origin call
|
|
78
|
+
* needs `include`.
|
|
79
|
+
*/
|
|
80
|
+
credentials?: RequestCredentials;
|
|
81
|
+
/**
|
|
82
|
+
* 自定义 fetch 实现,用于测试或在没有全局 fetch 的环境运行。
|
|
83
|
+
* A custom fetch implementation, for tests or environments without a global
|
|
84
|
+
* fetch.
|
|
85
|
+
*/
|
|
86
|
+
fetch?: typeof globalThis.fetch;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 配置逐字段解析后的结果,所有字段均已确定。
|
|
90
|
+
* The result of resolving configuration field by field, with every field
|
|
91
|
+
* decided.
|
|
92
|
+
*/
|
|
93
|
+
export interface OvResolvedOptions {
|
|
94
|
+
baseURL: string;
|
|
95
|
+
credentials: RequestCredentials;
|
|
96
|
+
headers: Readonly<Record<string, string>>;
|
|
97
|
+
signal?: AbortSignal;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 原生接口的请求描述。Client 只按 method、path、query 与 body 发请求,不解析
|
|
101
|
+
* 业务含义。
|
|
102
|
+
* A native API request. The Client sends it by method, path, query and body
|
|
103
|
+
* without interpreting the payload.
|
|
104
|
+
*/
|
|
105
|
+
export interface OvRequestSpec {
|
|
106
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
|
|
107
|
+
/**
|
|
108
|
+
* 以 `/` 开头的接口路径,不含服务地址与网关前缀。
|
|
109
|
+
* API path starting with `/`, without the service address or gateway prefix.
|
|
110
|
+
*/
|
|
111
|
+
path: string;
|
|
112
|
+
query?: Readonly<Record<string, OvQueryValue>>;
|
|
113
|
+
body?: unknown;
|
|
114
|
+
/**
|
|
115
|
+
* 本次请求的身份、作用域与服务地址覆盖,例如切换到另一个库或另一个网关。
|
|
116
|
+
* Identity, scope and service-address override for this request, for example
|
|
117
|
+
* switching to another library or another gateway.
|
|
118
|
+
*/
|
|
119
|
+
options?: OvRequestOptions;
|
|
120
|
+
}
|
|
121
|
+
/** 查询参数可接受的值;`undefined` 与 `null` 表示不发送。 */
|
|
122
|
+
export type OvQueryValue = string | number | boolean | null | undefined | readonly (string | number | boolean)[];
|
|
123
|
+
/**
|
|
124
|
+
* 原生接口的成功响应外壳。`result` 承载业务数据,其余字段是外层元数据。
|
|
125
|
+
* The success envelope of a native response. `result` carries the payload and
|
|
126
|
+
* the remaining fields are outer metadata.
|
|
127
|
+
*/
|
|
128
|
+
export interface OvSuccessEnvelope<TResult = unknown> {
|
|
129
|
+
result?: TResult;
|
|
130
|
+
status?: string;
|
|
131
|
+
[key: string]: unknown;
|
|
132
|
+
}
|
|
133
|
+
/** 原生接口的错误响应外壳。The error envelope of a native response. */
|
|
134
|
+
export interface OvErrorEnvelope {
|
|
135
|
+
status?: string;
|
|
136
|
+
error?: {
|
|
137
|
+
code?: string;
|
|
138
|
+
message?: string;
|
|
139
|
+
details?: unknown;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 框架无关的请求能力。库自带基于 `fetch` 的实现,宿主也可以自行实现以复用
|
|
144
|
+
* 已有请求层;模块只依赖本接口。
|
|
145
|
+
* Framework-neutral request capability. The library ships a `fetch`-based
|
|
146
|
+
* implementation, and a host may implement it to reuse an existing request
|
|
147
|
+
* layer; modules depend only on this interface.
|
|
148
|
+
*/
|
|
149
|
+
export interface OvClient {
|
|
150
|
+
/**
|
|
151
|
+
* 发一次请求并返回原生响应的 `result`。
|
|
152
|
+
* Sends one request and returns the native response's `result`.
|
|
153
|
+
*/
|
|
154
|
+
request<TResult>(spec: OvRequestSpec): Promise<TResult>;
|
|
155
|
+
/**
|
|
156
|
+
* 当前生效的服务地址,用于缓存键与订阅隔离。
|
|
157
|
+
* The effective service address, used to isolate caches and subscriptions.
|
|
158
|
+
*/
|
|
159
|
+
readonly baseURL: string;
|
|
160
|
+
}
|