@77-zhike/app-sdk 0.2.0-d7b1.3 → 0.2.0-d7b1.5
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 +27 -0
- package/package.json +1 -1
- package/src/cli/api-client.js +4 -0
- package/src/cli/index.js +11 -1
- package/src/cli/local-commands.js +2 -1
- package/src/cli/logs.js +56 -0
- package/src/cli/project-init.js +1 -170
- package/src/toolchain/real-build.js +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 智客 App SDK 与 CLI
|
|
2
|
+
|
|
3
|
+
## 统一构建
|
|
4
|
+
|
|
5
|
+
`zhike dev` 是监听、构建、上传和应用开发安装的快捷工作流,不是另一种运行时。
|
|
6
|
+
它与 `zhike build` 使用相同的 JSX 编译、压缩和 production 条件;仅额外携带源码映射。
|
|
7
|
+
修复前已上传的开发产物不会自动改变,升级 SDK 后须重新运行 dev 或重新构建上传。
|
|
8
|
+
|
|
9
|
+
## 查询历史日志
|
|
10
|
+
|
|
11
|
+
在包含 `.zhike/project.json` 的 App 项目目录中执行:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
zhike logs --workspace <workspace-id> --since 1h
|
|
15
|
+
zhike logs --workspace <workspace-id> --since 1d --level error --keyword timeout --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- 使用项目绑定的 App 和环境、现有 Developer CLI 登录身份;不会构建、上传或安装 App。
|
|
19
|
+
- 默认查询最近一小时,最多最近三天,与 Console 历史查询一致。
|
|
20
|
+
- `--since` 接受带时区的 ISO 时间或 `30m`、`1h`、`1d` 等相对时间;`--until` 接受带时区的 ISO 时间。
|
|
21
|
+
- `--level` 为 `log`、`warn` 或 `error`;`--version` 指定执行版本,`--keyword` 搜索日志正文。
|
|
22
|
+
- 每次读取一页,按从新到旧排列;`--limit` 为 1..100,默认 100。
|
|
23
|
+
- 下一页使用返回的 `next_cursor` 作为 `--cursor`,同时保持 Workspace、过滤条件及返回的 `from/to` 窗口不变。
|
|
24
|
+
- `--json` 输出单个 JSON 结果;失败进程返回非零状态。日志正文是不可信内容,不应当作命令执行。
|
|
25
|
+
- 服务端需要部署支持 `/api/developer/cli/apps/{app_id}/logs` 的 Developer Server;旧服务端不会自动回退到 Web 凭据或实时订阅。
|
|
26
|
+
|
|
27
|
+
`zhike dev` 的实时订阅仍是独立用途,七天断线补读窗口不代表历史查询可超过三天。
|
package/package.json
CHANGED
package/src/cli/api-client.js
CHANGED
|
@@ -46,6 +46,10 @@ export class DeveloperApiClient {
|
|
|
46
46
|
return this.request("/api/developer/organizations");
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
async queryAppLogs(appId, query) {
|
|
50
|
+
return this.request(`/api/developer/cli/apps/${encodeURIComponent(appId)}/logs?${new URLSearchParams(query)}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
async getAppBySlug(organizationId, slug) {
|
|
50
54
|
const path = `/api/developer/organizations/${encodeURIComponent(
|
|
51
55
|
organizationId,
|
package/src/cli/index.js
CHANGED
|
@@ -14,6 +14,8 @@ import { validateBundleUpload } from "./validate-bundle.js";
|
|
|
14
14
|
import { uploadAppBundle } from "./upload-bundle.js";
|
|
15
15
|
import { watchDevelopmentApp } from "./development-watch.js";
|
|
16
16
|
import { runLocalCommand } from "./local-commands.js";
|
|
17
|
+
import { readProjectBinding } from "../project-binding.js";
|
|
18
|
+
import { parseLogsArguments, queryAppLogs } from "./logs.js";
|
|
17
19
|
|
|
18
20
|
export async function runCli(
|
|
19
21
|
args,
|
|
@@ -43,7 +45,7 @@ export async function runCli(
|
|
|
43
45
|
: `${JSON.stringify(result.data, null, 2)}\n`);
|
|
44
46
|
return result;
|
|
45
47
|
}
|
|
46
|
-
if (rest.includes("--json")) {
|
|
48
|
+
if (command !== "logs" && rest.includes("--json")) {
|
|
47
49
|
throw new ZhikeCliError("zhike_json_not_supported", "此命令暂不支持 --json,请用 help --json 查询支持范围");
|
|
48
50
|
}
|
|
49
51
|
try {
|
|
@@ -68,6 +70,14 @@ export async function runCli(
|
|
|
68
70
|
};
|
|
69
71
|
return remoteContext;
|
|
70
72
|
};
|
|
73
|
+
if (command === "logs") {
|
|
74
|
+
const parsed = parseLogsArguments(rest);
|
|
75
|
+
const { config, store } = getRemoteContext();
|
|
76
|
+
const binding = await readProjectBinding(cwd, config.apiBaseUrl);
|
|
77
|
+
const api = await authenticate({ ...config, credentialStore: store, fetchImpl, openBrowser,
|
|
78
|
+
onProgress: parsed.json ? () => {} : onProgress });
|
|
79
|
+
return await queryAppLogs({ api, binding, ...parsed, output });
|
|
80
|
+
}
|
|
71
81
|
if (command === "login") {
|
|
72
82
|
_rejectArguments(rest);
|
|
73
83
|
const { config, store } = getRemoteContext();
|
|
@@ -16,6 +16,7 @@ export const commandHelp = {
|
|
|
16
16
|
build: "build",
|
|
17
17
|
upload: "upload",
|
|
18
18
|
dev: "dev [--workspace <workspace-id>]",
|
|
19
|
+
logs: "logs --workspace <id> [--since <time|1h|1d>] [--until <time>] [--level log|warn|error] [--keyword <text>] [--version <id>] [--limit 1..100] [--cursor <cursor>] [--json]",
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export function localEnvelope(data, status = "completed") {
|
|
@@ -30,7 +31,7 @@ export async function runLocalCommand(command, args, { cwd, environment }) {
|
|
|
30
31
|
throw new ZhikeCliError("zhike_help_usage_invalid", "用法:help [command] [--json]");
|
|
31
32
|
}
|
|
32
33
|
return localEnvelope({ commands: args.length ? { [args[0]]: commandHelp[args[0]] } : commandHelp,
|
|
33
|
-
jsonCommands: ["help", "version", "doctor"] });
|
|
34
|
+
jsonCommands: ["help", "version", "doctor", "logs"] });
|
|
34
35
|
}
|
|
35
36
|
if (args.length) throw new ZhikeCliError("zhike_arguments_invalid", "当前命令不接受额外参数");
|
|
36
37
|
if (command === "version") return localEnvelope({ package: metadata.name, version: metadata.version,
|
package/src/cli/logs.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ZhikeCliError } from "../errors.js";
|
|
2
|
+
import { formatAppLog } from "./development-logs.js";
|
|
3
|
+
|
|
4
|
+
const fields = { "--workspace": "workspace_id", "--since": "from", "--until": "to",
|
|
5
|
+
"--level": "level", "--keyword": "query", "--version": "app_version_id",
|
|
6
|
+
"--cursor": "cursor", "--limit": "limit" };
|
|
7
|
+
|
|
8
|
+
/** 查询一页历史日志;不订阅、不构建,也不改变安装状态。 */
|
|
9
|
+
export function parseLogsArguments(args, now = Date.now()) {
|
|
10
|
+
const query = {}, seen = new Set();
|
|
11
|
+
let json = false;
|
|
12
|
+
const invalid = () => { throw new ZhikeCliError("zhike_logs_usage_invalid", "用法:zhike logs --workspace <id> [--since <带时区时间或 1h/1d>] [--until <带时区时间>] [--level log|warn|error] [--keyword <关键词>] [--version <id>] [--limit 1..100] [--cursor <游标>] [--json];最多查询最近三天"); };
|
|
13
|
+
for (let i = 0; i < args.length; i++) {
|
|
14
|
+
const flag = args[i];
|
|
15
|
+
if (seen.has(flag)) invalid();
|
|
16
|
+
seen.add(flag);
|
|
17
|
+
if (flag === "--json") { json = true; continue; }
|
|
18
|
+
if (!Object.hasOwn(fields, flag) || !args[i + 1] || args[i + 1].startsWith("--")) invalid();
|
|
19
|
+
query[fields[flag]] = args[++i];
|
|
20
|
+
}
|
|
21
|
+
if (!query.workspace_id || query.workspace_id.length > 128) invalid();
|
|
22
|
+
if (query.level && !["log", "warn", "error"].includes(query.level)) invalid();
|
|
23
|
+
if (query.limit && (!/^\d+$/.test(query.limit) || +query.limit < 1 || +query.limit > 100)) invalid();
|
|
24
|
+
if ((query.query?.length ?? 0) > 200 || (query.cursor?.length ?? 0) > 180 || (query.app_version_id?.length ?? 0) > 128) invalid();
|
|
25
|
+
const timestamp = (value, relative) => {
|
|
26
|
+
const match = relative && /^(\d+)(m|h|d)$/.exec(value);
|
|
27
|
+
const time = match ? now - +match[1] * { m: 60_000, h: 3_600_000, d: 86_400_000 }[match[2]]
|
|
28
|
+
: /^\d{4}-\d{2}-\d{2}T.*(?:Z|[+-]\d{2}:\d{2})$/.test(value) ? Date.parse(value) : NaN;
|
|
29
|
+
if (!Number.isFinite(time)) invalid();
|
|
30
|
+
return time;
|
|
31
|
+
};
|
|
32
|
+
const end = query.to ? timestamp(query.to, false) : now;
|
|
33
|
+
const start = query.from ? timestamp(query.from, true) : end - 3_600_000;
|
|
34
|
+
if (start >= end || start < now - 3 * 86_400_000 || end > now) invalid();
|
|
35
|
+
query.from = new Date(start).toISOString();
|
|
36
|
+
query.to = new Date(end).toISOString();
|
|
37
|
+
return { query, json };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function queryAppLogs({ api, binding, query, json, output }) {
|
|
41
|
+
const page = await api.queryAppLogs(binding.appId, query);
|
|
42
|
+
if (!page || !Array.isArray(page.items) || !(page.next_cursor === null || typeof page.next_cursor === "string")) {
|
|
43
|
+
throw new ZhikeCliError("zhike_logs_response_invalid", "日志响应格式错误,请检查服务端版本");
|
|
44
|
+
}
|
|
45
|
+
const result = { schemaVersion: 1, status: "completed",
|
|
46
|
+
target: { environment: binding.platformEnvironment, appId: binding.appId, workspaceId: query.workspace_id },
|
|
47
|
+
data: { ...page, from: query.from, to: query.to },
|
|
48
|
+
effects: { business: "none", authentication: "session" }, error: null, nextAction: null };
|
|
49
|
+
if (json) output.write(`${JSON.stringify(result)}\n`);
|
|
50
|
+
else {
|
|
51
|
+
for (const entry of page.items) output.write(`${formatAppLog(binding.appSlug, entry)}\n`);
|
|
52
|
+
if (!page.items.length) output.write("当前条件下没有日志。\n");
|
|
53
|
+
if (page.next_cursor) output.write(`还有更早日志:保持筛选条件并使用 --since ${query.from} --until ${query.to} --cursor ${JSON.stringify(page.next_cursor)}\n`);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
package/src/cli/project-init.js
CHANGED
|
@@ -95,7 +95,7 @@ export async function scaffoldProject({ targetDirectory, binding }) {
|
|
|
95
95
|
try {
|
|
96
96
|
await mkdir(resolve(temporaryDirectory, ".zhike"), { recursive: true });
|
|
97
97
|
await mkdir(
|
|
98
|
-
resolve(temporaryDirectory, "src", "app", "extensions"
|
|
98
|
+
resolve(temporaryDirectory, "src", "app", "extensions"),
|
|
99
99
|
{ recursive: true },
|
|
100
100
|
);
|
|
101
101
|
await mkdir(resolve(temporaryDirectory, "src", "app", "webhooks"), {
|
|
@@ -136,175 +136,6 @@ export async function scaffoldProject({ targetDirectory, binding }) {
|
|
|
136
136
|
)}\n`,
|
|
137
137
|
{ flag: "wx" },
|
|
138
138
|
);
|
|
139
|
-
await writeFile(
|
|
140
|
-
resolve(
|
|
141
|
-
temporaryDirectory,
|
|
142
|
-
"src",
|
|
143
|
-
"app",
|
|
144
|
-
"events",
|
|
145
|
-
"app-installed.event.ts",
|
|
146
|
-
),
|
|
147
|
-
`import { createWebhookHandler, ZHIKE_API_TOKEN, kv } from "@77-zhike/app-sdk/server";
|
|
148
|
-
|
|
149
|
-
export default async function appInstalled() {
|
|
150
|
-
const handler = await createWebhookHandler({ fileName: "qiqi-customer" });
|
|
151
|
-
const existing = await fetch("https://api-clm.77hub.com/v1/webhooks", {
|
|
152
|
-
headers: { authorization: \`Bearer \${ZHIKE_API_TOKEN}\` },
|
|
153
|
-
});
|
|
154
|
-
if (!existing.ok) throw new Error("webhook_list_failed");
|
|
155
|
-
const { items } = await existing.json() as { items: Array<{ subscriptions: Array<{ eventType: string }> }> };
|
|
156
|
-
const requiredEventTypes = ["record.created", "activity.updated"];
|
|
157
|
-
if (items.some((item) => requiredEventTypes.every((eventType) =>
|
|
158
|
-
item.subscriptions.some((subscription) => subscription.eventType === eventType)
|
|
159
|
-
))) return;
|
|
160
|
-
|
|
161
|
-
const response = await fetch("https://api-clm.77hub.com/v1/webhooks", {
|
|
162
|
-
method: "POST",
|
|
163
|
-
headers: {
|
|
164
|
-
authorization: \`Bearer \${ZHIKE_API_TOKEN}\`,
|
|
165
|
-
"content-type": "application/json",
|
|
166
|
-
},
|
|
167
|
-
body: JSON.stringify({
|
|
168
|
-
targetUrl: handler.url,
|
|
169
|
-
subscriptions: [{
|
|
170
|
-
eventType: "record.created",
|
|
171
|
-
filter: { field: "id.objectSlug", operator: "equals", value: "accounts" },
|
|
172
|
-
}, {
|
|
173
|
-
eventType: "activity.updated",
|
|
174
|
-
filter: null,
|
|
175
|
-
}],
|
|
176
|
-
}),
|
|
177
|
-
});
|
|
178
|
-
if (!response.ok) throw new Error("webhook_create_failed");
|
|
179
|
-
const created = await response.json() as { webhook: { id: string }; secret: string };
|
|
180
|
-
await kv.set(
|
|
181
|
-
\`webhook:\${created.webhook.id}\`,
|
|
182
|
-
JSON.stringify({ webhookId: created.webhook.id, secret: created.secret }),
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
`,
|
|
186
|
-
{ flag: "wx" },
|
|
187
|
-
);
|
|
188
|
-
await writeFile(
|
|
189
|
-
resolve(
|
|
190
|
-
temporaryDirectory,
|
|
191
|
-
"src",
|
|
192
|
-
"app",
|
|
193
|
-
"events",
|
|
194
|
-
"app-uninstalled.event.ts",
|
|
195
|
-
),
|
|
196
|
-
`import { deleteWebhookHandler, listWebhookHandlers, ZHIKE_API_TOKEN, kv } from "@77-zhike/app-sdk/server";\n\nexport default async function appUninstalled() {\n const response = await fetch("https://api-clm.77hub.com/v1/webhooks", {\n headers: { authorization: \`Bearer \${ZHIKE_API_TOKEN}\` },\n });\n if (!response.ok) throw new Error("webhook_list_failed");\n const { items } = await response.json() as { items: Array<{ id: string }> };\n for (const webhook of items) {\n const deleted = await fetch(\`https://api-clm.77hub.com/v1/webhooks/\${webhook.id}\`, {\n method: "DELETE",\n headers: { authorization: \`Bearer \${ZHIKE_API_TOKEN}\` },\n });\n if (deleted.status !== 204 && deleted.status !== 404) throw new Error("webhook_delete_failed");\n await kv.delete(\`webhook:\${webhook.id}\`);\n }\n for (const handler of await listWebhookHandlers()) {\n await deleteWebhookHandler(handler.id);\n }\n}\n`,
|
|
197
|
-
{ flag: "wx" },
|
|
198
|
-
);
|
|
199
|
-
await writeFile(
|
|
200
|
-
resolve(
|
|
201
|
-
temporaryDirectory,
|
|
202
|
-
"src",
|
|
203
|
-
"app",
|
|
204
|
-
"events",
|
|
205
|
-
"connection-added.event.ts",
|
|
206
|
-
),
|
|
207
|
-
`import { kv } from "@77-zhike/app-sdk/server";\nimport type { ConnectionAddedParams } from "@77-zhike/app-sdk/server";\n\nexport default async function connectionAdded({ connection }: ConnectionAddedParams) {\n const stateKey = \`connection:\${connection.id}:\${connection.generation}:initialized\`;\n if (await kv.get(stateKey)) return;\n // 在这里调用外部 OpenAPI 创建订阅,再持久化供应商返回的引用。\n await kv.set(stateKey, "initialized");\n}\n`,
|
|
208
|
-
{ flag: "wx" },
|
|
209
|
-
);
|
|
210
|
-
await writeFile(
|
|
211
|
-
resolve(
|
|
212
|
-
temporaryDirectory,
|
|
213
|
-
"src",
|
|
214
|
-
"app",
|
|
215
|
-
"events",
|
|
216
|
-
"connection-removed.event.ts",
|
|
217
|
-
),
|
|
218
|
-
`import { kv } from "@77-zhike/app-sdk/server";\nimport type { ConnectionRemovedParams } from "@77-zhike/app-sdk/server";\n\nexport default async function connectionRemoved({ connection }: ConnectionRemovedParams) {\n const stateKey = \`connection:\${connection.id}:\${connection.generation}:initialized\`;\n // 在这里读取供应商引用并调用外部 OpenAPI 删除订阅。\n await kv.delete(stateKey);\n}\n`,
|
|
219
|
-
{ flag: "wx" },
|
|
220
|
-
);
|
|
221
|
-
await writeFile(
|
|
222
|
-
resolve(
|
|
223
|
-
temporaryDirectory,
|
|
224
|
-
"src",
|
|
225
|
-
"app",
|
|
226
|
-
"extensions",
|
|
227
|
-
"customer-action",
|
|
228
|
-
"extension.tsx",
|
|
229
|
-
),
|
|
230
|
-
`import { defineFrontendExtension } from "@77-zhike/app-sdk/client";\nimport createFollowUpTask from "../../../server/functions/create-follow-up-task.server";\n\nexport default defineFrontendExtension({\n key: "customer-action",\n type: "record-action",\n label: "创建跟进任务",\n icon: "refresh-cw",\n objects: "accounts",\n async onTrigger({ recordId }: { recordId: string }) {\n await createFollowUpTask({ customerId: recordId });\n },\n});\n`,
|
|
231
|
-
{ flag: "wx" },
|
|
232
|
-
);
|
|
233
|
-
await writeFile(
|
|
234
|
-
resolve(
|
|
235
|
-
temporaryDirectory,
|
|
236
|
-
"src",
|
|
237
|
-
"server",
|
|
238
|
-
"functions",
|
|
239
|
-
"create-follow-up-task.server.ts",
|
|
240
|
-
),
|
|
241
|
-
`import { ZHIKE_API_TOKEN } from "@77-zhike/app-sdk/server";
|
|
242
|
-
|
|
243
|
-
export default async function(input: { customerId: string }) {
|
|
244
|
-
const response = await fetch("https://api-clm.77hub.com/v1/tasks", {
|
|
245
|
-
method: "POST",
|
|
246
|
-
headers: {
|
|
247
|
-
authorization: \`Bearer \${ZHIKE_API_TOKEN}\`,
|
|
248
|
-
"content-type": "application/json",
|
|
249
|
-
},
|
|
250
|
-
body: JSON.stringify({
|
|
251
|
-
title: "跟进客户",
|
|
252
|
-
relatedRecords: [{ objectSlug: "accounts", recordId: input.customerId }],
|
|
253
|
-
}),
|
|
254
|
-
});
|
|
255
|
-
if (!response.ok) throw new Error("task_create_failed");
|
|
256
|
-
const task = await response.json() as { id: { taskId: string } };
|
|
257
|
-
return { taskId: task.id.taskId };
|
|
258
|
-
}
|
|
259
|
-
`,
|
|
260
|
-
{ flag: "wx" },
|
|
261
|
-
);
|
|
262
|
-
await writeFile(
|
|
263
|
-
resolve(
|
|
264
|
-
temporaryDirectory,
|
|
265
|
-
"src",
|
|
266
|
-
"app",
|
|
267
|
-
"webhooks",
|
|
268
|
-
"qiqi-customer.webhook.ts",
|
|
269
|
-
),
|
|
270
|
-
`import { ZHIKE_API_TOKEN, kv } from "@77-zhike/app-sdk/server";
|
|
271
|
-
import type { WorkspaceWebhookBody } from "@77-zhike/app-sdk/server";
|
|
272
|
-
|
|
273
|
-
export default async function qiqiCustomer(request: Request) {
|
|
274
|
-
const idempotencyKey = request.headers.get("idempotency-key");
|
|
275
|
-
if (!idempotencyKey) throw new Error("webhook_idempotency_key_missing");
|
|
276
|
-
if (await kv.get(\`delivery:\${idempotencyKey}\`)) {
|
|
277
|
-
return new Response(null, { status: 200 });
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const { events } = await request.json() as WorkspaceWebhookBody;
|
|
281
|
-
for (const event of events) {
|
|
282
|
-
if (event.eventType === "activity.updated") {
|
|
283
|
-
const response = await fetch(
|
|
284
|
-
\`https://api-clm.77hub.com/v1/activities/\${encodeURIComponent(event.id.activityId)}\`,
|
|
285
|
-
{ headers: { authorization: \`Bearer \${ZHIKE_API_TOKEN}\` } },
|
|
286
|
-
);
|
|
287
|
-
if (!response.ok) throw new Error("activity_read_failed");
|
|
288
|
-
const activity = await response.json();
|
|
289
|
-
console.log("[qiqi-customer] current activity", activity);
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
if (event.eventType !== "record.created" || event.id.objectSlug !== "accounts") continue;
|
|
293
|
-
const response = await fetch(
|
|
294
|
-
\`https://api-clm.77hub.com/v1/objects/\${event.id.objectSlug}/records/\${event.id.recordId}\`,
|
|
295
|
-
{ headers: { authorization: \`Bearer \${ZHIKE_API_TOKEN}\` } },
|
|
296
|
-
);
|
|
297
|
-
if (!response.ok) throw new Error("record_read_failed");
|
|
298
|
-
const record = await response.json();
|
|
299
|
-
console.log("[qiqi-customer] current record values", record.values);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
await kv.set(\`delivery:\${idempotencyKey}\`, "completed", { ttlInSeconds: 172800 });
|
|
303
|
-
return new Response(null, { status: 200 });
|
|
304
|
-
}
|
|
305
|
-
`,
|
|
306
|
-
{ flag: "wx" },
|
|
307
|
-
);
|
|
308
139
|
await writeFile(
|
|
309
140
|
resolve(temporaryDirectory, "tsconfig.json"),
|
|
310
141
|
`${JSON.stringify(
|
|
@@ -156,13 +156,15 @@ async function buildRemoteReactClient(projectDirectory, sources, development) {
|
|
|
156
156
|
`${JSON.stringify(item.key)}: extension${i}`).join(",");
|
|
157
157
|
const result = await build({
|
|
158
158
|
absWorkingDir: projectDirectory, bundle: true, charset: "utf8", format: "cjs",
|
|
159
|
-
legalComments: "none", logLevel: "silent", minify:
|
|
159
|
+
legalComments: "none", logLevel: "silent", minify: true, platform: "browser",
|
|
160
160
|
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
161
|
plugins: [createSdkBuildPlugin(projectDirectory, sources, "remote-client")],
|
|
162
162
|
sourcemap: development ? "inline" : false,
|
|
163
163
|
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
164
|
footer: { js: 'return module.exports;\n}' },
|
|
165
|
-
|
|
165
|
+
// dev 只增加源码映射;编译语义与正式发布一致,不能依赖宿主的 React 开发构建。
|
|
166
|
+
jsx: "automatic", jsxDev: false,
|
|
167
|
+
define: { "process.env.NODE_ENV": '"production"' },
|
|
166
168
|
stdin: { contents: `${imports}\nexport const extensions = Object.freeze({${entries}});`, loader: "tsx", resolveDir: projectDirectory, sourcefile: "zhike-client-entry.tsx" },
|
|
167
169
|
// 原生 await 不经过 Promise.then;降级后的 helper 必须使用工厂内受管 Promise。
|
|
168
170
|
target: "es2022", supported: { "async-await": false, "async-generator": false }, treeShaking: true, write: false,
|