@nextclaw/app-runtime 0.4.0 → 0.5.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/README.md +12 -4
- package/dist/cli/app-runtime-cli.service.d.ts +2 -0
- package/dist/cli/app-runtime-cli.service.js +55 -2
- package/dist/cli/app-runtime-options.service.d.ts +10 -1
- package/dist/cli/app-runtime-options.service.js +39 -2
- package/dist/commands/create.controller.d.ts +2 -1
- package/dist/commands/create.controller.js +3 -2
- package/dist/commands/inspect.controller.js +2 -1
- package/dist/commands/run.controller.js +25 -7
- package/dist/host/app-host.service.d.ts +3 -1
- package/dist/host/app-host.service.js +5 -1
- package/dist/host/app-instance.service.js +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +7 -1
- package/dist/install/app-installation.service.js +1 -0
- package/dist/install/app-installation.types.d.ts +1 -0
- package/dist/manifest/app-manifest.service.js +9 -3
- package/dist/manifest/app-manifest.types.d.ts +9 -3
- package/dist/package.js +1 -1
- package/dist/publish/app-marketplace-client.service.js +2 -2
- package/dist/publish/app-publish.service.d.ts +8 -1
- package/dist/publish/app-publish.service.js +87 -7
- package/dist/publish/platform-auth-state.service.d.ts +11 -0
- package/dist/publish/platform-auth-state.service.js +26 -0
- package/dist/runtime/app-build.service.d.ts +24 -0
- package/dist/runtime/app-build.service.js +55 -0
- package/dist/runtime/app-runtime-toolchain.service.d.ts +30 -0
- package/dist/runtime/app-runtime-toolchain.service.js +96 -0
- package/dist/runtime/wasm-main-runner.service.js +1 -0
- package/dist/runtime/wasmtime-wasi-http-component.service.d.ts +24 -0
- package/dist/runtime/wasmtime-wasi-http-component.service.js +129 -0
- package/dist/scaffold/app-scaffold.service.d.ts +11 -2
- package/dist/scaffold/app-scaffold.service.js +27 -8
- package/dist/scaffold/app-ts-http-scaffold-template.service.d.ts +25 -0
- package/dist/scaffold/app-ts-http-scaffold-template.service.js +496 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
- `napp create <app-dir>`:生成一个最小可跑的微应用骨架
|
|
8
8
|
- `napp inspect <app-dir>`:校验应用目录与 manifest
|
|
9
|
+
- `napp doctor`:检查本机 NApp/WASI HTTP 开发运行环境
|
|
10
|
+
- `napp build <app-dir> --install`:安装模板依赖并构建 TS/WASI HTTP 后端
|
|
9
11
|
- `napp run <app-dir|app-id>`:启动本地宿主,支持目录运行和已安装应用运行
|
|
10
12
|
- `napp dev <app-dir>`:当前等价于 `run`
|
|
11
13
|
- `napp pack <app-dir>`:把应用目录打成 `.napp` bundle
|
|
@@ -33,7 +35,7 @@ napp --help
|
|
|
33
35
|
napp --version
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
当前版本先聚焦“独立可运行的微应用宿主 + 可分发、可安装、可更新、可授权的 CLI/runtime 闭环”。普通用户入口推荐通过 NextClaw 的 `nextclaw-app-runtime` skill 编排这些命令。
|
|
37
39
|
|
|
38
40
|
## 应用目录
|
|
39
41
|
|
|
@@ -41,6 +43,8 @@ napp --version
|
|
|
41
43
|
manifest.json
|
|
42
44
|
main/
|
|
43
45
|
app.wasm
|
|
46
|
+
package.json # ts-http 模板存在
|
|
47
|
+
src/ # ts-http 模板存在
|
|
44
48
|
ui/
|
|
45
49
|
index.html
|
|
46
50
|
assets/
|
|
@@ -48,11 +52,12 @@ assets/
|
|
|
48
52
|
|
|
49
53
|
## 当前 MVP 范围
|
|
50
54
|
|
|
51
|
-
- `main` 执行形态:`wasm`
|
|
55
|
+
- `main` 执行形态:`wasm` 或 `wasi-http-component`
|
|
52
56
|
- UI 装载:本地静态服务
|
|
53
57
|
- 宿主桥接:`/__napp/*`
|
|
58
|
+
- WASI HTTP 业务 API:`/api/*`
|
|
54
59
|
- 权限词汇:`documentAccess`、`allowedDomains`、`storage`、`capabilities`
|
|
55
|
-
- 当前 Wasm 执行底座:Node 原生 `WebAssembly`
|
|
60
|
+
- 当前 Wasm 执行底座:Node 原生 `WebAssembly` 与 Wasmtime `serve`
|
|
56
61
|
- 分发包形态:`.napp`(底层为 zip)
|
|
57
62
|
- 安装目录:`~/.nextclaw/apps/packages/<app-id>/<version>/`
|
|
58
63
|
- 用户数据目录:`~/.nextclaw/apps/data/<app-id>/`
|
|
@@ -65,8 +70,11 @@ assets/
|
|
|
65
70
|
开发者工作流:
|
|
66
71
|
|
|
67
72
|
```bash
|
|
68
|
-
napp
|
|
73
|
+
napp doctor
|
|
74
|
+
napp create ./my-first-napp --template ts-http
|
|
75
|
+
napp build ./my-first-napp --install
|
|
69
76
|
napp inspect ./my-first-napp
|
|
77
|
+
napp run ./my-first-napp --data ./my-first-napp/.napp/data
|
|
70
78
|
napp pack ./my-first-napp
|
|
71
79
|
napp publish ./my-first-napp
|
|
72
80
|
```
|
|
@@ -14,6 +14,8 @@ import { RegistryCommand } from "../commands/registry.controller.js";
|
|
|
14
14
|
import { RevokeCommand } from "../commands/revoke.controller.js";
|
|
15
15
|
import { UninstallCommand } from "../commands/uninstall.controller.js";
|
|
16
16
|
import { UpdateCommand } from "../commands/update.controller.js";
|
|
17
|
+
import { AppRuntimeToolchainService } from "../runtime/app-runtime-toolchain.service.js";
|
|
18
|
+
import { AppBuildService } from "../runtime/app-build.service.js";
|
|
17
19
|
import { AppRuntimeOptionsService } from "./app-runtime-options.service.js";
|
|
18
20
|
//#region src/cli/app-runtime-cli.service.ts
|
|
19
21
|
var AppRuntimeCliService = class {
|
|
@@ -44,6 +46,12 @@ var AppRuntimeCliService = class {
|
|
|
44
46
|
case "inspect":
|
|
45
47
|
await this.handleInspect(restArgs);
|
|
46
48
|
return;
|
|
49
|
+
case "build":
|
|
50
|
+
await this.handleBuild(restArgs);
|
|
51
|
+
return;
|
|
52
|
+
case "doctor":
|
|
53
|
+
await this.handleDoctor(restArgs);
|
|
54
|
+
return;
|
|
47
55
|
case "run":
|
|
48
56
|
await this.handleRun(restArgs);
|
|
49
57
|
return;
|
|
@@ -93,6 +101,7 @@ var AppRuntimeCliService = class {
|
|
|
93
101
|
const options = this.optionsService.readCreateOptions(optionArgs);
|
|
94
102
|
await new CreateCommand().run({
|
|
95
103
|
appDirectory: target,
|
|
104
|
+
template: options.template,
|
|
96
105
|
json: options.json,
|
|
97
106
|
write: this.write
|
|
98
107
|
});
|
|
@@ -106,6 +115,46 @@ var AppRuntimeCliService = class {
|
|
|
106
115
|
write: this.write
|
|
107
116
|
});
|
|
108
117
|
};
|
|
118
|
+
handleBuild = async (restArgs) => {
|
|
119
|
+
const { target, optionArgs } = this.optionsService.readTarget("build", restArgs);
|
|
120
|
+
const options = this.optionsService.readBuildOptions(optionArgs);
|
|
121
|
+
const result = await new AppBuildService().build({
|
|
122
|
+
appDirectory: target,
|
|
123
|
+
install: options.install
|
|
124
|
+
});
|
|
125
|
+
if (options.json) {
|
|
126
|
+
this.write(`${JSON.stringify({
|
|
127
|
+
ok: true,
|
|
128
|
+
build: result
|
|
129
|
+
}, null, 2)}\n`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!result.built) {
|
|
133
|
+
this.write(`Build skipped: ${result.skippedReason ?? result.mainKind}\n`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
this.write(`Built ${result.mainKind} app\n`);
|
|
137
|
+
this.write(`Main: ${result.mainEntryPath}\n`);
|
|
138
|
+
if (result.installedDependencies) this.write("Dependencies: installed\n");
|
|
139
|
+
};
|
|
140
|
+
handleDoctor = async (restArgs) => {
|
|
141
|
+
const options = this.optionsService.readJsonOnlyOptions(restArgs);
|
|
142
|
+
const result = await new AppRuntimeToolchainService().doctor();
|
|
143
|
+
if (options.json) {
|
|
144
|
+
this.write(`${JSON.stringify({
|
|
145
|
+
ok: result.ok,
|
|
146
|
+
doctor: result
|
|
147
|
+
}, null, 2)}\n`);
|
|
148
|
+
if (!result.ok) process.exitCode = 1;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.write(`NApp runtime doctor: ${result.ok ? "ok" : "not ready"}\n`);
|
|
152
|
+
for (const tool of result.tools) {
|
|
153
|
+
this.write(`${tool.ok ? "ok" : "missing"} ${tool.name}${tool.version ? ` ${tool.version}` : ""}\n`);
|
|
154
|
+
if (!tool.ok) this.write(` ${tool.installHint}\n`);
|
|
155
|
+
}
|
|
156
|
+
if (!result.ok) process.exitCode = 1;
|
|
157
|
+
};
|
|
109
158
|
handleRun = async (restArgs) => {
|
|
110
159
|
const { target, optionArgs } = this.optionsService.readTarget("run", restArgs);
|
|
111
160
|
const options = this.optionsService.readRuntimeOptions(optionArgs);
|
|
@@ -113,6 +162,7 @@ var AppRuntimeCliService = class {
|
|
|
113
162
|
appReference: target,
|
|
114
163
|
host: options.host,
|
|
115
164
|
port: options.port,
|
|
165
|
+
dataDirectory: options.dataDirectory,
|
|
116
166
|
json: options.json,
|
|
117
167
|
documentGrantMap: options.documentGrantMap,
|
|
118
168
|
write: this.write
|
|
@@ -125,6 +175,7 @@ var AppRuntimeCliService = class {
|
|
|
125
175
|
appReference: target,
|
|
126
176
|
host: options.host,
|
|
127
177
|
port: options.port,
|
|
178
|
+
dataDirectory: options.dataDirectory,
|
|
128
179
|
json: options.json,
|
|
129
180
|
documentGrantMap: options.documentGrantMap,
|
|
130
181
|
write: this.write
|
|
@@ -271,9 +322,11 @@ var AppRuntimeCliService = class {
|
|
|
271
322
|
});
|
|
272
323
|
};
|
|
273
324
|
writeUsage = () => {
|
|
274
|
-
this.write("Usage: napp create <app-dir> [--json]\n");
|
|
325
|
+
this.write("Usage: napp create <app-dir> [--template starter|ts-http] [--json]\n");
|
|
275
326
|
this.write(" napp inspect <app-dir> [--json]\n");
|
|
276
|
-
this.write(" napp
|
|
327
|
+
this.write(" napp build <app-dir> [--install] [--json]\n");
|
|
328
|
+
this.write(" napp doctor [--json]\n");
|
|
329
|
+
this.write(" napp <run|dev> <app-dir|app-id> [--host 127.0.0.1] [--port 3100] [--data /path] [--json] [--document scope=/path]\n");
|
|
277
330
|
this.write(" napp pack <app-dir> [--out bundle.napp] [--json]\n");
|
|
278
331
|
this.write(" napp publish <app-dir> [--meta marketplace.json] [--api-base <url>] [--token <token>] [--json]\n");
|
|
279
332
|
this.write(" napp install <app-dir|bundle.napp|app-id[@version]> [--registry <url>] [--json]\n");
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
|
|
2
|
+
import { AppScaffoldTemplate } from "../scaffold/app-scaffold.service.js";
|
|
2
3
|
|
|
3
4
|
//#region src/cli/app-runtime-options.service.d.ts
|
|
4
5
|
type RuntimeCliOptions = {
|
|
5
6
|
host: string;
|
|
6
7
|
port: number;
|
|
8
|
+
dataDirectory?: string;
|
|
7
9
|
json: boolean;
|
|
8
10
|
documentGrantMap: AppDocumentGrantMap;
|
|
9
11
|
};
|
|
10
12
|
type CreateCliOptions = {
|
|
11
13
|
json: boolean;
|
|
14
|
+
template: AppScaffoldTemplate;
|
|
12
15
|
};
|
|
13
16
|
type PackCliOptions = {
|
|
14
17
|
json: boolean;
|
|
15
18
|
outputPath?: string;
|
|
16
19
|
};
|
|
20
|
+
type BuildCliOptions = {
|
|
21
|
+
json: boolean;
|
|
22
|
+
install: boolean;
|
|
23
|
+
};
|
|
17
24
|
type JsonOnlyCliOptions = {
|
|
18
25
|
json: boolean;
|
|
19
26
|
};
|
|
@@ -50,7 +57,9 @@ declare class AppRuntimeOptionsService {
|
|
|
50
57
|
optionArgs: string[];
|
|
51
58
|
};
|
|
52
59
|
readCreateOptions: (rawArgs: string[]) => CreateCliOptions;
|
|
60
|
+
private readCreateTemplate;
|
|
53
61
|
readPackOptions: (rawArgs: string[]) => PackCliOptions;
|
|
62
|
+
readBuildOptions: (rawArgs: string[]) => BuildCliOptions;
|
|
54
63
|
readJsonOnlyOptions: (rawArgs: string[]) => JsonOnlyCliOptions;
|
|
55
64
|
readInstallOptions: (rawArgs: string[]) => InstallCliOptions;
|
|
56
65
|
readUpdateOptions: (rawArgs: string[]) => UpdateCliOptions;
|
|
@@ -64,4 +73,4 @@ declare class AppRuntimeOptionsService {
|
|
|
64
73
|
private requireOptionValue;
|
|
65
74
|
}
|
|
66
75
|
//#endregion
|
|
67
|
-
export { AppRuntimeOptionsService, CreateCliOptions, GrantCliOptions, InstallCliOptions, JsonOnlyCliOptions, PackCliOptions, PublishCliOptions, RevokeCliOptions, RuntimeCliOptions, UninstallCliOptions, UpdateCliOptions };
|
|
76
|
+
export { AppRuntimeOptionsService, BuildCliOptions, CreateCliOptions, GrantCliOptions, InstallCliOptions, JsonOnlyCliOptions, PackCliOptions, PublishCliOptions, RevokeCliOptions, RuntimeCliOptions, UninstallCliOptions, UpdateCliOptions };
|
|
@@ -9,18 +9,31 @@ var AppRuntimeOptionsService = class {
|
|
|
9
9
|
};
|
|
10
10
|
};
|
|
11
11
|
readCreateOptions = (rawArgs) => {
|
|
12
|
-
const options = {
|
|
13
|
-
|
|
12
|
+
const options = {
|
|
13
|
+
json: false,
|
|
14
|
+
template: "starter"
|
|
15
|
+
};
|
|
16
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
17
|
+
const current = rawArgs[index];
|
|
14
18
|
if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
|
|
19
|
+
const nextValue = rawArgs[index + 1];
|
|
15
20
|
switch (current) {
|
|
16
21
|
case "--json":
|
|
17
22
|
options.json = true;
|
|
18
23
|
break;
|
|
24
|
+
case "--template":
|
|
25
|
+
options.template = this.readCreateTemplate(this.requireOptionValue(current, nextValue));
|
|
26
|
+
index += 1;
|
|
27
|
+
break;
|
|
19
28
|
default: throw new Error(`未知参数:${current}`);
|
|
20
29
|
}
|
|
21
30
|
}
|
|
22
31
|
return options;
|
|
23
32
|
};
|
|
33
|
+
readCreateTemplate = (rawTemplate) => {
|
|
34
|
+
if (rawTemplate === "starter" || rawTemplate === "ts-http") return rawTemplate;
|
|
35
|
+
throw new Error("--template 只支持 starter 或 ts-http。");
|
|
36
|
+
};
|
|
24
37
|
readPackOptions = (rawArgs) => {
|
|
25
38
|
const options = { json: false };
|
|
26
39
|
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
@@ -40,6 +53,25 @@ var AppRuntimeOptionsService = class {
|
|
|
40
53
|
}
|
|
41
54
|
return options;
|
|
42
55
|
};
|
|
56
|
+
readBuildOptions = (rawArgs) => {
|
|
57
|
+
const options = {
|
|
58
|
+
json: false,
|
|
59
|
+
install: false
|
|
60
|
+
};
|
|
61
|
+
for (const current of rawArgs) {
|
|
62
|
+
if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
|
|
63
|
+
switch (current) {
|
|
64
|
+
case "--json":
|
|
65
|
+
options.json = true;
|
|
66
|
+
break;
|
|
67
|
+
case "--install":
|
|
68
|
+
options.install = true;
|
|
69
|
+
break;
|
|
70
|
+
default: throw new Error(`未知参数:${current}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return options;
|
|
74
|
+
};
|
|
43
75
|
readJsonOnlyOptions = (rawArgs) => {
|
|
44
76
|
const options = { json: false };
|
|
45
77
|
for (const current of rawArgs) {
|
|
@@ -118,6 +150,7 @@ var AppRuntimeOptionsService = class {
|
|
|
118
150
|
const options = {
|
|
119
151
|
host: "127.0.0.1",
|
|
120
152
|
port: 3100,
|
|
153
|
+
dataDirectory: void 0,
|
|
121
154
|
json: false,
|
|
122
155
|
documentGrantMap: {}
|
|
123
156
|
};
|
|
@@ -138,6 +171,10 @@ var AppRuntimeOptionsService = class {
|
|
|
138
171
|
case "--json":
|
|
139
172
|
options.json = true;
|
|
140
173
|
break;
|
|
174
|
+
case "--data":
|
|
175
|
+
options.dataDirectory = this.requireOptionValue(current, nextValue);
|
|
176
|
+
index += 1;
|
|
177
|
+
break;
|
|
141
178
|
case "--document":
|
|
142
179
|
this.assignDocumentGrant(options.documentGrantMap, this.requireOptionValue(current, nextValue));
|
|
143
180
|
index += 1;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppScaffoldService } from "../scaffold/app-scaffold.service.js";
|
|
1
|
+
import { AppScaffoldService, AppScaffoldTemplate } from "../scaffold/app-scaffold.service.js";
|
|
2
2
|
|
|
3
3
|
//#region src/commands/create.controller.d.ts
|
|
4
4
|
declare class CreateCommand {
|
|
@@ -6,6 +6,7 @@ declare class CreateCommand {
|
|
|
6
6
|
constructor(scaffoldService?: AppScaffoldService);
|
|
7
7
|
run: (params: {
|
|
8
8
|
appDirectory: string;
|
|
9
|
+
template: AppScaffoldTemplate;
|
|
9
10
|
json: boolean;
|
|
10
11
|
write: (text: string) => void;
|
|
11
12
|
}) => Promise<void>;
|
|
@@ -5,8 +5,8 @@ var CreateCommand = class {
|
|
|
5
5
|
this.scaffoldService = scaffoldService;
|
|
6
6
|
}
|
|
7
7
|
run = async (params) => {
|
|
8
|
-
const { appDirectory, json, write } = params;
|
|
9
|
-
const result = await this.scaffoldService.scaffold(appDirectory);
|
|
8
|
+
const { appDirectory, template, json, write } = params;
|
|
9
|
+
const result = await this.scaffoldService.scaffold(appDirectory, { template });
|
|
10
10
|
if (json) {
|
|
11
11
|
write(`${JSON.stringify({
|
|
12
12
|
ok: true,
|
|
@@ -15,6 +15,7 @@ var CreateCommand = class {
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
write(`Created app scaffold at ${result.appDirectory}\n`);
|
|
18
|
+
write(`Template: ${result.template}\n`);
|
|
18
19
|
write(`Manifest: ${result.manifestPath}\n`);
|
|
19
20
|
write("Next: napp inspect <app-dir> && napp run <app-dir>\n");
|
|
20
21
|
};
|
|
@@ -17,7 +17,8 @@ var InspectCommand = class {
|
|
|
17
17
|
}
|
|
18
18
|
write(`App: ${summary.name} (${summary.id})\n`);
|
|
19
19
|
write(`Version: ${summary.version}\n`);
|
|
20
|
-
write(`
|
|
20
|
+
write(`Main Kind: ${summary.mainKind}\n`);
|
|
21
|
+
if (summary.action) write(`Action: ${summary.action}\n`);
|
|
21
22
|
write(`Main: ${summary.mainEntryPath}\n`);
|
|
22
23
|
write(`UI: ${summary.uiEntryPath}\n`);
|
|
23
24
|
};
|
|
@@ -2,6 +2,7 @@ import { AppManifestService } from "../manifest/app-manifest.service.js";
|
|
|
2
2
|
import { AppHostService } from "../host/app-host.service.js";
|
|
3
3
|
import { AppInstanceService } from "../host/app-instance.service.js";
|
|
4
4
|
import { AppInstallationService } from "../install/app-installation.service.js";
|
|
5
|
+
import { WasmtimeWasiHttpComponentService } from "../runtime/wasmtime-wasi-http-component.service.js";
|
|
5
6
|
//#region src/commands/run.controller.ts
|
|
6
7
|
var RunCommand = class {
|
|
7
8
|
constructor(manifestService = new AppManifestService(), installationService = new AppInstallationService()) {
|
|
@@ -9,19 +10,35 @@ var RunCommand = class {
|
|
|
9
10
|
this.installationService = installationService;
|
|
10
11
|
}
|
|
11
12
|
run = async (params) => {
|
|
12
|
-
const { appReference, host, port, json, documentGrantMap, write } = params;
|
|
13
|
+
const { appReference, host, port, dataDirectory, json, documentGrantMap, write } = params;
|
|
13
14
|
const launch = await this.installationService.resolveLaunch(appReference, documentGrantMap);
|
|
14
15
|
const bundle = await this.manifestService.load(launch.appDirectory);
|
|
15
16
|
const appInstance = new AppInstanceService(bundle);
|
|
16
17
|
await appInstance.initialize(launch.documentGrantMap, { appId: launch.appId });
|
|
17
18
|
await this.installationService.persistGrants(launch.appId, launch.documentGrantMap);
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const wasiHttpComponentService = bundle.manifest.main.kind === "wasi-http-component" ? new WasmtimeWasiHttpComponentService() : void 0;
|
|
20
|
+
const effectiveDataDirectory = dataDirectory ?? launch.dataDirectory;
|
|
21
|
+
if (wasiHttpComponentService) {
|
|
22
|
+
if (!effectiveDataDirectory) throw new Error("wasi-http-component 应用需要通过 --data /path 指定后端数据目录。");
|
|
23
|
+
await wasiHttpComponentService.start({
|
|
24
|
+
wasmPath: bundle.mainEntryPath,
|
|
25
|
+
dataDirectory: effectiveDataDirectory
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const appHost = new AppHostService(appInstance, wasiHttpComponentService);
|
|
29
|
+
let hostHandle;
|
|
30
|
+
try {
|
|
31
|
+
hostHandle = await appHost.start({
|
|
32
|
+
host,
|
|
33
|
+
port
|
|
34
|
+
});
|
|
35
|
+
} catch (error) {
|
|
36
|
+
await wasiHttpComponentService?.stop();
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
23
39
|
const shutdown = async () => {
|
|
24
40
|
await appHost.stop();
|
|
41
|
+
await wasiHttpComponentService?.stop();
|
|
25
42
|
process.exit(0);
|
|
26
43
|
};
|
|
27
44
|
process.once("SIGINT", () => {
|
|
@@ -36,7 +53,8 @@ var RunCommand = class {
|
|
|
36
53
|
host: hostHandle,
|
|
37
54
|
app: {
|
|
38
55
|
appId: launch.appId ?? bundle.manifest.id,
|
|
39
|
-
appDirectory: launch.appDirectory
|
|
56
|
+
appDirectory: launch.appDirectory,
|
|
57
|
+
dataDirectory: effectiveDataDirectory
|
|
40
58
|
}
|
|
41
59
|
}, null, 2)}\n`);
|
|
42
60
|
return;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppInstanceService } from "./app-instance.service.js";
|
|
2
|
+
import { WasmtimeWasiHttpComponentService } from "../runtime/wasmtime-wasi-http-component.service.js";
|
|
2
3
|
|
|
3
4
|
//#region src/host/app-host.service.d.ts
|
|
4
5
|
type AppHostStartOptions = {
|
|
@@ -13,10 +14,11 @@ type AppHostHandle = {
|
|
|
13
14
|
};
|
|
14
15
|
declare class AppHostService {
|
|
15
16
|
private readonly appInstance;
|
|
17
|
+
private readonly wasiHttpComponentService?;
|
|
16
18
|
private server?;
|
|
17
19
|
private readonly bridgeServer;
|
|
18
20
|
private readonly uiServer;
|
|
19
|
-
constructor(appInstance: AppInstanceService);
|
|
21
|
+
constructor(appInstance: AppInstanceService, wasiHttpComponentService?: WasmtimeWasiHttpComponentService | undefined);
|
|
20
22
|
start: (options: AppHostStartOptions) => Promise<AppHostHandle>;
|
|
21
23
|
stop: () => Promise<void>;
|
|
22
24
|
private handleRequest;
|
|
@@ -6,8 +6,9 @@ var AppHostService = class {
|
|
|
6
6
|
server;
|
|
7
7
|
bridgeServer;
|
|
8
8
|
uiServer;
|
|
9
|
-
constructor(appInstance) {
|
|
9
|
+
constructor(appInstance, wasiHttpComponentService) {
|
|
10
10
|
this.appInstance = appInstance;
|
|
11
|
+
this.wasiHttpComponentService = wasiHttpComponentService;
|
|
11
12
|
this.bridgeServer = new HostBridgeServer(appInstance);
|
|
12
13
|
this.uiServer = new UiServerService(appInstance.bundle);
|
|
13
14
|
}
|
|
@@ -48,6 +49,9 @@ var AppHostService = class {
|
|
|
48
49
|
};
|
|
49
50
|
handleRequest = async (request, response) => {
|
|
50
51
|
try {
|
|
52
|
+
if (this.wasiHttpComponentService) {
|
|
53
|
+
if (await this.wasiHttpComponentService.handleRequest(request, response)) return;
|
|
54
|
+
}
|
|
51
55
|
if (await this.bridgeServer.handle(request, response)) return;
|
|
52
56
|
await this.uiServer.handle(request, response);
|
|
53
57
|
} catch (error) {
|
|
@@ -22,6 +22,7 @@ var AppInstanceService = class {
|
|
|
22
22
|
return this.permissionsService.summarize(this.bundle, this.getPermissions());
|
|
23
23
|
};
|
|
24
24
|
runAction = async (action) => {
|
|
25
|
+
if (this.bundle.manifest.main.kind !== "wasm") throw new Error("当前应用不支持 __napp/run action,请通过 /api/* 调用 WASI HTTP 后端。");
|
|
25
26
|
const expectedAction = this.bundle.manifest.main.action;
|
|
26
27
|
if (action && action !== expectedAction) throw new Error(`当前应用只支持动作 ${expectedAction}。`);
|
|
27
28
|
const input = await this.collectDocumentSummaryInput();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest } from "./manifest/app-manifest.types.js";
|
|
1
|
+
import { AppCoreWasmMainManifest, AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest, AppWasiHttpComponentMainManifest } from "./manifest/app-manifest.types.js";
|
|
2
2
|
import { AppManifestService } from "./manifest/app-manifest.service.js";
|
|
3
3
|
import { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult } from "./bundle/app-bundle.types.js";
|
|
4
4
|
import { AppBundleService } from "./bundle/app-bundle.service.js";
|
|
@@ -10,7 +10,9 @@ import { WasmSidecarClientService } from "./sidecar/wasm-sidecar-client.service.
|
|
|
10
10
|
import { WasmMainRunnerService } from "./runtime/wasm-main-runner.service.js";
|
|
11
11
|
import { AppInstanceService, AppRunResult } from "./host/app-instance.service.js";
|
|
12
12
|
import { HostBridgeServer } from "./bridge/host-bridge.service.js";
|
|
13
|
-
import {
|
|
13
|
+
import { AppScaffoldFile, AppTsHttpScaffoldTemplateService } from "./scaffold/app-ts-http-scaffold-template.service.js";
|
|
14
|
+
import { AppScaffoldResult, AppScaffoldService, AppScaffoldTemplate } from "./scaffold/app-scaffold.service.js";
|
|
15
|
+
import { AppRuntimeOptionsService, BuildCliOptions, CreateCliOptions, GrantCliOptions, InstallCliOptions, JsonOnlyCliOptions, PackCliOptions, PublishCliOptions, RevokeCliOptions, RuntimeCliOptions, UninstallCliOptions, UpdateCliOptions } from "./cli/app-runtime-options.service.js";
|
|
14
16
|
import { AppRuntimeCliService } from "./cli/app-runtime-cli.service.js";
|
|
15
17
|
import { CreateCommand } from "./commands/create.controller.js";
|
|
16
18
|
import { AppHomeService } from "./paths/app-home.service.js";
|
|
@@ -31,12 +33,16 @@ import { PermissionsCommand } from "./commands/permissions.controller.js";
|
|
|
31
33
|
import { AppMarketplaceMetadata, AppPublishFile, AppPublishPayload, AppPublishResult, DEFAULT_APP_MARKETPLACE_API_BASE } from "./publish/app-publish.types.js";
|
|
32
34
|
import { AppMarketplaceClientService } from "./publish/app-marketplace-client.service.js";
|
|
33
35
|
import { AppMarketplaceMetadataService } from "./publish/app-marketplace-metadata.service.js";
|
|
36
|
+
import { PlatformAuthStateService, PlatformPublishAuthState } from "./publish/platform-auth-state.service.js";
|
|
34
37
|
import { AppPublishService } from "./publish/app-publish.service.js";
|
|
35
38
|
import { PublishCommand } from "./commands/publish.controller.js";
|
|
36
39
|
import { RegistryCommand } from "./commands/registry.controller.js";
|
|
37
40
|
import { RevokeCommand } from "./commands/revoke.controller.js";
|
|
38
41
|
import { UpdateCommand } from "./commands/update.controller.js";
|
|
39
42
|
import { UninstallCommand } from "./commands/uninstall.controller.js";
|
|
43
|
+
import { WasmtimeWasiHttpComponentHandle, WasmtimeWasiHttpComponentService, WasmtimeWasiHttpComponentStartOptions } from "./runtime/wasmtime-wasi-http-component.service.js";
|
|
40
44
|
import { AppHostHandle, AppHostService, AppHostStartOptions } from "./host/app-host.service.js";
|
|
45
|
+
import { AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeToolStatus, AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
46
|
+
import { AppBuildResult, AppBuildService } from "./runtime/app-build.service.js";
|
|
41
47
|
import { UiServerService } from "./ui/ui-server.service.js";
|
|
42
|
-
export { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult, AppBundleService, AppDocumentAccessMode, AppDocumentAccessScope, AppDocumentGrantMap, AppDocumentGrantMutationResult, AppDocumentGrantState, AppGrantService, AppHomeService, AppHostHandle, AppHostService, AppHostStartOptions, AppInfoResult, AppInstallResult, AppInstallSourceKind, AppInstallationService, AppInstalledPermissionState, AppInstanceService, AppLaunchResolution, AppMainManifest, AppManifest, AppManifestBundle, AppManifestService, AppManifestSummary, AppMarketplaceClientService, AppMarketplaceMetadata, AppMarketplaceMetadataService, AppPermissionSummary, AppPermissions, AppPermissionsService, AppPublishFile, AppPublishPayload, AppPublishResult, AppPublishService, AppPublisher, AppRegistry, AppRegistryAppRecord, AppRegistryConfig, AppRegistryConfigService, AppRegistryConfigSnapshot, AppRegistryInstalledVersion, AppRegistryService, AppRemoteRegistryClientService, AppRemoteRegistryDocument, AppRemoteRegistryResolution, AppRemoteRegistryVersion, AppRunResult, AppRuntimeCliService, AppRuntimeOptionsService, AppUiManifest, AppUninstallResult, AppUpdateResult, CreateCliOptions, CreateCommand, DEFAULT_APP_MARKETPLACE_API_BASE, DEFAULT_APP_REGISTRY_URL, GrantCliOptions, GrantCommand, HostBridgeServer, InfoCommand, InstallCliOptions, InstallCommand, InstalledAppListItem, JsonOnlyCliOptions, ListCommand, MainRunRequest, MainRunResult, MainRunnerService, PackCliOptions, PackCommand, PermissionsCommand, PublishCliOptions, PublishCommand, RegistryCommand, ResolvedDocumentGrant, ResolvedPermissions, RevokeCliOptions, RevokeCommand, RuntimeCliOptions, UiServerService, UninstallCliOptions, UninstallCommand, UpdateCliOptions, UpdateCommand, WasmDocumentSummaryInput, WasmMainRunnerService, WasmSidecarClientService };
|
|
48
|
+
export { AppBuildResult, AppBuildService, AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult, AppBundleService, AppCoreWasmMainManifest, AppDocumentAccessMode, AppDocumentAccessScope, AppDocumentGrantMap, AppDocumentGrantMutationResult, AppDocumentGrantState, AppGrantService, AppHomeService, AppHostHandle, AppHostService, AppHostStartOptions, AppInfoResult, AppInstallResult, AppInstallSourceKind, AppInstallationService, AppInstalledPermissionState, AppInstanceService, AppLaunchResolution, AppMainManifest, AppManifest, AppManifestBundle, AppManifestService, AppManifestSummary, AppMarketplaceClientService, AppMarketplaceMetadata, AppMarketplaceMetadataService, AppPermissionSummary, AppPermissions, AppPermissionsService, AppPublishFile, AppPublishPayload, AppPublishResult, AppPublishService, AppPublisher, AppRegistry, AppRegistryAppRecord, AppRegistryConfig, AppRegistryConfigService, AppRegistryConfigSnapshot, AppRegistryInstalledVersion, AppRegistryService, AppRemoteRegistryClientService, AppRemoteRegistryDocument, AppRemoteRegistryResolution, AppRemoteRegistryVersion, AppRunResult, AppRuntimeCliService, AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeOptionsService, AppRuntimeToolStatus, AppRuntimeToolchainService, AppScaffoldFile, AppScaffoldResult, AppScaffoldService, AppScaffoldTemplate, AppTsHttpScaffoldTemplateService, AppUiManifest, AppUninstallResult, AppUpdateResult, AppWasiHttpComponentMainManifest, BuildCliOptions, CreateCliOptions, CreateCommand, DEFAULT_APP_MARKETPLACE_API_BASE, DEFAULT_APP_REGISTRY_URL, GrantCliOptions, GrantCommand, HostBridgeServer, InfoCommand, InstallCliOptions, InstallCommand, InstalledAppListItem, JsonOnlyCliOptions, ListCommand, MainRunRequest, MainRunResult, MainRunnerService, PackCliOptions, PackCommand, PermissionsCommand, PlatformAuthStateService, PlatformPublishAuthState, PublishCliOptions, PublishCommand, RegistryCommand, ResolvedDocumentGrant, ResolvedPermissions, RevokeCliOptions, RevokeCommand, RuntimeCliOptions, UiServerService, UninstallCliOptions, UninstallCommand, UpdateCliOptions, UpdateCommand, WasmDocumentSummaryInput, WasmMainRunnerService, WasmSidecarClientService, WasmtimeWasiHttpComponentHandle, WasmtimeWasiHttpComponentService, WasmtimeWasiHttpComponentStartOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AppManifestService } from "./manifest/app-manifest.service.js";
|
|
2
2
|
import { AppBundleService } from "./bundle/app-bundle.service.js";
|
|
3
3
|
import { HostBridgeServer } from "./bridge/host-bridge.service.js";
|
|
4
|
+
import { AppTsHttpScaffoldTemplateService } from "./scaffold/app-ts-http-scaffold-template.service.js";
|
|
5
|
+
import { AppScaffoldService } from "./scaffold/app-scaffold.service.js";
|
|
4
6
|
import { CreateCommand } from "./commands/create.controller.js";
|
|
5
7
|
import { UiServerService } from "./ui/ui-server.service.js";
|
|
6
8
|
import { AppHostService } from "./host/app-host.service.js";
|
|
@@ -15,6 +17,7 @@ import { AppRegistryConfigService } from "./registry/app-registry-config.service
|
|
|
15
17
|
import { AppRemoteRegistryClientService } from "./registry/app-remote-registry-client.service.js";
|
|
16
18
|
import { AppRegistryService } from "./registry/app-registry.service.js";
|
|
17
19
|
import { AppInstallationService } from "./install/app-installation.service.js";
|
|
20
|
+
import { WasmtimeWasiHttpComponentService } from "./runtime/wasmtime-wasi-http-component.service.js";
|
|
18
21
|
import { AppGrantService } from "./permissions/app-grant.service.js";
|
|
19
22
|
import { GrantCommand } from "./commands/grant.controller.js";
|
|
20
23
|
import { InfoCommand } from "./commands/info.controller.js";
|
|
@@ -25,12 +28,15 @@ import { PermissionsCommand } from "./commands/permissions.controller.js";
|
|
|
25
28
|
import { DEFAULT_APP_MARKETPLACE_API_BASE } from "./publish/app-publish.types.js";
|
|
26
29
|
import { AppMarketplaceClientService } from "./publish/app-marketplace-client.service.js";
|
|
27
30
|
import { AppMarketplaceMetadataService } from "./publish/app-marketplace-metadata.service.js";
|
|
31
|
+
import { PlatformAuthStateService } from "./publish/platform-auth-state.service.js";
|
|
28
32
|
import { AppPublishService } from "./publish/app-publish.service.js";
|
|
29
33
|
import { PublishCommand } from "./commands/publish.controller.js";
|
|
30
34
|
import { RegistryCommand } from "./commands/registry.controller.js";
|
|
31
35
|
import { RevokeCommand } from "./commands/revoke.controller.js";
|
|
32
36
|
import { UninstallCommand } from "./commands/uninstall.controller.js";
|
|
33
37
|
import { UpdateCommand } from "./commands/update.controller.js";
|
|
38
|
+
import { AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
39
|
+
import { AppBuildService } from "./runtime/app-build.service.js";
|
|
34
40
|
import { AppRuntimeOptionsService } from "./cli/app-runtime-options.service.js";
|
|
35
41
|
import { AppRuntimeCliService } from "./cli/app-runtime-cli.service.js";
|
|
36
|
-
export { AppBundleService, AppGrantService, AppHomeService, AppHostService, AppInstallationService, AppInstanceService, AppManifestService, AppMarketplaceClientService, AppMarketplaceMetadataService, AppPermissionsService, AppPublishService, AppRegistryConfigService, AppRegistryService, AppRemoteRegistryClientService, AppRuntimeCliService, AppRuntimeOptionsService, CreateCommand, DEFAULT_APP_MARKETPLACE_API_BASE, DEFAULT_APP_REGISTRY_URL, GrantCommand, HostBridgeServer, InfoCommand, InstallCommand, ListCommand, MainRunnerService, PackCommand, PermissionsCommand, PublishCommand, RegistryCommand, RevokeCommand, UiServerService, UninstallCommand, UpdateCommand, WasmMainRunnerService, WasmSidecarClientService };
|
|
42
|
+
export { AppBuildService, AppBundleService, AppGrantService, AppHomeService, AppHostService, AppInstallationService, AppInstanceService, AppManifestService, AppMarketplaceClientService, AppMarketplaceMetadataService, AppPermissionsService, AppPublishService, AppRegistryConfigService, AppRegistryService, AppRemoteRegistryClientService, AppRuntimeCliService, AppRuntimeOptionsService, AppRuntimeToolchainService, AppScaffoldService, AppTsHttpScaffoldTemplateService, CreateCommand, DEFAULT_APP_MARKETPLACE_API_BASE, DEFAULT_APP_REGISTRY_URL, GrantCommand, HostBridgeServer, InfoCommand, InstallCommand, ListCommand, MainRunnerService, PackCommand, PermissionsCommand, PlatformAuthStateService, PublishCommand, RegistryCommand, RevokeCommand, UiServerService, UninstallCommand, UpdateCommand, WasmMainRunnerService, WasmSidecarClientService, WasmtimeWasiHttpComponentService };
|
|
@@ -27,7 +27,8 @@ var AppManifestService = class {
|
|
|
27
27
|
name: bundle.manifest.name,
|
|
28
28
|
version: bundle.manifest.version,
|
|
29
29
|
description: bundle.manifest.description,
|
|
30
|
-
|
|
30
|
+
mainKind: bundle.manifest.main.kind,
|
|
31
|
+
action: bundle.manifest.main.kind === "wasm" ? bundle.manifest.main.action : void 0,
|
|
31
32
|
manifestPath: bundle.manifestPath,
|
|
32
33
|
mainEntryPath: bundle.mainEntryPath,
|
|
33
34
|
uiEntryPath: bundle.uiEntryPath,
|
|
@@ -54,13 +55,18 @@ var AppManifestService = class {
|
|
|
54
55
|
};
|
|
55
56
|
parseMain = (rawMain) => {
|
|
56
57
|
const candidate = this.assertObject(rawMain, "main");
|
|
57
|
-
|
|
58
|
-
return {
|
|
58
|
+
const kind = this.readRequiredString(candidate.kind, "main.kind");
|
|
59
|
+
if (kind === "wasm") return {
|
|
59
60
|
kind: "wasm",
|
|
60
61
|
entry: this.readRequiredString(candidate.entry, "main.entry"),
|
|
61
62
|
export: this.readRequiredString(candidate.export, "main.export"),
|
|
62
63
|
action: this.readRequiredString(candidate.action, "main.action")
|
|
63
64
|
};
|
|
65
|
+
if (kind === "wasi-http-component") return {
|
|
66
|
+
kind: "wasi-http-component",
|
|
67
|
+
entry: this.readRequiredString(candidate.entry, "main.entry")
|
|
68
|
+
};
|
|
69
|
+
throw new Error("当前 main.kind 只支持 wasm 或 wasi-http-component。");
|
|
64
70
|
};
|
|
65
71
|
parseUi = (rawUi) => {
|
|
66
72
|
const candidate = this.assertObject(rawUi, "ui");
|
|
@@ -15,12 +15,17 @@ type AppPermissions = {
|
|
|
15
15
|
hostBridge?: boolean;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
type
|
|
18
|
+
type AppCoreWasmMainManifest = {
|
|
19
19
|
kind: "wasm";
|
|
20
20
|
entry: string;
|
|
21
21
|
export: string;
|
|
22
22
|
action: string;
|
|
23
23
|
};
|
|
24
|
+
type AppWasiHttpComponentMainManifest = {
|
|
25
|
+
kind: "wasi-http-component";
|
|
26
|
+
entry: string;
|
|
27
|
+
};
|
|
28
|
+
type AppMainManifest = AppCoreWasmMainManifest | AppWasiHttpComponentMainManifest;
|
|
24
29
|
type AppUiManifest = {
|
|
25
30
|
entry: string;
|
|
26
31
|
};
|
|
@@ -50,7 +55,8 @@ type AppManifestSummary = {
|
|
|
50
55
|
name: string;
|
|
51
56
|
version: string;
|
|
52
57
|
description?: string;
|
|
53
|
-
|
|
58
|
+
mainKind: AppMainManifest["kind"];
|
|
59
|
+
action?: string;
|
|
54
60
|
manifestPath: string;
|
|
55
61
|
mainEntryPath: string;
|
|
56
62
|
uiEntryPath: string;
|
|
@@ -58,4 +64,4 @@ type AppManifestSummary = {
|
|
|
58
64
|
permissions: AppPermissions;
|
|
59
65
|
};
|
|
60
66
|
//#endregion
|
|
61
|
-
export { AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest };
|
|
67
|
+
export { AppCoreWasmMainManifest, AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest, AppWasiHttpComponentMainManifest };
|
package/dist/package.js
CHANGED
|
@@ -3,8 +3,8 @@ import "./app-publish.types.js";
|
|
|
3
3
|
var AppMarketplaceClientService = class {
|
|
4
4
|
publish = async (params) => {
|
|
5
5
|
const apiBaseUrl = this.normalizeApiBase(params.apiBaseUrl ?? "https://apps-registry.nextclaw.io");
|
|
6
|
-
const token = params.token?.trim()
|
|
7
|
-
if (!token) throw new Error("缺少 marketplace
|
|
6
|
+
const token = params.token?.trim();
|
|
7
|
+
if (!token) throw new Error("缺少 marketplace publish token。请先登录 NextClaw,或传入 --token。");
|
|
8
8
|
const response = await fetch(`${apiBaseUrl}/api/v1/apps/publish`, {
|
|
9
9
|
method: "POST",
|
|
10
10
|
headers: {
|