@77-zhike/app-sdk 0.2.0-d7b1.2 → 0.2.0-d7b1.20
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 +281 -0
- package/package.json +17 -3
- package/src/cli/api-client.js +4 -0
- package/src/cli/browser-auth.js +64 -18
- package/src/cli/credential-store.js +21 -0
- package/src/cli/development-logs.js +5 -2
- package/src/cli/index.js +59 -42
- package/src/cli/local-commands.js +6 -3
- package/src/cli/logs.js +56 -0
- package/src/cli/project-init.js +111 -179
- package/src/cli/windows-credential-bridge.ps1 +131 -0
- package/src/cli/windows-credential-store.js +112 -0
- package/src/client/analysis.d.ts +4 -0
- package/src/client/analysis.js +12 -0
- package/src/client/destinations.d.ts +25 -0
- package/src/client/destinations.js +70 -0
- package/src/client/documents.d.ts +21 -0
- package/src/client/documents.js +39 -0
- package/src/client/external-url.js +9 -0
- package/src/client/index.d.ts +225 -3
- package/src/client/index.js +75 -3
- package/src/client/interactions.d.ts +23 -3
- package/src/client/interactions.js +53 -3
- package/src/client/points.generated.js +56 -0
- package/src/config.js +11 -7
- package/src/forms/array-contract.d.ts +32 -0
- package/src/forms/array-contract.js +138 -0
- package/src/forms/components.generated.js +2 -2
- package/src/forms/factory.js +21 -7
- package/src/forms/field-array.d.ts +16 -0
- package/src/forms/field-array.js +52 -0
- package/src/forms/index.d.ts +74 -3
- package/src/forms/index.js +2 -0
- package/src/forms/options.d.ts +7 -2
- package/src/forms/options.js +8 -1
- package/src/forms/record-options.d.ts +28 -0
- package/src/forms/record-options.js +92 -0
- package/src/forms/schema.d.ts +73 -9
- package/src/forms/schema.js +128 -0
- package/src/forms/state.d.ts +30 -0
- package/src/forms/state.js +82 -0
- package/src/forms/validation.d.ts +9 -0
- package/src/forms/validation.js +81 -0
- package/src/forms/values.d.ts +5 -0
- package/src/forms/values.js +38 -0
- package/src/jsx-dev-runtime.d.ts +2 -0
- package/src/jsx-dev-runtime.js +1 -0
- package/src/jsx-runtime.d.ts +2 -0
- package/src/jsx-runtime.js +1 -0
- package/src/server/agents/index.d.ts +62 -0
- package/src/server/agents/index.js +40 -0
- package/src/server/index.d.ts +60 -5
- package/src/server/index.js +43 -0
- package/src/server/steps/index.d.ts +71 -0
- package/src/server/steps/index.js +15 -0
- package/src/server/triggers/index.d.ts +68 -0
- package/src/server/triggers/index.js +27 -0
- package/src/server/workflow-blocks/index.d.ts +72 -0
- package/src/server/workflow-blocks/index.js +32 -0
- package/src/toolchain/agents/discovery.js +126 -0
- package/src/toolchain/agents/exposure.js +31 -0
- package/src/toolchain/agents/manifest.js +84 -0
- package/src/toolchain/ai-capabilities.js +69 -0
- package/src/toolchain/allowed-packages.json +7 -0
- package/src/toolchain/dependency-policy.js +181 -0
- package/src/toolchain/index.js +0 -88
- package/src/toolchain/real-build.js +135 -27
- package/src/toolchain/source-discovery.js +330 -81
- package/src/toolchain/workflow-blocks/discovery.js +133 -0
- package/src/toolchain/workflow-steps/manifest.js +99 -0
- package/src/toolchain/workflow-triggers/manifest.js +47 -0
- package/src/ui/components.generated.js +4 -1
- package/src/ui/conversation.d.ts +81 -0
- package/src/ui/conversation.js +82 -0
- package/src/ui/data-table-model.d.ts +14 -0
- package/src/ui/data-table-model.js +98 -0
- package/src/ui/data-table.d.ts +70 -0
- package/src/ui/data-table.js +74 -0
- package/src/ui/events.d.ts +10 -0
- package/src/ui/factory.js +87 -3
- package/src/ui/index.d.ts +351 -8
- package/src/ui/index.js +1 -1
- package/src/ui/jsx.generated.d.ts +359 -0
- package/src/ui/native-dom.d.ts +49 -0
- package/src/ui/native-dom.js +44 -0
- package/src/ui/scroll-viewport.d.ts +22 -0
- package/src/ui/scroll-viewport.js +23 -0
- package/src/ui/slider.d.ts +27 -0
- package/src/ui/slider.js +26 -0
- package/src/ui/style.d.ts +5 -0
- package/src/ui/style.generated.js +2 -0
- package/src/ui/style.js +15 -0
- package/src/ui/text-selection.d.ts +22 -0
- package/src/ui/text-selection.js +23 -0
- package/src/ui/validation.js +86 -0
- package/src/cli/validate-bundle.js +0 -36
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
import { publicComponentNames } from '../ui/components.generated.js';
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
5
|
import { dirname, relative, resolve, sep } from "node:path";
|
|
5
6
|
import { build } from "esbuild";
|
|
6
7
|
import ts from "typescript";
|
|
7
8
|
|
|
9
|
+
import { agentManifest, stripPath } from "./agents/discovery.js";
|
|
8
10
|
import { serializeWebhookResponse } from "./webhook-response.js";
|
|
9
11
|
|
|
10
12
|
import { TOOLING_VERSION } from "../config.js";
|
|
11
13
|
import { ZhikeCliError } from "../errors.js";
|
|
12
14
|
import { readProjectBinding } from "../project-binding.js";
|
|
13
15
|
import { canonicalJsonBytes } from "./canonical-json.js";
|
|
14
|
-
import { discoverAppSources } from "./source-discovery.js";
|
|
16
|
+
import { discoverAppSources, validateImports } from "./source-discovery.js";
|
|
17
|
+
import { createDependencyPolicyPlugin } from "./dependency-policy.js";
|
|
15
18
|
import { createTransportTar } from "./transport-tar.js";
|
|
16
19
|
|
|
17
20
|
export const APP_BUNDLE_PACKAGE_FORMAT = "zhike.app-bundle.v1";
|
|
@@ -32,18 +35,21 @@ export async function buildAppBundle({
|
|
|
32
35
|
} = {}) {
|
|
33
36
|
await readProjectBinding(projectDirectory, expectedEnvironment);
|
|
34
37
|
const sources = await discoverAppSources(projectDirectory);
|
|
38
|
+
let clientBytes, serverBytes;
|
|
39
|
+
try {
|
|
40
|
+
clientBytes = sources.frontendExtensions.length > 0
|
|
41
|
+
? await buildRemoteReactClient(projectDirectory, sources, development) : null;
|
|
42
|
+
serverBytes = sources.lifecycleEvents.length > 0 ||
|
|
43
|
+
sources.serverFunctions.length > 0 ||
|
|
44
|
+
sources.webhookHandlers.length > 0 ||
|
|
45
|
+
sources.workflowSteps.length > 0 ||
|
|
46
|
+
sources.workflowTriggers.length > 0 || sources.agents.length > 0 || sources.actions.length > 0
|
|
47
|
+
? await buildServerArtifact(projectDirectory, sources) : null;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const policyError = error.errors?.find(item => item.detail instanceof ZhikeCliError)?.detail;
|
|
50
|
+
throw policyError ?? error;
|
|
51
|
+
}
|
|
35
52
|
await assertTypeScriptProgram(projectDirectory, sources);
|
|
36
|
-
|
|
37
|
-
const clientBytes =
|
|
38
|
-
sources.frontendExtensions.length > 0
|
|
39
|
-
? await buildRemoteReactClient(projectDirectory, sources, development)
|
|
40
|
-
: null;
|
|
41
|
-
const serverBytes =
|
|
42
|
-
sources.lifecycleEvents.length > 0 ||
|
|
43
|
-
sources.serverFunctions.length > 0 ||
|
|
44
|
-
sources.webhookHandlers.length > 0
|
|
45
|
-
? await buildServerArtifact(projectDirectory, sources)
|
|
46
|
-
: null;
|
|
47
53
|
const manifest = createManifest({
|
|
48
54
|
clientBytes,
|
|
49
55
|
serverBytes,
|
|
@@ -90,13 +96,15 @@ export async function buildAppBundle({
|
|
|
90
96
|
});
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
async function assertTypeScriptProgram(projectDirectory, { sourceFiles, serverFunctions }) {
|
|
99
|
+
async function assertTypeScriptProgram(projectDirectory, { sourceFiles, serverFunctions, agents, actions }) {
|
|
94
100
|
const paths = {
|
|
95
101
|
"@77-zhike/app-sdk": [resolve(SDK_SOURCE_ROOT, "index.d.ts")],
|
|
96
102
|
"@77-zhike/app-sdk/client": [resolve(SDK_SOURCE_ROOT, "client", "index.d.ts")],
|
|
97
103
|
"@77-zhike/app-sdk/server": [resolve(SDK_SOURCE_ROOT, "server", "index.d.ts")],
|
|
98
104
|
"@77-zhike/app-sdk/ui": [resolve(SDK_SOURCE_ROOT, "ui", "index.d.ts")],
|
|
99
105
|
"@77-zhike/app-sdk/forms": [resolve(SDK_SOURCE_ROOT, "forms", "index.d.ts")],
|
|
106
|
+
"@77-zhike/app-sdk/jsx-runtime": [resolve(SDK_SOURCE_ROOT, "jsx-runtime.d.ts")],
|
|
107
|
+
"@77-zhike/app-sdk/jsx-dev-runtime": [resolve(SDK_SOURCE_ROOT, "jsx-dev-runtime.d.ts")],
|
|
100
108
|
"react": [resolve(dirname(createRequire(import.meta.url).resolve("@types/react/package.json")), "index.d.ts")],
|
|
101
109
|
"react/jsx-runtime": [resolve(dirname(createRequire(import.meta.url).resolve("@types/react/package.json")), "jsx-runtime.d.ts")],
|
|
102
110
|
"react/jsx-dev-runtime": [resolve(dirname(createRequire(import.meta.url).resolve("@types/react/package.json")), "jsx-dev-runtime.d.ts")],
|
|
@@ -104,6 +112,7 @@ async function assertTypeScriptProgram(projectDirectory, { sourceFiles, serverFu
|
|
|
104
112
|
const options = {
|
|
105
113
|
baseUrl: projectDirectory,
|
|
106
114
|
jsx: ts.JsxEmit.ReactJSX,
|
|
115
|
+
jsxImportSource: "@77-zhike/app-sdk",
|
|
107
116
|
lib: ["lib.es2022.d.ts", "lib.dom.d.ts"],
|
|
108
117
|
module: ts.ModuleKind.ESNext,
|
|
109
118
|
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
@@ -117,11 +126,16 @@ async function assertTypeScriptProgram(projectDirectory, { sourceFiles, serverFu
|
|
|
117
126
|
const rootNames = sourceFiles.map((path) => resolve(projectDirectory, "src", path));
|
|
118
127
|
// 仅供 TypeScript 检查,不落盘、不进 Artifact;复用原包装的参数/结果合同。
|
|
119
128
|
const contractPath = resolve(projectDirectory, ".zhike/server-function-contracts.ts");
|
|
129
|
+
const handlers = [
|
|
130
|
+
...serverFunctions.map(item => ({ ...item, member: '' })),
|
|
131
|
+
...agents.flatMap(agent => agent.tools.map(item => ({ ...item, member: '.execute' }))),
|
|
132
|
+
...actions.map(item => ({...item, member: '.execute'})),
|
|
133
|
+
];
|
|
120
134
|
const contractSource = [
|
|
121
135
|
'import type { ServerFunction } from "@77-zhike/app-sdk/server";',
|
|
122
|
-
...
|
|
136
|
+
...handlers.flatMap(({ relativePath, member }, index) => [
|
|
123
137
|
`import handler${index} from ${JSON.stringify(`../src/${relativePath.slice(0, -3)}`)};`,
|
|
124
|
-
`type Contract${index} = ServerFunction<Parameters<typeof handler${index}>, Awaited<ReturnType<typeof handler${index}>>>;`,
|
|
138
|
+
`type Contract${index} = ServerFunction<Parameters<typeof handler${index}${member}>, Awaited<ReturnType<typeof handler${index}${member}>>>;`,
|
|
125
139
|
]),
|
|
126
140
|
].join("\n");
|
|
127
141
|
const host = ts.createCompilerHost(options);
|
|
@@ -130,14 +144,14 @@ async function assertTypeScriptProgram(projectDirectory, { sourceFiles, serverFu
|
|
|
130
144
|
resolve(fileName) === contractPath
|
|
131
145
|
? ts.createSourceFile(fileName, contractSource, languageVersion, true)
|
|
132
146
|
: getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
133
|
-
if (
|
|
147
|
+
if (handlers.length) rootNames.push(contractPath);
|
|
134
148
|
const program = ts.createProgram({ rootNames, options, host });
|
|
135
149
|
const diagnostics = ts.getPreEmitDiagnostics(program);
|
|
136
150
|
if (diagnostics.length === 0) return;
|
|
137
151
|
const diagnostic = diagnostics[0];
|
|
138
|
-
const contractLine = diagnostic.file
|
|
152
|
+
const contractLine = diagnostic.file && resolve(diagnostic.file.fileName) === contractPath
|
|
139
153
|
? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start || 0).line : -1;
|
|
140
|
-
const contractOwner = contractLine > 0 ?
|
|
154
|
+
const contractOwner = contractLine > 0 ? handlers[Math.floor((contractLine - 1) / 2)] : null;
|
|
141
155
|
const location = contractOwner ? `src/${contractOwner.relativePath}(参数/返回类型)` : diagnostic.file
|
|
142
156
|
? `${relative(projectDirectory, diagnostic.file.fileName).split(sep).join("/")}:${
|
|
143
157
|
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start || 0).line + 1
|
|
@@ -156,13 +170,16 @@ async function buildRemoteReactClient(projectDirectory, sources, development) {
|
|
|
156
170
|
`${JSON.stringify(item.key)}: extension${i}`).join(",");
|
|
157
171
|
const result = await build({
|
|
158
172
|
absWorkingDir: projectDirectory, bundle: true, charset: "utf8", format: "cjs",
|
|
159
|
-
legalComments: "none", logLevel: "silent", minify:
|
|
173
|
+
legalComments: "none", logLevel: "silent", minify: true, platform: "browser",
|
|
160
174
|
external: ["@77-zhike/app-sdk/runtime", "react", "react/jsx-runtime", "react/jsx-dev-runtime", "@77-zhike/app-sdk/client", "@77-zhike/app-sdk/ui", "@77-zhike/app-sdk/forms"],
|
|
161
|
-
plugins: [createSdkBuildPlugin(projectDirectory, sources, "remote-client")
|
|
175
|
+
plugins: [createSdkBuildPlugin(projectDirectory, sources, "remote-client"),
|
|
176
|
+
await createDependencyPolicyPlugin(projectDirectory, "client", validateImports)],
|
|
162
177
|
sourcemap: development ? "inline" : false,
|
|
163
178
|
banner: { js: 'export function createClientApp(platformModules) {\nconst module = { exports: {} };\nconst exports = module.exports;\nconst require = name => { if (!Object.hasOwn(platformModules, name)) throw new Error("runtime_module_unavailable"); return platformModules[name]; };\nconst Promise = require("@77-zhike/app-sdk/runtime").Promise;' },
|
|
164
179
|
footer: { js: 'return module.exports;\n}' },
|
|
165
|
-
|
|
180
|
+
// dev 只增加源码映射;编译语义与正式发布一致,不能依赖宿主的 React 开发构建。
|
|
181
|
+
jsx: "automatic", jsxDev: false, jsxImportSource: "@77-zhike/app-sdk",
|
|
182
|
+
define: { "process.env.NODE_ENV": '"production"' },
|
|
166
183
|
stdin: { contents: `${imports}\nexport const extensions = Object.freeze({${entries}});`, loader: "tsx", resolveDir: projectDirectory, sourcefile: "zhike-client-entry.tsx" },
|
|
167
184
|
// 原生 await 不经过 Promise.then;降级后的 helper 必须使用工厂内受管 Promise。
|
|
168
185
|
target: "es2022", supported: { "async-await": false, "async-generator": false }, treeShaking: true, write: false,
|
|
@@ -178,7 +195,12 @@ async function buildServerArtifact(projectDirectory, sources) {
|
|
|
178
195
|
const hasConnectionLifecycle = sources.lifecycleEvents.some(
|
|
179
196
|
({ event }) => event === "connection-added" || event === "connection-removed",
|
|
180
197
|
);
|
|
198
|
+
const tools = [...sources.agents.flatMap(agent => agent.tools), ...sources.actions];
|
|
199
|
+
const toolImports = tools.map((tool, index) => `import agentTool${index} from "./src/${tool.relativePath}";`);
|
|
200
|
+
const agentToolDeclarations = `const agentTools = new Map([${tools.map((tool, index) => `[${JSON.stringify(tool.entry)}, agentTool${index}]`).join(",")}]);`;
|
|
201
|
+
const agentToolDispatch = ` if (request.kind === "agent_tool" || request.kind === "app_action") { const prefix = request.kind === "app_action" ? "action/" : "agent-tool/"; const tool = typeof request.entryKey === "string" && request.entryKey.startsWith(prefix) ? agentTools.get(request.entryKey) : null; if (!tool) throw new Error("runtime_agent_tool_not_found"); return tool.execute(Object.freeze({ ...request.input })); }\n`;
|
|
181
202
|
const imports = [
|
|
203
|
+
...toolImports,
|
|
182
204
|
...(hasConnectionLifecycle
|
|
183
205
|
? ['import { getWorkspaceConnection as getLifecycleConnection } from "@77-zhike/app-sdk/server";']
|
|
184
206
|
: []),
|
|
@@ -194,6 +216,14 @@ async function buildServerArtifact(projectDirectory, sources) {
|
|
|
194
216
|
(definition, index) =>
|
|
195
217
|
`import webhookHandler${index} from "./src/${definition.relativePath}";`,
|
|
196
218
|
),
|
|
219
|
+
...sources.workflowSteps.map(
|
|
220
|
+
(definition, index) =>
|
|
221
|
+
`import workflowStep${index} from "./src/${definition.handlerPaths.execute}";`,
|
|
222
|
+
),
|
|
223
|
+
...sources.workflowTriggers.map(
|
|
224
|
+
(definition, index) => Object.entries(definition.handlerPaths).map(([name, path]) =>
|
|
225
|
+
`import workflowTrigger${index}_${name} from "./src/${path}";`).join("\n"),
|
|
226
|
+
),
|
|
197
227
|
].join("\n");
|
|
198
228
|
const lifecycleEntries = sources.lifecycleEvents
|
|
199
229
|
.map(
|
|
@@ -213,7 +243,19 @@ async function buildServerArtifact(projectDirectory, sources) {
|
|
|
213
243
|
`[${JSON.stringify(definition.key)}, webhookHandler${index}]`,
|
|
214
244
|
)
|
|
215
245
|
.join(",\n");
|
|
216
|
-
const
|
|
246
|
+
const workflowEntries = sources.workflowSteps
|
|
247
|
+
.map((definition, index) => `[${JSON.stringify(definition.entry)}, workflowStep${index}]`)
|
|
248
|
+
.join(",\n");
|
|
249
|
+
const triggerEntries = sources.workflowTriggers.flatMap((definition, index) =>
|
|
250
|
+
Object.entries(definition.entries).map(([name, entry]) =>
|
|
251
|
+
`[${JSON.stringify(entry)}, workflowTrigger${index}_${name}]`)).join(",\n");
|
|
252
|
+
const triggerDeclarations = sources.workflowTriggers.length > 0
|
|
253
|
+
? `const workflowTriggers = new Map([${triggerEntries}]);\n`
|
|
254
|
+
: "";
|
|
255
|
+
const triggerDispatch = sources.workflowTriggers.length > 0
|
|
256
|
+
? ` if (request.kind === "workflow_trigger") {\n const handler = workflowTriggers.get(request.entryKey);\n if (!handler) throw new Error("runtime_workflow_trigger_not_found");\n const result = await handler(Object.freeze({ ...request.params }));\n return request.entryKey.endsWith("/deactivate") ? null : result;\n }\n`
|
|
257
|
+
: "";
|
|
258
|
+
const stdin = `${imports}\n${serializeWebhookResponse.toString()}\nconst lifecycleEvents = new Map([${lifecycleEntries}]);\nconst serverFunctions = new Map([${serverEntries}]);\nconst webhookHandlers = new Map([${webhookEntries}]);\nconst workflowSteps = new Map([${workflowEntries}]);\n${triggerDeclarations}${agentToolDeclarations}\nexport async function dispatchServerInvocation(request) {\n if (!request || typeof request !== "object") throw new Error("runtime_invocation_invalid");\n if (request.kind === "lifecycle_event") {\n const definition = lifecycleEvents.get(request.entryKey);\n if (!definition) throw new Error("runtime_lifecycle_event_not_found");\n const params = definition.event === "app-installed" || definition.event === "app-uninstalled" ? request.context : Object.freeze({ connection: getLifecycleConnection() });\n await definition.handler(params);\n return null;\n }\n if (request.kind === "server_function") {\n const handler = serverFunctions.get(request.entryKey);\n if (!handler) throw new Error("runtime_server_function_not_found");\n return handler(...request.args);\n }\n if (request.kind === "workflow_step") {\n const handler = workflowSteps.get(request.entryKey);\n if (!handler) throw new Error("runtime_workflow_step_not_found");\n return handler(Object.freeze({ config: request.config }));\n }\n${triggerDispatch}${agentToolDispatch} if (request.kind === "webhook_handler") {\n const handler = webhookHandlers.get(request.entryKey);\n if (!handler) throw new Error("runtime_webhook_handler_not_found");\n const input = request.webRequest;\n const webRequest = new Request(input.url, { method: input.method, headers: input.headers, body: ["GET", "HEAD"].includes(input.method) ? undefined : input.body });\n const response = await handler(webRequest, Object.freeze({ ...request.context }));\n if (!(response instanceof Response)) throw new Error("runtime_webhook_response_invalid");\n return serializeWebhookResponse(response);\n }\n throw new Error("runtime_invocation_kind_invalid");\n}\n`;
|
|
217
259
|
const result = await build({
|
|
218
260
|
absWorkingDir: projectDirectory,
|
|
219
261
|
bundle: true,
|
|
@@ -223,7 +265,8 @@ async function buildServerArtifact(projectDirectory, sources) {
|
|
|
223
265
|
logLevel: "silent",
|
|
224
266
|
minify: true,
|
|
225
267
|
platform: "browser",
|
|
226
|
-
plugins: [createSdkBuildPlugin(projectDirectory, sources, "server")
|
|
268
|
+
plugins: [createSdkBuildPlugin(projectDirectory, sources, "server"),
|
|
269
|
+
await createDependencyPolicyPlugin(projectDirectory, "server", validateImports)],
|
|
227
270
|
sourcemap: false,
|
|
228
271
|
stdin: { contents: stdin, loader: "ts", resolveDir: projectDirectory, sourcefile: "zhike-server-entry.ts" },
|
|
229
272
|
target: "es2022",
|
|
@@ -243,6 +286,38 @@ function createSdkBuildPlugin(projectDirectory, sources, target) {
|
|
|
243
286
|
return {
|
|
244
287
|
name: "zhike-app-sdk-runtime",
|
|
245
288
|
setup(buildApi) {
|
|
289
|
+
buildApi.onResolve({ filter: /^@77-zhike\/app-sdk\/jsx(?:-dev)?-runtime$/ }, args => ({ path: args.path, namespace: "zhike-jsx" }));
|
|
290
|
+
buildApi.onLoad({ filter: /.*/, namespace: "zhike-jsx" }, args => ({
|
|
291
|
+
contents: args.path.endsWith("jsx-dev-runtime")
|
|
292
|
+
? 'export { jsxDEV, Fragment } from "react/jsx-dev-runtime";'
|
|
293
|
+
: 'export { jsx, jsxs, Fragment } from "react/jsx-runtime";', loader: "js",
|
|
294
|
+
}));
|
|
295
|
+
if (target === 'remote-client') {
|
|
296
|
+
buildApi.onResolve({ filter: /\.css\?inline$/ }, args => args.path.startsWith('.')
|
|
297
|
+
? { path: resolve(args.resolveDir, args.path.slice(0, -7)), namespace: 'zhike-native-css' }
|
|
298
|
+
: { errors: [{ text: 'NativeDOM 样式必须使用本地相对路径' }] });
|
|
299
|
+
buildApi.onLoad({ filter: /.*/, namespace: 'zhike-native-css' }, async args => ({
|
|
300
|
+
contents: await readFile(args.path, 'utf8'), loader: 'text', watchFiles: [args.path],
|
|
301
|
+
}));
|
|
302
|
+
}
|
|
303
|
+
if (target === "remote-client") {
|
|
304
|
+
// 新构建固化 authoring 默认值;Guest 仍为不可变旧 Bundle 提供兼容模块。
|
|
305
|
+
buildApi.onResolve({ filter: /^@77-zhike\/app-sdk\/ui$/ }, args => args.namespace === "zhike-ui-authoring"
|
|
306
|
+
? { path: args.path, external: true }
|
|
307
|
+
: { path: args.path, namespace: "zhike-ui-authoring" });
|
|
308
|
+
buildApi.onLoad({ filter: /.*/, namespace: "zhike-ui-authoring" }, () => ({ loader: "js", contents: `
|
|
309
|
+
import * as ui from "@77-zhike/app-sdk/ui";
|
|
310
|
+
import { createElement } from "react";
|
|
311
|
+
export const TextBlock = props => createElement(ui.TextBlock, { ...props, align: props.align ?? "left" });
|
|
312
|
+
export const Badge = props => {
|
|
313
|
+
if (props.tone !== undefined) throw new Error("Badge.tone 已移除,请使用 StatusBadge");
|
|
314
|
+
return createElement(ui.Badge, props);
|
|
315
|
+
};
|
|
316
|
+
export const TableCell = Object.defineProperties(props => createElement(ui.TableCell, props), { Avatar: { get: () => ui.Avatar }, Badge: { value: Badge } });
|
|
317
|
+
export const Table = Object.defineProperties(props => createElement(ui.Table, props), { Header: { get: () => ui.Table.Header }, HeaderCell: { get: () => ui.Table.HeaderCell }, Body: { get: () => ui.Table.Body }, Row: { get: () => ui.Table.Row }, Cell: { value: TableCell } });
|
|
318
|
+
export const { ${[...publicComponentNames.filter(name => !["TextBlock", "Badge", "Table", "TableCell"].includes(name)), "Typography", "Widget", "useConversation"].join(", ")} } = ui;
|
|
319
|
+
` }));
|
|
320
|
+
}
|
|
246
321
|
if (target !== "remote-client") buildApi.onResolve({ filter: /^@77-zhike\/app-sdk\/(client|server)$/ }, (args) => ({
|
|
247
322
|
external: target === "server" && args.path.endsWith("/server"),
|
|
248
323
|
path: args.path,
|
|
@@ -252,7 +327,10 @@ function createSdkBuildPlugin(projectDirectory, sources, target) {
|
|
|
252
327
|
}));
|
|
253
328
|
buildApi.onLoad({ filter: /.*/, namespace: "zhike-sdk-runtime" }, (args) => {
|
|
254
329
|
if (args.path.endsWith("/client")) {
|
|
255
|
-
return {
|
|
330
|
+
return {
|
|
331
|
+
contents: "export const defineFrontendExtension = (definition) => definition; export const definePage = (definition) => ({ ...definition, type: 'page' }); export const defineToolRenderer = (definition) => ({ ...definition, type: 'tool-renderer' });",
|
|
332
|
+
loader: "js",
|
|
333
|
+
};
|
|
256
334
|
}
|
|
257
335
|
return { contents: "export const defineLifecycleEvent = (definition) => definition; export const defineServerFunction = (handler) => handler; export const defineWebhookHandler = (definition) => definition; export const createWebhookHandler = async () => { throw new Error('webhook_handler_runtime_unavailable'); }; export const listWebhookHandlers = async () => { throw new Error('webhook_handler_runtime_unavailable'); }; export const deleteWebhookHandler = async () => { throw new Error('webhook_handler_runtime_unavailable'); };", loader: "js" };
|
|
258
336
|
});
|
|
@@ -291,7 +369,7 @@ function createManifest({ clientBytes, serverBytes, sources }) {
|
|
|
291
369
|
sdkAbiVersion: "2",
|
|
292
370
|
toolchainVersion: TOOLING_VERSION,
|
|
293
371
|
...(sources.frontendExtensions.length > 0
|
|
294
|
-
? { clientRuntime: { runtimeVersion: "remote-react.
|
|
372
|
+
? { clientRuntime: { runtimeVersion: "remote-react.v3" } } : {}),
|
|
295
373
|
artifacts: {
|
|
296
374
|
...(clientBytes
|
|
297
375
|
? {
|
|
@@ -314,7 +392,7 @@ function createManifest({ clientBytes, serverBytes, sources }) {
|
|
|
314
392
|
}
|
|
315
393
|
: {}),
|
|
316
394
|
},
|
|
317
|
-
frontendExtensions: sources.frontendExtensions.map(({ key, type, entry, label, icon, objects }) => ({
|
|
395
|
+
frontendExtensions: sources.frontendExtensions.map(({ key, type, entry, label, icon, objects, name, order, variant, showInNavigation, showHeader, fillHeight }) => ({
|
|
318
396
|
artifact: "client",
|
|
319
397
|
entry,
|
|
320
398
|
key,
|
|
@@ -322,12 +400,22 @@ function createManifest({ clientBytes, serverBytes, sources }) {
|
|
|
322
400
|
...(label === undefined ? {} : { label }),
|
|
323
401
|
...(icon === undefined ? {} : { icon }),
|
|
324
402
|
...(objects === undefined ? {} : { objects }),
|
|
403
|
+
...(name === undefined ? {} : { name }),
|
|
404
|
+
...(order === undefined ? {} : { order }),
|
|
405
|
+
...(variant === undefined ? {} : { variant }),
|
|
406
|
+
...(showInNavigation === undefined ? {} : { showInNavigation }),
|
|
407
|
+
...(showHeader === undefined ? {} : { showHeader }),
|
|
408
|
+
...(fillHeight === undefined ? {} : { fillHeight }),
|
|
325
409
|
})),
|
|
326
410
|
lifecycleEvents: sources.lifecycleEvents.map(({ event, key }) => ({
|
|
327
411
|
artifact: "server",
|
|
328
412
|
event,
|
|
329
413
|
key,
|
|
330
414
|
})),
|
|
415
|
+
...(sources.agents.length ? { agents: sources.agents.map(agentManifest) } : {}),
|
|
416
|
+
...((sources.actions.length || sources.dataCapabilities.length || sources.agents.some(agent => agent.aiExposure || agent.actionRefs || agent.tools.some(tool => tool.aiExposure))) ? {aiCapabilitiesVersion:'1'} : {}),
|
|
417
|
+
...(sources.actions.length ? {actions:sources.actions.map(stripPath)} : {}),
|
|
418
|
+
...(sources.dataCapabilities.length ? {dataCapabilities:sources.dataCapabilities.map(stripPath)} : {}),
|
|
331
419
|
serverFunctions: sources.serverFunctions.map(({ key }) => ({
|
|
332
420
|
artifact: "server",
|
|
333
421
|
key,
|
|
@@ -337,6 +425,20 @@ function createManifest({ clientBytes, serverBytes, sources }) {
|
|
|
337
425
|
key,
|
|
338
426
|
methods,
|
|
339
427
|
})),
|
|
428
|
+
...(sources.workflowSteps.length > 0 ? { workflowSteps: sources.workflowSteps.map(
|
|
429
|
+
({ key, title, description, connection, configSchema, outcomes, entry }) => ({
|
|
430
|
+
artifact: "server", key, entry, title,
|
|
431
|
+
...(description === undefined ? {} : { description }),
|
|
432
|
+
connection, configSchema, outcomes,
|
|
433
|
+
}),
|
|
434
|
+
) } : {}),
|
|
435
|
+
...(sources.workflowTriggers.length > 0 ? { workflowTriggers: sources.workflowTriggers.map(
|
|
436
|
+
({ key, title, description, connection, requestHeaders, configSchema, outcomes, entries }) => ({
|
|
437
|
+
artifact: "server", key, entries, title,
|
|
438
|
+
...(description === undefined ? {} : { description }),
|
|
439
|
+
connection, requestHeaders, configSchema, outcomes,
|
|
440
|
+
}),
|
|
441
|
+
) } : {}),
|
|
340
442
|
};
|
|
341
443
|
}
|
|
342
444
|
|
|
@@ -344,8 +446,14 @@ function createServerDefinitionsDigest(sources) {
|
|
|
344
446
|
return sha256(
|
|
345
447
|
canonicalJsonBytes({
|
|
346
448
|
lifecycleEvents: sources.lifecycleEvents.map(({ event, key }) => ({ event, key })),
|
|
449
|
+
...(sources.agents.length ? { agents: sources.agents.map(({ key, tools }) => ({
|
|
450
|
+
key, tools: tools.map(({ key: toolKey, entry }) => ({ key: toolKey, entry })),
|
|
451
|
+
})) } : {}),
|
|
452
|
+
...(sources.actions.length ? {actions:sources.actions.map(({key,entry})=>({key,entry}))} : {}),
|
|
347
453
|
serverFunctions: sources.serverFunctions.map(({ key }) => ({ key })),
|
|
348
454
|
webhookHandlers: sources.webhookHandlers.map(({ key, methods }) => ({ key, methods })),
|
|
455
|
+
...(sources.workflowSteps.length > 0 ? { workflowSteps: sources.workflowSteps.map(({ key, entry }) => ({ key, entry })) } : {}),
|
|
456
|
+
...(sources.workflowTriggers.length > 0 ? { workflowTriggers: sources.workflowTriggers.map(({ key, entries }) => ({ key, entries })) } : {}),
|
|
349
457
|
}),
|
|
350
458
|
);
|
|
351
459
|
}
|