@nextclaw/app-runtime 0.6.0 → 0.7.1-beta.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 +20 -3
- package/dist/bundle/app-bundle.service.d.ts +7 -2
- package/dist/bundle/app-bundle.service.js +65 -10
- package/dist/bundle/app-bundle.types.d.ts +3 -1
- package/dist/cli/app-runtime-cli.service.js +8 -5
- package/dist/cli/app-runtime-options.service.d.ts +4 -0
- package/dist/cli/app-runtime-options.service.js +20 -2
- package/dist/commands/pack.controller.d.ts +1 -0
- package/dist/commands/pack.controller.js +4 -3
- package/dist/commands/publish.controller.d.ts +1 -0
- package/dist/commands/publish.controller.js +4 -3
- package/dist/commands/validate-publish.controller.d.ts +1 -0
- package/dist/commands/validate-publish.controller.js +4 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/install/app-installation.service.d.ts +4 -1
- package/dist/install/app-installation.service.js +21 -3
- package/dist/install/app-installation.types.d.ts +4 -0
- package/dist/package.js +1 -1
- package/dist/publish/app-publish-validation.service.d.ts +3 -0
- package/dist/publish/app-publish-validation.service.js +7 -3
- package/dist/publish/app-publish.service.d.ts +2 -0
- package/dist/publish/app-publish.service.js +9 -3
- package/dist/publish/app-publish.types.d.ts +4 -1
- package/dist/registry/app-registry.service.d.ts +1 -0
- package/dist/registry/app-registry.service.js +2 -1
- package/dist/registry/app-registry.types.d.ts +2 -0
- package/dist/registry/app-remote-registry-client.service.js +5 -1
- package/dist/registry/app-remote-registry.types.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
- `napp build <app-dir> --install`:安装模板依赖并构建 TS/WASI HTTP 后端
|
|
11
11
|
- `napp run <app-dir|app-id>`:启动本地宿主,支持目录运行和已安装应用运行
|
|
12
12
|
- `napp dev <app-dir>`:当前等价于 `run`
|
|
13
|
-
- `napp pack <app-dir>`:把应用目录打成 `.napp`
|
|
13
|
+
- `napp pack <app-dir>`:把应用目录打成 `.napp` 分发包,默认使用轻量 `source` 模式
|
|
14
14
|
- `napp validate-publish <app-dir>`:本地做发布前校验并输出体积/包内容 warning
|
|
15
|
-
- `napp publish <app-dir>`:把应用目录发布到官方 apps registry
|
|
15
|
+
- `napp publish <app-dir>`:把应用目录发布到官方 apps registry,默认发布轻量 `source` 分发包
|
|
16
16
|
- `napp install <app-dir|bundle.napp|app-id[@version]>`:从本地或 registry 安装应用
|
|
17
17
|
- `napp update <app-id>`:更新已安装应用
|
|
18
18
|
- `napp uninstall <app-id>`:卸载已安装应用
|
|
@@ -59,7 +59,7 @@ assets/
|
|
|
59
59
|
- WASI HTTP 业务 API:`/api/*`
|
|
60
60
|
- 权限词汇:`documentAccess`、`allowedDomains`、`storage`、`capabilities`
|
|
61
61
|
- 当前 Wasm 执行底座:Node 原生 `WebAssembly` 与 Wasmtime `serve`
|
|
62
|
-
- 分发包形态:`.napp`(底层为 zip
|
|
62
|
+
- 分发包形态:`.napp`(底层为 zip,支持 `source` / `bundle` 双模式)
|
|
63
63
|
- 安装目录:`~/.nextclaw/apps/packages/<app-id>/<version>/`
|
|
64
64
|
- 用户数据目录:`~/.nextclaw/apps/data/<app-id>/`
|
|
65
65
|
- 本地 registry:`~/.nextclaw/apps/registry.json`
|
|
@@ -176,6 +176,22 @@ assets/
|
|
|
176
176
|
checksums.json
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
## 分发模式
|
|
180
|
+
|
|
181
|
+
`.napp` 仍然是统一容器,但现在支持两种分发模式:
|
|
182
|
+
|
|
183
|
+
- `source`:默认模式。包里主要是用户源码、UI、资源和 manifest;安装时本地物化成运行态,适合轻量分发。
|
|
184
|
+
- `bundle`:显式模式。包里直接带运行态 `main/app.wasm`,适合高级用户、确定性发布或离线场景。
|
|
185
|
+
|
|
186
|
+
命令示例:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
napp validate-publish ./my-first-napp --mode source
|
|
190
|
+
napp pack ./my-first-napp --mode source
|
|
191
|
+
napp publish ./my-first-napp --mode source
|
|
192
|
+
napp pack ./my-first-napp --mode bundle
|
|
193
|
+
```
|
|
194
|
+
|
|
179
195
|
## Registry Metadata 结构
|
|
180
196
|
|
|
181
197
|
registry 按 npm 风格使用一个 base URL,再按 app id 拉取 metadata 文档。metadata 的最小结构如下:
|
|
@@ -196,6 +212,7 @@ registry 按 npm 风格使用一个 base URL,再按 app id 拉取 metadata 文
|
|
|
196
212
|
"name": "NextClaw Official"
|
|
197
213
|
},
|
|
198
214
|
"dist": {
|
|
215
|
+
"kind": "source",
|
|
199
216
|
"bundle": "./-/hello-notes-0.2.0.napp",
|
|
200
217
|
"sha256": "<sha256>"
|
|
201
218
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppManifestService } from "../manifest/app-manifest.service.js";
|
|
2
|
-
import { AppBundleExtractResult, AppBundlePackResult } from "./app-bundle.types.js";
|
|
2
|
+
import { AppBundleExtractResult, AppBundlePackResult, AppDistributionMode } from "./app-bundle.types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/bundle/app-bundle.service.d.ts
|
|
5
5
|
declare class AppBundleService {
|
|
@@ -8,14 +8,19 @@ declare class AppBundleService {
|
|
|
8
8
|
packAppDirectory: (params: {
|
|
9
9
|
appDirectory: string;
|
|
10
10
|
outputPath?: string;
|
|
11
|
+
mode?: AppDistributionMode;
|
|
11
12
|
}) => Promise<AppBundlePackResult>;
|
|
12
13
|
extractBundle: (params: {
|
|
13
14
|
bundlePath: string;
|
|
14
15
|
targetDirectory: string;
|
|
15
16
|
}) => Promise<AppBundleExtractResult>;
|
|
16
|
-
private
|
|
17
|
+
private collectRuntimeFiles;
|
|
18
|
+
private collectSourceFiles;
|
|
17
19
|
private collectDirectoryPaths;
|
|
20
|
+
private collectSourceDirectoryPaths;
|
|
21
|
+
private shouldExcludeSourcePath;
|
|
18
22
|
private buildMetadata;
|
|
23
|
+
private normalizeMetadata;
|
|
19
24
|
private buildChecksums;
|
|
20
25
|
private computeSha256;
|
|
21
26
|
private normalizeBundleFileName;
|
|
@@ -9,9 +9,11 @@ var AppBundleService = class {
|
|
|
9
9
|
this.manifestService = manifestService;
|
|
10
10
|
}
|
|
11
11
|
packAppDirectory = async (params) => {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
12
|
+
const { appDirectory, outputPath, mode: requestedMode } = params;
|
|
13
|
+
const bundle = await this.manifestService.load(appDirectory);
|
|
14
|
+
const mode = requestedMode ?? "bundle";
|
|
15
|
+
const { appFiles, filePaths } = mode === "source" ? await this.collectSourceFiles(bundle) : await this.collectRuntimeFiles(bundle);
|
|
16
|
+
const metadata = this.buildMetadata(bundle.manifest.id, bundle.manifest.name, bundle.manifest.version, mode);
|
|
15
17
|
const bundleJsonPath = ".napp/bundle.json";
|
|
16
18
|
const checksumsJsonPath = ".napp/checksums.json";
|
|
17
19
|
const bundleJsonBytes = strToU8(`${JSON.stringify(metadata, null, 2)}\n`);
|
|
@@ -25,11 +27,11 @@ var AppBundleService = class {
|
|
|
25
27
|
[bundleJsonPath]: bundleJsonBytes,
|
|
26
28
|
[checksumsJsonPath]: checksumsJsonBytes
|
|
27
29
|
}, { level: 9 });
|
|
28
|
-
const
|
|
29
|
-
await mkdir(path.dirname(
|
|
30
|
-
await writeFile(
|
|
30
|
+
const resolvedOutputPath = outputPath ? path.resolve(outputPath) : path.join(path.dirname(bundle.appDirectory), `${this.normalizeBundleFileName(bundle.manifest.id)}-${bundle.manifest.version}.napp`);
|
|
31
|
+
await mkdir(path.dirname(resolvedOutputPath), { recursive: true });
|
|
32
|
+
await writeFile(resolvedOutputPath, Buffer.from(archiveBytes));
|
|
31
33
|
return {
|
|
32
|
-
bundlePath:
|
|
34
|
+
bundlePath: resolvedOutputPath,
|
|
33
35
|
metadata,
|
|
34
36
|
sizeBytes: archiveBytes.byteLength,
|
|
35
37
|
filePaths
|
|
@@ -51,7 +53,8 @@ var AppBundleService = class {
|
|
|
51
53
|
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
52
54
|
await writeFile(targetPath, Buffer.from(archive[entryName]));
|
|
53
55
|
}
|
|
54
|
-
const
|
|
56
|
+
const rawMetadata = await this.readJsonFile(path.join(targetDirectory, ".napp", "bundle.json"), "bundle metadata");
|
|
57
|
+
const metadata = this.normalizeMetadata(rawMetadata);
|
|
55
58
|
const checksums = await this.readJsonFile(path.join(targetDirectory, ".napp", "checksums.json"), "bundle checksums");
|
|
56
59
|
await this.verifyChecksums(targetDirectory, checksums);
|
|
57
60
|
await this.manifestService.load(targetDirectory);
|
|
@@ -61,7 +64,7 @@ var AppBundleService = class {
|
|
|
61
64
|
checksums
|
|
62
65
|
};
|
|
63
66
|
};
|
|
64
|
-
|
|
67
|
+
collectRuntimeFiles = async (bundle) => {
|
|
65
68
|
const appDirectory = bundle.appDirectory;
|
|
66
69
|
const filePaths = new Set([path.relative(appDirectory, bundle.manifestPath), path.relative(appDirectory, bundle.mainEntryPath)]);
|
|
67
70
|
await this.collectDirectoryPaths(bundle.uiDirectoryPath, appDirectory, filePaths);
|
|
@@ -75,6 +78,23 @@ var AppBundleService = class {
|
|
|
75
78
|
filePaths: sortedPaths
|
|
76
79
|
};
|
|
77
80
|
};
|
|
81
|
+
collectSourceFiles = async (bundle) => {
|
|
82
|
+
const filePaths = /* @__PURE__ */ new Set();
|
|
83
|
+
await this.collectSourceDirectoryPaths(bundle.appDirectory, bundle.appDirectory, filePaths);
|
|
84
|
+
const sortedPaths = Array.from(filePaths).sort((left, right) => left.localeCompare(right));
|
|
85
|
+
const appFiles = {};
|
|
86
|
+
for (const relativePath of sortedPaths) {
|
|
87
|
+
if (bundle.manifest.main.kind === "wasi-http-component" && relativePath === bundle.manifest.main.entry) {
|
|
88
|
+
appFiles[relativePath] = SOURCE_WASM_PLACEHOLDER_BYTES;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
appFiles[relativePath] = new Uint8Array(await readFile(path.join(bundle.appDirectory, relativePath)));
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
appFiles,
|
|
95
|
+
filePaths: sortedPaths
|
|
96
|
+
};
|
|
97
|
+
};
|
|
78
98
|
collectDirectoryPaths = async (directoryPath, appDirectory, filePaths) => {
|
|
79
99
|
try {
|
|
80
100
|
const entries = await readdir(directoryPath, { withFileTypes: true });
|
|
@@ -91,9 +111,32 @@ var AppBundleService = class {
|
|
|
91
111
|
return;
|
|
92
112
|
}
|
|
93
113
|
};
|
|
94
|
-
|
|
114
|
+
collectSourceDirectoryPaths = async (directoryPath, appDirectory, filePaths) => {
|
|
115
|
+
try {
|
|
116
|
+
const entries = await readdir(directoryPath, { withFileTypes: true });
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
const entryPath = path.join(directoryPath, entry.name);
|
|
119
|
+
const relativePath = path.relative(appDirectory, entryPath).replace(/\\/g, "/");
|
|
120
|
+
if (entry.isDirectory()) {
|
|
121
|
+
if (this.shouldExcludeSourcePath(relativePath)) continue;
|
|
122
|
+
await this.collectSourceDirectoryPaths(entryPath, appDirectory, filePaths);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (!entry.isFile()) continue;
|
|
126
|
+
if (this.shouldExcludeSourcePath(relativePath)) continue;
|
|
127
|
+
filePaths.add(relativePath);
|
|
128
|
+
}
|
|
129
|
+
} catch {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
shouldExcludeSourcePath = (relativePath) => {
|
|
134
|
+
return relativePath === ".napp" || relativePath.startsWith(".napp/") || relativePath === "main/node_modules" || relativePath.startsWith("main/node_modules/") || relativePath === "main/dist" || relativePath.startsWith("main/dist/") || relativePath === "main/generated" || relativePath.startsWith("main/generated/");
|
|
135
|
+
};
|
|
136
|
+
buildMetadata = (appId, name, version, distributionMode) => {
|
|
95
137
|
return {
|
|
96
138
|
bundleFormatVersion: 1,
|
|
139
|
+
distributionMode,
|
|
97
140
|
appId,
|
|
98
141
|
name,
|
|
99
142
|
version,
|
|
@@ -101,6 +144,17 @@ var AppBundleService = class {
|
|
|
101
144
|
checksumsFile: ".napp/checksums.json"
|
|
102
145
|
};
|
|
103
146
|
};
|
|
147
|
+
normalizeMetadata = (rawMetadata) => {
|
|
148
|
+
return {
|
|
149
|
+
bundleFormatVersion: 1,
|
|
150
|
+
distributionMode: rawMetadata.distributionMode === "source" ? "source" : "bundle",
|
|
151
|
+
appId: String(rawMetadata.appId ?? ""),
|
|
152
|
+
name: String(rawMetadata.name ?? ""),
|
|
153
|
+
version: String(rawMetadata.version ?? ""),
|
|
154
|
+
entryManifest: "manifest.json",
|
|
155
|
+
checksumsFile: ".napp/checksums.json"
|
|
156
|
+
};
|
|
157
|
+
};
|
|
104
158
|
buildChecksums = (files) => {
|
|
105
159
|
const entries = Object.entries(files).sort(([left], [right]) => left.localeCompare(right));
|
|
106
160
|
return {
|
|
@@ -135,5 +189,6 @@ var AppBundleService = class {
|
|
|
135
189
|
}
|
|
136
190
|
};
|
|
137
191
|
};
|
|
192
|
+
const SOURCE_WASM_PLACEHOLDER_BYTES = Uint8Array.from(Buffer.from("AGFzbQEAAAABBwFgAn9/AX8DAgEABxMBD3N1bW1hcml6ZV9ub3RlcwAACg0BCwAgACABakHIAWoL", "base64"));
|
|
138
193
|
//#endregion
|
|
139
194
|
export { AppBundleService };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//#region src/bundle/app-bundle.types.d.ts
|
|
2
|
+
type AppDistributionMode = "bundle" | "source";
|
|
2
3
|
type AppBundleMetadata = {
|
|
3
4
|
bundleFormatVersion: 1;
|
|
5
|
+
distributionMode: AppDistributionMode;
|
|
4
6
|
appId: string;
|
|
5
7
|
name: string;
|
|
6
8
|
version: string;
|
|
@@ -23,4 +25,4 @@ type AppBundleExtractResult = {
|
|
|
23
25
|
checksums: AppBundleChecksums;
|
|
24
26
|
};
|
|
25
27
|
//#endregion
|
|
26
|
-
export { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult };
|
|
28
|
+
export { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult, AppDistributionMode };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { version } from "../package.js";
|
|
2
2
|
import { CreateCommand } from "../commands/create.controller.js";
|
|
3
|
+
import { AppRuntimeToolchainService } from "../runtime/app-runtime-toolchain.service.js";
|
|
4
|
+
import { AppBuildService } from "../runtime/app-build.service.js";
|
|
3
5
|
import { RunCommand } from "../commands/run.controller.js";
|
|
4
6
|
import { DevCommand } from "../commands/dev.controller.js";
|
|
5
7
|
import { GrantCommand } from "../commands/grant.controller.js";
|
|
@@ -15,8 +17,6 @@ import { RevokeCommand } from "../commands/revoke.controller.js";
|
|
|
15
17
|
import { UninstallCommand } from "../commands/uninstall.controller.js";
|
|
16
18
|
import { UpdateCommand } from "../commands/update.controller.js";
|
|
17
19
|
import { ValidatePublishCommand } from "../commands/validate-publish.controller.js";
|
|
18
|
-
import { AppRuntimeToolchainService } from "../runtime/app-runtime-toolchain.service.js";
|
|
19
|
-
import { AppBuildService } from "../runtime/app-build.service.js";
|
|
20
20
|
import { AppRuntimeOptionsService } from "./app-runtime-options.service.js";
|
|
21
21
|
//#region src/cli/app-runtime-cli.service.ts
|
|
22
22
|
var AppRuntimeCliService = class {
|
|
@@ -191,6 +191,7 @@ var AppRuntimeCliService = class {
|
|
|
191
191
|
await new PackCommand().run({
|
|
192
192
|
appDirectory: target,
|
|
193
193
|
outputPath: options.outputPath,
|
|
194
|
+
mode: options.mode,
|
|
194
195
|
json: options.json,
|
|
195
196
|
write: this.write
|
|
196
197
|
});
|
|
@@ -203,6 +204,7 @@ var AppRuntimeCliService = class {
|
|
|
203
204
|
metadataPath: options.metadataPath,
|
|
204
205
|
apiBaseUrl: options.apiBaseUrl,
|
|
205
206
|
token: options.token,
|
|
207
|
+
mode: options.mode,
|
|
206
208
|
json: options.json,
|
|
207
209
|
write: this.write
|
|
208
210
|
});
|
|
@@ -213,6 +215,7 @@ var AppRuntimeCliService = class {
|
|
|
213
215
|
await new ValidatePublishCommand().run({
|
|
214
216
|
appDirectory: target,
|
|
215
217
|
metadataPath: options.metadataPath,
|
|
218
|
+
mode: options.mode,
|
|
216
219
|
json: options.json,
|
|
217
220
|
write: this.write
|
|
218
221
|
});
|
|
@@ -341,9 +344,9 @@ var AppRuntimeCliService = class {
|
|
|
341
344
|
this.write(" napp build <app-dir> [--install] [--json]\n");
|
|
342
345
|
this.write(" napp doctor [--json]\n");
|
|
343
346
|
this.write(" napp <run|dev> <app-dir|app-id> [--host 127.0.0.1] [--port 3100] [--data /path] [--json] [--document scope=/path]\n");
|
|
344
|
-
this.write(" napp pack <app-dir> [--out bundle.napp] [--json]\n");
|
|
345
|
-
this.write(" napp publish <app-dir> [--meta marketplace.json] [--api-base <url>] [--token <token>] [--json]\n");
|
|
346
|
-
this.write(" napp validate-publish <app-dir> [--meta marketplace.json] [--json]\n");
|
|
347
|
+
this.write(" napp pack <app-dir> [--mode source|bundle] [--out bundle.napp] [--json]\n");
|
|
348
|
+
this.write(" napp publish <app-dir> [--mode source|bundle] [--meta marketplace.json] [--api-base <url>] [--token <token>] [--json]\n");
|
|
349
|
+
this.write(" napp validate-publish <app-dir> [--mode source|bundle] [--meta marketplace.json] [--json]\n");
|
|
347
350
|
this.write(" napp install <app-dir|bundle.napp|app-id[@version]> [--registry <url>] [--json]\n");
|
|
348
351
|
this.write(" napp update <app-id> [--version <version>] [--registry <url>] [--json]\n");
|
|
349
352
|
this.write(" napp uninstall <app-id> [--purge-data] [--json]\n");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
1
2
|
import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
|
|
2
3
|
import { AppScaffoldTemplate } from "../scaffold/app-scaffold.service.js";
|
|
3
4
|
|
|
@@ -16,6 +17,7 @@ type CreateCliOptions = {
|
|
|
16
17
|
type PackCliOptions = {
|
|
17
18
|
json: boolean;
|
|
18
19
|
outputPath?: string;
|
|
20
|
+
mode: AppDistributionMode;
|
|
19
21
|
};
|
|
20
22
|
type BuildCliOptions = {
|
|
21
23
|
json: boolean;
|
|
@@ -50,6 +52,7 @@ type PublishCliOptions = {
|
|
|
50
52
|
metadataPath?: string;
|
|
51
53
|
apiBaseUrl?: string;
|
|
52
54
|
token?: string;
|
|
55
|
+
mode: AppDistributionMode;
|
|
53
56
|
};
|
|
54
57
|
declare class AppRuntimeOptionsService {
|
|
55
58
|
readTarget: (command: string, rawArgs: string[]) => {
|
|
@@ -68,6 +71,7 @@ declare class AppRuntimeOptionsService {
|
|
|
68
71
|
readGrantOptions: (rawArgs: string[]) => GrantCliOptions;
|
|
69
72
|
readRevokeOptions: (rawArgs: string[]) => RevokeCliOptions;
|
|
70
73
|
readPublishOptions: (rawArgs: string[]) => PublishCliOptions;
|
|
74
|
+
private readDistributionMode;
|
|
71
75
|
private assignDocumentGrant;
|
|
72
76
|
private readDocumentScopeId;
|
|
73
77
|
private requireOptionValue;
|
|
@@ -35,7 +35,10 @@ var AppRuntimeOptionsService = class {
|
|
|
35
35
|
throw new Error("--template 只支持 starter、ts-http 或 ts-http-lite。");
|
|
36
36
|
};
|
|
37
37
|
readPackOptions = (rawArgs) => {
|
|
38
|
-
const options = {
|
|
38
|
+
const options = {
|
|
39
|
+
json: false,
|
|
40
|
+
mode: "source"
|
|
41
|
+
};
|
|
39
42
|
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
40
43
|
const current = rawArgs[index];
|
|
41
44
|
if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
|
|
@@ -48,6 +51,10 @@ var AppRuntimeOptionsService = class {
|
|
|
48
51
|
options.outputPath = this.requireOptionValue(current, nextValue);
|
|
49
52
|
index += 1;
|
|
50
53
|
break;
|
|
54
|
+
case "--mode":
|
|
55
|
+
options.mode = this.readDistributionMode(this.requireOptionValue(current, nextValue));
|
|
56
|
+
index += 1;
|
|
57
|
+
break;
|
|
51
58
|
default: throw new Error(`未知参数:${current}`);
|
|
52
59
|
}
|
|
53
60
|
}
|
|
@@ -231,7 +238,10 @@ var AppRuntimeOptionsService = class {
|
|
|
231
238
|
return options;
|
|
232
239
|
};
|
|
233
240
|
readPublishOptions = (rawArgs) => {
|
|
234
|
-
const options = {
|
|
241
|
+
const options = {
|
|
242
|
+
json: false,
|
|
243
|
+
mode: "source"
|
|
244
|
+
};
|
|
235
245
|
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
236
246
|
const current = rawArgs[index];
|
|
237
247
|
if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
|
|
@@ -252,11 +262,19 @@ var AppRuntimeOptionsService = class {
|
|
|
252
262
|
options.token = this.requireOptionValue(current, nextValue);
|
|
253
263
|
index += 1;
|
|
254
264
|
break;
|
|
265
|
+
case "--mode":
|
|
266
|
+
options.mode = this.readDistributionMode(this.requireOptionValue(current, nextValue));
|
|
267
|
+
index += 1;
|
|
268
|
+
break;
|
|
255
269
|
default: throw new Error(`未知参数:${current}`);
|
|
256
270
|
}
|
|
257
271
|
}
|
|
258
272
|
return options;
|
|
259
273
|
};
|
|
274
|
+
readDistributionMode = (rawMode) => {
|
|
275
|
+
if (rawMode === "source" || rawMode === "bundle") return rawMode;
|
|
276
|
+
throw new Error("--mode 只支持 source 或 bundle。");
|
|
277
|
+
};
|
|
260
278
|
assignDocumentGrant = (documentGrantMap, rawGrant) => {
|
|
261
279
|
const delimiterIndex = rawGrant.indexOf("=");
|
|
262
280
|
if (delimiterIndex < 1) throw new Error("--document 必须使用 scopeId=/absolute/or/relative/path 格式。");
|
|
@@ -5,10 +5,11 @@ var PackCommand = class {
|
|
|
5
5
|
this.bundleService = bundleService;
|
|
6
6
|
}
|
|
7
7
|
run = async (params) => {
|
|
8
|
-
const { appDirectory, outputPath, json, write } = params;
|
|
8
|
+
const { appDirectory, outputPath, mode, json, write } = params;
|
|
9
9
|
const result = await this.bundleService.packAppDirectory({
|
|
10
10
|
appDirectory,
|
|
11
|
-
outputPath
|
|
11
|
+
outputPath,
|
|
12
|
+
mode
|
|
12
13
|
});
|
|
13
14
|
if (json) {
|
|
14
15
|
write(`${JSON.stringify({
|
|
@@ -17,7 +18,7 @@ var PackCommand = class {
|
|
|
17
18
|
}, null, 2)}\n`);
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
|
-
write(`Packed ${result.metadata.name} ${result.metadata.version}\n`);
|
|
21
|
+
write(`Packed ${result.metadata.name} ${result.metadata.version} (${result.metadata.distributionMode})\n`);
|
|
21
22
|
write(`Bundle: ${result.bundlePath}\n`);
|
|
22
23
|
};
|
|
23
24
|
};
|
|
@@ -5,12 +5,13 @@ var PublishCommand = class {
|
|
|
5
5
|
this.publishService = publishService;
|
|
6
6
|
}
|
|
7
7
|
run = async (params) => {
|
|
8
|
-
const { appDirectory, metadataPath, apiBaseUrl, token, json, write } = params;
|
|
8
|
+
const { appDirectory, metadataPath, apiBaseUrl, token, mode, json, write } = params;
|
|
9
9
|
const result = await this.publishService.publish({
|
|
10
10
|
appDirectory,
|
|
11
11
|
metadataPath,
|
|
12
12
|
apiBaseUrl,
|
|
13
|
-
token
|
|
13
|
+
token,
|
|
14
|
+
mode
|
|
14
15
|
});
|
|
15
16
|
if (json) {
|
|
16
17
|
write(`${JSON.stringify({
|
|
@@ -20,7 +21,7 @@ var PublishCommand = class {
|
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
23
|
write(`${result.created ? "Published" : "Updated"} ${result.item.name} (${result.item.appId}) ${result.item.latestVersion}\n`);
|
|
23
|
-
write(`
|
|
24
|
+
write(`Distribution: ${result.distribution.path} (${result.distribution.mode})\n`);
|
|
24
25
|
if (result.item.webUrl) write(`Details: ${result.item.webUrl}\n`);
|
|
25
26
|
write(`Install: ${result.item.install.command}\n`);
|
|
26
27
|
};
|
|
@@ -5,10 +5,11 @@ var ValidatePublishCommand = class {
|
|
|
5
5
|
this.validationService = validationService;
|
|
6
6
|
}
|
|
7
7
|
run = async (params) => {
|
|
8
|
-
const { appDirectory, metadataPath, json, write } = params;
|
|
8
|
+
const { appDirectory, metadataPath, mode, json, write } = params;
|
|
9
9
|
const result = await this.validationService.validate({
|
|
10
10
|
appDirectory,
|
|
11
|
-
metadataPath
|
|
11
|
+
metadataPath,
|
|
12
|
+
mode
|
|
12
13
|
});
|
|
13
14
|
if (json) {
|
|
14
15
|
write(`${JSON.stringify({
|
|
@@ -18,6 +19,7 @@ var ValidatePublishCommand = class {
|
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
write(`Publish validation ok for ${result.appId}@${result.version}\n`);
|
|
22
|
+
write(`Distribution mode: ${result.distributionMode}\n`);
|
|
21
23
|
write(`Main kind: ${result.mainKind}\n`);
|
|
22
24
|
write(`Main: ${result.mainEntryPath}\n`);
|
|
23
25
|
write(`Metadata: ${result.metadataPath}\n`);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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
|
-
import { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult } from "./bundle/app-bundle.types.js";
|
|
3
|
+
import { AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult, AppDistributionMode } from "./bundle/app-bundle.types.js";
|
|
4
4
|
import { AppBundleService } from "./bundle/app-bundle.service.js";
|
|
5
5
|
import { AppDocumentGrantMap, AppDocumentGrantMutationResult, AppDocumentGrantState, AppInstalledPermissionState, AppPermissionSummary, ResolvedDocumentGrant, ResolvedPermissions } from "./permissions/app-permissions.types.js";
|
|
6
6
|
import { AppPermissionsService } from "./permissions/app-permissions.service.js";
|
|
@@ -22,6 +22,8 @@ import { AppInstallSourceKind, AppRegistry, AppRegistryAppRecord, AppRegistryIns
|
|
|
22
22
|
import { AppRegistryService } from "./registry/app-registry.service.js";
|
|
23
23
|
import { AppGrantService } from "./permissions/app-grant.service.js";
|
|
24
24
|
import { GrantCommand } from "./commands/grant.controller.js";
|
|
25
|
+
import { AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeToolStatus, AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
26
|
+
import { AppBuildResult, AppBuildService } from "./runtime/app-build.service.js";
|
|
25
27
|
import { AppRegistryConfigService } from "./registry/app-registry-config.service.js";
|
|
26
28
|
import { AppRemoteRegistryClientService } from "./registry/app-remote-registry-client.service.js";
|
|
27
29
|
import { AppInfoResult, AppInstallResult, AppLaunchResolution, AppUninstallResult, AppUpdateResult, InstalledAppListItem } from "./install/app-installation.types.js";
|
|
@@ -45,7 +47,5 @@ import { AppPublishValidationResult, AppPublishValidationService, AppPublishVali
|
|
|
45
47
|
import { ValidatePublishCommand } from "./commands/validate-publish.controller.js";
|
|
46
48
|
import { WasmtimeWasiHttpComponentHandle, WasmtimeWasiHttpComponentService, WasmtimeWasiHttpComponentStartOptions } from "./runtime/wasmtime-wasi-http-component.service.js";
|
|
47
49
|
import { AppHostHandle, AppHostService, AppHostStartOptions } from "./host/app-host.service.js";
|
|
48
|
-
import { AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeToolStatus, AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
49
|
-
import { AppBuildResult, AppBuildService } from "./runtime/app-build.service.js";
|
|
50
50
|
import { UiServerService } from "./ui/ui-server.service.js";
|
|
51
|
-
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, AppPublishValidationResult, AppPublishValidationService, AppPublishValidationWarning, AppPublishValidationWarningCode, AppPublisher, AppRegistry, AppRegistryAppRecord, AppRegistryConfig, AppRegistryConfigService, AppRegistryConfigSnapshot, AppRegistryInstalledVersion, AppRegistryService, AppRemoteRegistryClientService, AppRemoteRegistryDocument, AppRemoteRegistryResolution, AppRemoteRegistryVersion, AppRunResult, AppRuntimeCliService, AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeOptionsService, AppRuntimeToolStatus, AppRuntimeToolchainService, AppScaffoldFile, AppScaffoldResult, AppScaffoldService, AppScaffoldTemplate, AppTsHttpLiteScaffoldTemplateService, 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, ValidatePublishCommand, WasmDocumentSummaryInput, WasmMainRunnerService, WasmSidecarClientService, WasmtimeWasiHttpComponentHandle, WasmtimeWasiHttpComponentService, WasmtimeWasiHttpComponentStartOptions };
|
|
51
|
+
export { AppBuildResult, AppBuildService, AppBundleChecksums, AppBundleExtractResult, AppBundleMetadata, AppBundlePackResult, AppBundleService, AppCoreWasmMainManifest, AppDistributionMode, 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, AppPublishValidationResult, AppPublishValidationService, AppPublishValidationWarning, AppPublishValidationWarningCode, AppPublisher, AppRegistry, AppRegistryAppRecord, AppRegistryConfig, AppRegistryConfigService, AppRegistryConfigSnapshot, AppRegistryInstalledVersion, AppRegistryService, AppRemoteRegistryClientService, AppRemoteRegistryDocument, AppRemoteRegistryResolution, AppRemoteRegistryVersion, AppRunResult, AppRuntimeCliService, AppRuntimeCommandResult, AppRuntimeDoctorResult, AppRuntimeOptionsService, AppRuntimeToolStatus, AppRuntimeToolchainService, AppScaffoldFile, AppScaffoldResult, AppScaffoldService, AppScaffoldTemplate, AppTsHttpLiteScaffoldTemplateService, 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, ValidatePublishCommand, WasmDocumentSummaryInput, WasmMainRunnerService, WasmSidecarClientService, WasmtimeWasiHttpComponentHandle, WasmtimeWasiHttpComponentService, WasmtimeWasiHttpComponentStartOptions };
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,8 @@ import { WasmSidecarClientService } from "./sidecar/wasm-sidecar-client.service.
|
|
|
13
13
|
import { WasmMainRunnerService } from "./runtime/wasm-main-runner.service.js";
|
|
14
14
|
import { AppInstanceService } from "./host/app-instance.service.js";
|
|
15
15
|
import { AppHomeService } from "./paths/app-home.service.js";
|
|
16
|
+
import { AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
17
|
+
import { AppBuildService } from "./runtime/app-build.service.js";
|
|
16
18
|
import { DEFAULT_APP_REGISTRY_URL } from "./registry/app-remote-registry.types.js";
|
|
17
19
|
import { AppRegistryConfigService } from "./registry/app-registry-config.service.js";
|
|
18
20
|
import { AppRemoteRegistryClientService } from "./registry/app-remote-registry-client.service.js";
|
|
@@ -38,8 +40,6 @@ import { UninstallCommand } from "./commands/uninstall.controller.js";
|
|
|
38
40
|
import { UpdateCommand } from "./commands/update.controller.js";
|
|
39
41
|
import { AppPublishValidationService } from "./publish/app-publish-validation.service.js";
|
|
40
42
|
import { ValidatePublishCommand } from "./commands/validate-publish.controller.js";
|
|
41
|
-
import { AppRuntimeToolchainService } from "./runtime/app-runtime-toolchain.service.js";
|
|
42
|
-
import { AppBuildService } from "./runtime/app-build.service.js";
|
|
43
43
|
import { AppRuntimeOptionsService } from "./cli/app-runtime-options.service.js";
|
|
44
44
|
import { AppRuntimeCliService } from "./cli/app-runtime-cli.service.js";
|
|
45
45
|
export { AppBuildService, AppBundleService, AppGrantService, AppHomeService, AppHostService, AppInstallationService, AppInstanceService, AppManifestService, AppMarketplaceClientService, AppMarketplaceMetadataService, AppPermissionsService, AppPublishService, AppPublishValidationService, AppRegistryConfigService, AppRegistryService, AppRemoteRegistryClientService, AppRuntimeCliService, AppRuntimeOptionsService, AppRuntimeToolchainService, AppScaffoldService, AppTsHttpLiteScaffoldTemplateService, 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, ValidatePublishCommand, WasmMainRunnerService, WasmSidecarClientService, WasmtimeWasiHttpComponentService };
|
|
@@ -3,6 +3,7 @@ import { AppBundleService } from "../bundle/app-bundle.service.js";
|
|
|
3
3
|
import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
|
|
4
4
|
import { AppHomeService } from "../paths/app-home.service.js";
|
|
5
5
|
import { AppRegistryService } from "../registry/app-registry.service.js";
|
|
6
|
+
import { AppBuildService } from "../runtime/app-build.service.js";
|
|
6
7
|
import { AppRegistryConfigService } from "../registry/app-registry-config.service.js";
|
|
7
8
|
import { AppRemoteRegistryClientService } from "../registry/app-remote-registry-client.service.js";
|
|
8
9
|
import { AppInfoResult, AppInstallResult, AppLaunchResolution, AppUninstallResult, AppUpdateResult, InstalledAppListItem } from "./app-installation.types.js";
|
|
@@ -12,10 +13,11 @@ declare class AppInstallationService {
|
|
|
12
13
|
private readonly appHomeService;
|
|
13
14
|
private readonly bundleService;
|
|
14
15
|
private readonly manifestService;
|
|
16
|
+
private readonly buildService;
|
|
15
17
|
private readonly registryService;
|
|
16
18
|
private readonly registryConfigService;
|
|
17
19
|
private readonly remoteRegistryClient;
|
|
18
|
-
constructor(appHomeService?: AppHomeService, bundleService?: AppBundleService, manifestService?: AppManifestService, registryService?: AppRegistryService, registryConfigService?: AppRegistryConfigService, remoteRegistryClient?: AppRemoteRegistryClientService);
|
|
20
|
+
constructor(appHomeService?: AppHomeService, bundleService?: AppBundleService, manifestService?: AppManifestService, buildService?: AppBuildService, registryService?: AppRegistryService, registryConfigService?: AppRegistryConfigService, remoteRegistryClient?: AppRemoteRegistryClientService);
|
|
19
21
|
install: (appSource: string, options?: {
|
|
20
22
|
registryUrl?: string;
|
|
21
23
|
}) => Promise<AppInstallResult>;
|
|
@@ -32,6 +34,7 @@ declare class AppInstallationService {
|
|
|
32
34
|
private detectLocalSourceType;
|
|
33
35
|
private parseRegistrySpec;
|
|
34
36
|
private looksLikePath;
|
|
37
|
+
private materializeDistribution;
|
|
35
38
|
}
|
|
36
39
|
//#endregion
|
|
37
40
|
export { AppInstallationService };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AppManifestService } from "../manifest/app-manifest.service.js";
|
|
2
2
|
import { AppBundleService } from "../bundle/app-bundle.service.js";
|
|
3
3
|
import { AppHomeService } from "../paths/app-home.service.js";
|
|
4
|
+
import { AppBuildService } from "../runtime/app-build.service.js";
|
|
4
5
|
import { AppRegistryConfigService } from "../registry/app-registry-config.service.js";
|
|
5
6
|
import { AppRemoteRegistryClientService } from "../registry/app-remote-registry-client.service.js";
|
|
6
7
|
import { AppRegistryService } from "../registry/app-registry.service.js";
|
|
@@ -8,10 +9,11 @@ import { access, cp, mkdir, rm } from "node:fs/promises";
|
|
|
8
9
|
import path from "node:path";
|
|
9
10
|
//#region src/install/app-installation.service.ts
|
|
10
11
|
var AppInstallationService = class {
|
|
11
|
-
constructor(appHomeService = new AppHomeService(), bundleService = new AppBundleService(), manifestService = new AppManifestService(), registryService = new AppRegistryService(appHomeService), registryConfigService = new AppRegistryConfigService(appHomeService), remoteRegistryClient = new AppRemoteRegistryClientService(new AppRegistryConfigService(appHomeService))) {
|
|
12
|
+
constructor(appHomeService = new AppHomeService(), bundleService = new AppBundleService(), manifestService = new AppManifestService(), buildService = new AppBuildService(), registryService = new AppRegistryService(appHomeService), registryConfigService = new AppRegistryConfigService(appHomeService), remoteRegistryClient = new AppRemoteRegistryClientService(new AppRegistryConfigService(appHomeService))) {
|
|
12
13
|
this.appHomeService = appHomeService;
|
|
13
14
|
this.bundleService = bundleService;
|
|
14
15
|
this.manifestService = manifestService;
|
|
16
|
+
this.buildService = buildService;
|
|
15
17
|
this.registryService = registryService;
|
|
16
18
|
this.registryConfigService = registryConfigService;
|
|
17
19
|
this.remoteRegistryClient = remoteRegistryClient;
|
|
@@ -28,10 +30,14 @@ var AppInstallationService = class {
|
|
|
28
30
|
targetDirectory: tempDirectory
|
|
29
31
|
})).bundlePath;
|
|
30
32
|
const extractedDirectory = path.join(tempDirectory, "bundle");
|
|
31
|
-
await this.bundleService.extractBundle({
|
|
33
|
+
const extractedMetadata = await this.bundleService.extractBundle({
|
|
32
34
|
bundlePath,
|
|
33
35
|
targetDirectory: extractedDirectory
|
|
34
36
|
});
|
|
37
|
+
await this.materializeDistribution({
|
|
38
|
+
appDirectory: extractedDirectory,
|
|
39
|
+
distributionMode: extractedMetadata.metadata.distributionMode
|
|
40
|
+
});
|
|
35
41
|
const manifestBundle = await this.manifestService.load(extractedDirectory);
|
|
36
42
|
const installDirectory = this.appHomeService.getInstallDirectory(manifestBundle.manifest.id, manifestBundle.manifest.version);
|
|
37
43
|
if (source.kind === "registry" && manifestBundle.manifest.id !== source.registryResolution.appId) throw new Error(`bundle manifest.appId 与 registry 请求不一致:期望 ${source.registryResolution.appId},实际 ${manifestBundle.manifest.id}`);
|
|
@@ -51,6 +57,7 @@ var AppInstallationService = class {
|
|
|
51
57
|
installDirectory,
|
|
52
58
|
dataDirectory,
|
|
53
59
|
sourceKind: source.kind,
|
|
60
|
+
distributionMode: source.kind === "registry" ? source.registryResolution.distributionMode : extractedMetadata.metadata.distributionMode,
|
|
54
61
|
sourceRef: source.sourceRef,
|
|
55
62
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
56
63
|
permissions: manifestBundle.manifest.permissions ?? {},
|
|
@@ -67,6 +74,7 @@ var AppInstallationService = class {
|
|
|
67
74
|
dataDirectory,
|
|
68
75
|
sourceKind: source.kind,
|
|
69
76
|
sourceRef: source.sourceRef,
|
|
77
|
+
distributionMode: registryRecord.installedVersions[registryRecord.activeVersion]?.distributionMode,
|
|
70
78
|
permissions: registryRecord.installedVersions[registryRecord.activeVersion]?.permissions ?? {},
|
|
71
79
|
registryUrl: registryRecord.installedVersions[registryRecord.activeVersion]?.registryUrl,
|
|
72
80
|
bundleUrl: registryRecord.installedVersions[registryRecord.activeVersion]?.bundleUrl,
|
|
@@ -138,7 +146,8 @@ var AppInstallationService = class {
|
|
|
138
146
|
appId: appRecord.appId,
|
|
139
147
|
name: appRecord.name,
|
|
140
148
|
activeVersion: appRecord.activeVersion,
|
|
141
|
-
sourceKind: appRecord.installedVersions[appRecord.activeVersion]?.sourceKind ?? "directory"
|
|
149
|
+
sourceKind: appRecord.installedVersions[appRecord.activeVersion]?.sourceKind ?? "directory",
|
|
150
|
+
distributionMode: appRecord.installedVersions[appRecord.activeVersion]?.distributionMode
|
|
142
151
|
}));
|
|
143
152
|
};
|
|
144
153
|
info = async (appId) => {
|
|
@@ -155,6 +164,7 @@ var AppInstallationService = class {
|
|
|
155
164
|
version: versionRecord.version,
|
|
156
165
|
installDirectory: versionRecord.installDirectory,
|
|
157
166
|
sourceKind: versionRecord.sourceKind,
|
|
167
|
+
distributionMode: versionRecord.distributionMode,
|
|
158
168
|
sourceRef: versionRecord.sourceRef,
|
|
159
169
|
installedAt: versionRecord.installedAt,
|
|
160
170
|
permissions: versionRecord.permissions,
|
|
@@ -251,6 +261,14 @@ var AppInstallationService = class {
|
|
|
251
261
|
looksLikePath = (appSource) => {
|
|
252
262
|
return appSource.startsWith(".") || appSource.startsWith("/") || appSource.includes(path.sep);
|
|
253
263
|
};
|
|
264
|
+
materializeDistribution = async (params) => {
|
|
265
|
+
if (params.distributionMode !== "source") return;
|
|
266
|
+
if ((await this.manifestService.load(params.appDirectory)).manifest.main.kind !== "wasi-http-component") return;
|
|
267
|
+
await this.buildService.build({
|
|
268
|
+
appDirectory: params.appDirectory,
|
|
269
|
+
install: true
|
|
270
|
+
});
|
|
271
|
+
};
|
|
254
272
|
};
|
|
255
273
|
//#endregion
|
|
256
274
|
export { AppInstallationService };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppPermissions } from "../manifest/app-manifest.types.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
|
|
3
4
|
import { AppPublisher } from "../registry/app-remote-registry.types.js";
|
|
4
5
|
import { AppInstallSourceKind } from "../registry/app-registry.types.js";
|
|
@@ -11,6 +12,7 @@ type AppInstallResult = {
|
|
|
11
12
|
installDirectory: string;
|
|
12
13
|
dataDirectory: string;
|
|
13
14
|
sourceKind: AppInstallSourceKind;
|
|
15
|
+
distributionMode?: AppDistributionMode;
|
|
14
16
|
sourceRef: string;
|
|
15
17
|
permissions: AppPermissions;
|
|
16
18
|
registryUrl?: string;
|
|
@@ -28,6 +30,7 @@ type AppInfoResult = {
|
|
|
28
30
|
version: string;
|
|
29
31
|
installDirectory: string;
|
|
30
32
|
sourceKind: AppInstallSourceKind;
|
|
33
|
+
distributionMode?: AppDistributionMode;
|
|
31
34
|
sourceRef: string;
|
|
32
35
|
installedAt: string;
|
|
33
36
|
permissions: AppPermissions;
|
|
@@ -43,6 +46,7 @@ type InstalledAppListItem = {
|
|
|
43
46
|
name: string;
|
|
44
47
|
activeVersion: string;
|
|
45
48
|
sourceKind: AppInstallSourceKind;
|
|
49
|
+
distributionMode?: AppDistributionMode;
|
|
46
50
|
};
|
|
47
51
|
type AppUninstallResult = {
|
|
48
52
|
appId: string;
|
package/dist/package.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppManifestService } from "../manifest/app-manifest.service.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
import { AppBundleService } from "../bundle/app-bundle.service.js";
|
|
3
4
|
import { AppMarketplaceMetadataService } from "./app-marketplace-metadata.service.js";
|
|
4
5
|
|
|
@@ -14,6 +15,7 @@ type AppPublishValidationResult = {
|
|
|
14
15
|
metadataPath: string;
|
|
15
16
|
appId: string;
|
|
16
17
|
version: string;
|
|
18
|
+
distributionMode: AppDistributionMode;
|
|
17
19
|
mainKind: string;
|
|
18
20
|
mainEntryPath: string;
|
|
19
21
|
mainEntrySizeBytes: number;
|
|
@@ -29,6 +31,7 @@ declare class AppPublishValidationService {
|
|
|
29
31
|
validate: (params: {
|
|
30
32
|
appDirectory: string;
|
|
31
33
|
metadataPath?: string;
|
|
34
|
+
mode?: AppDistributionMode;
|
|
32
35
|
}) => Promise<AppPublishValidationResult>;
|
|
33
36
|
private buildWarnings;
|
|
34
37
|
private formatBytes;
|
|
@@ -14,9 +14,11 @@ var AppPublishValidationService = class {
|
|
|
14
14
|
this.bundleService = bundleService;
|
|
15
15
|
}
|
|
16
16
|
validate = async (params) => {
|
|
17
|
-
const appDirectory =
|
|
17
|
+
const { appDirectory: inputAppDirectory, metadataPath: inputMetadataPath, mode } = params;
|
|
18
|
+
const appDirectory = path.resolve(inputAppDirectory);
|
|
19
|
+
const distributionMode = mode ?? "source";
|
|
18
20
|
const bundle = await this.manifestService.load(appDirectory);
|
|
19
|
-
const metadataPath =
|
|
21
|
+
const metadataPath = inputMetadataPath ? path.resolve(inputMetadataPath) : path.join(appDirectory, "marketplace.json");
|
|
20
22
|
await this.metadataService.load({
|
|
21
23
|
appDirectory,
|
|
22
24
|
manifest: bundle.manifest,
|
|
@@ -26,7 +28,8 @@ var AppPublishValidationService = class {
|
|
|
26
28
|
try {
|
|
27
29
|
const packResult = await this.bundleService.packAppDirectory({
|
|
28
30
|
appDirectory,
|
|
29
|
-
outputPath: path.join(tempDirectory, `${bundle.manifest.id}-${bundle.manifest.version}.napp`)
|
|
31
|
+
outputPath: path.join(tempDirectory, `${bundle.manifest.id}-${bundle.manifest.version}.napp`),
|
|
32
|
+
mode: distributionMode
|
|
30
33
|
});
|
|
31
34
|
const mainEntryStats = await stat(bundle.mainEntryPath);
|
|
32
35
|
const warnings = this.buildWarnings({
|
|
@@ -39,6 +42,7 @@ var AppPublishValidationService = class {
|
|
|
39
42
|
metadataPath,
|
|
40
43
|
appId: bundle.manifest.id,
|
|
41
44
|
version: bundle.manifest.version,
|
|
45
|
+
distributionMode,
|
|
42
46
|
mainKind: bundle.manifest.main.kind,
|
|
43
47
|
mainEntryPath: bundle.mainEntryPath,
|
|
44
48
|
mainEntrySizeBytes: mainEntryStats.size,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppManifestService } from "../manifest/app-manifest.service.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
import { AppBundleService } from "../bundle/app-bundle.service.js";
|
|
3
4
|
import { AppPublishResult } from "./app-publish.types.js";
|
|
4
5
|
import { AppMarketplaceClientService } from "./app-marketplace-client.service.js";
|
|
@@ -18,6 +19,7 @@ declare class AppPublishService {
|
|
|
18
19
|
metadataPath?: string;
|
|
19
20
|
apiBaseUrl?: string;
|
|
20
21
|
token?: string;
|
|
22
|
+
mode?: AppDistributionMode;
|
|
21
23
|
}) => Promise<AppPublishResult>;
|
|
22
24
|
private resolvePublishActor;
|
|
23
25
|
private fetchCurrentPlatformUser;
|
|
@@ -18,6 +18,7 @@ var AppPublishService = class {
|
|
|
18
18
|
}
|
|
19
19
|
publish = async (params) => {
|
|
20
20
|
const { appDirectory: inputAppDirectory, metadataPath, apiBaseUrl, token } = params;
|
|
21
|
+
const distributionMode = params.mode ?? "source";
|
|
21
22
|
const appDirectory = path.resolve(inputAppDirectory);
|
|
22
23
|
const manifestBundle = await this.manifestService.load(appDirectory);
|
|
23
24
|
const metadata = await this.metadataService.load({
|
|
@@ -30,7 +31,10 @@ var AppPublishService = class {
|
|
|
30
31
|
explicitToken: token,
|
|
31
32
|
appId: manifestBundle.manifest.id
|
|
32
33
|
});
|
|
33
|
-
const bundle = await this.bundleService.packAppDirectory({
|
|
34
|
+
const bundle = await this.bundleService.packAppDirectory({
|
|
35
|
+
appDirectory,
|
|
36
|
+
mode: distributionMode
|
|
37
|
+
});
|
|
34
38
|
const bundleBytes = Buffer.from(await readFile(bundle.bundlePath));
|
|
35
39
|
const bundleSha256 = createHash("sha256").update(bundleBytes).digest("hex");
|
|
36
40
|
const publishFiles = await this.metadataService.collectPublishFiles({
|
|
@@ -52,6 +56,7 @@ var AppPublishService = class {
|
|
|
52
56
|
homepage: metadata.homepage,
|
|
53
57
|
featured: metadata.featured ?? false,
|
|
54
58
|
publisher: actor.publisher,
|
|
59
|
+
distributionMode,
|
|
55
60
|
manifest: manifestBundle.manifest,
|
|
56
61
|
permissions: manifestBundle.manifest.permissions ?? {},
|
|
57
62
|
bundleBase64: bundleBytes.toString("base64"),
|
|
@@ -67,9 +72,10 @@ var AppPublishService = class {
|
|
|
67
72
|
apiBaseUrl,
|
|
68
73
|
token: actor.token
|
|
69
74
|
}),
|
|
70
|
-
|
|
75
|
+
distribution: {
|
|
71
76
|
path: bundle.bundlePath,
|
|
72
|
-
sha256: bundleSha256
|
|
77
|
+
sha256: bundleSha256,
|
|
78
|
+
mode: distributionMode
|
|
73
79
|
}
|
|
74
80
|
};
|
|
75
81
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppManifest, AppPermissions } from "../manifest/app-manifest.types.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
import { AppPublisher } from "../registry/app-remote-registry.types.js";
|
|
3
4
|
|
|
4
5
|
//#region src/publish/app-publish.types.d.ts
|
|
@@ -35,6 +36,7 @@ type AppPublishPayload = {
|
|
|
35
36
|
homepage?: string;
|
|
36
37
|
featured: boolean;
|
|
37
38
|
publisher: AppPublisher;
|
|
39
|
+
distributionMode: AppDistributionMode;
|
|
38
40
|
manifest: AppManifest;
|
|
39
41
|
permissions: AppPermissions;
|
|
40
42
|
bundleBase64: string;
|
|
@@ -56,9 +58,10 @@ type AppPublishResult = {
|
|
|
56
58
|
registry: string;
|
|
57
59
|
};
|
|
58
60
|
};
|
|
59
|
-
|
|
61
|
+
distribution: {
|
|
60
62
|
path: string;
|
|
61
63
|
sha256: string;
|
|
64
|
+
mode: AppDistributionMode;
|
|
62
65
|
};
|
|
63
66
|
fileCount: number;
|
|
64
67
|
};
|
|
@@ -22,6 +22,7 @@ declare class AppRegistryService {
|
|
|
22
22
|
sourceKind: AppInstallSourceKind;
|
|
23
23
|
sourceRef: string;
|
|
24
24
|
installedAt: string;
|
|
25
|
+
distributionMode?: AppRegistryInstalledVersion["distributionMode"];
|
|
25
26
|
permissions: AppPermissions;
|
|
26
27
|
registryUrl?: string;
|
|
27
28
|
bundleUrl?: string;
|
|
@@ -36,7 +36,7 @@ var AppRegistryService = class {
|
|
|
36
36
|
return appRecord.installedVersions[appRecord.activeVersion];
|
|
37
37
|
};
|
|
38
38
|
upsertInstallation = async (params) => {
|
|
39
|
-
const { appId, name, description, version, installDirectory, dataDirectory, sourceKind, sourceRef, installedAt, permissions, registryUrl, bundleUrl, sha256, publisher } = params;
|
|
39
|
+
const { appId, name, description, version, installDirectory, dataDirectory, sourceKind, sourceRef, installedAt, distributionMode, permissions, registryUrl, bundleUrl, sha256, publisher } = params;
|
|
40
40
|
const registry = await this.load();
|
|
41
41
|
const currentRecord = registry.apps[appId];
|
|
42
42
|
const nextRecord = {
|
|
@@ -53,6 +53,7 @@ var AppRegistryService = class {
|
|
|
53
53
|
sourceKind,
|
|
54
54
|
sourceRef,
|
|
55
55
|
installedAt,
|
|
56
|
+
distributionMode,
|
|
56
57
|
permissions,
|
|
57
58
|
registryUrl,
|
|
58
59
|
bundleUrl,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppPermissions } from "../manifest/app-manifest.types.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
|
|
3
4
|
import { AppPublisher } from "./app-remote-registry.types.js";
|
|
4
5
|
|
|
@@ -10,6 +11,7 @@ type AppRegistryInstalledVersion = {
|
|
|
10
11
|
sourceKind: AppInstallSourceKind;
|
|
11
12
|
sourceRef: string;
|
|
12
13
|
installedAt: string;
|
|
14
|
+
distributionMode?: AppDistributionMode;
|
|
13
15
|
permissions: AppPermissions;
|
|
14
16
|
registryUrl?: string;
|
|
15
17
|
bundleUrl?: string;
|
|
@@ -25,7 +25,8 @@ var AppRemoteRegistryClientService = class {
|
|
|
25
25
|
description: versionRecord.description ?? document.description,
|
|
26
26
|
publisher: versionRecord.publisher,
|
|
27
27
|
permissions: versionRecord.permissions,
|
|
28
|
-
|
|
28
|
+
distributionMode: versionRecord.dist.kind === "source" ? "source" : "bundle",
|
|
29
|
+
bundleUrl: new URL(versionRecord.dist.artifact ?? versionRecord.dist.source ?? versionRecord.dist.bundle, metadataUrl).toString(),
|
|
29
30
|
sha256: versionRecord.dist.sha256
|
|
30
31
|
};
|
|
31
32
|
};
|
|
@@ -72,7 +73,10 @@ var AppRemoteRegistryClientService = class {
|
|
|
72
73
|
publisher: this.parsePublisher(candidate.publisher, version),
|
|
73
74
|
permissions: candidate.permissions,
|
|
74
75
|
dist: {
|
|
76
|
+
kind: distCandidate.kind === "source" || distCandidate.kind === "bundle" ? distCandidate.kind : void 0,
|
|
77
|
+
artifact: this.readOptionalString(distCandidate.artifact, `versions.${version}.dist.artifact`),
|
|
75
78
|
bundle: this.readRequiredString(distCandidate.bundle, `versions.${version}.dist.bundle`),
|
|
79
|
+
source: this.readOptionalString(distCandidate.source, `versions.${version}.dist.source`),
|
|
76
80
|
sha256: this.readRequiredString(distCandidate.sha256, `versions.${version}.dist.sha256`)
|
|
77
81
|
}
|
|
78
82
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppPermissions } from "../manifest/app-manifest.types.js";
|
|
2
|
+
import { AppDistributionMode } from "../bundle/app-bundle.types.js";
|
|
2
3
|
|
|
3
4
|
//#region src/registry/app-remote-registry.types.d.ts
|
|
4
5
|
declare const DEFAULT_APP_REGISTRY_URL = "https://apps-registry.nextclaw.io/api/v1/apps/registry/";
|
|
@@ -25,7 +26,10 @@ type AppRemoteRegistryVersion = {
|
|
|
25
26
|
publisher?: AppPublisher;
|
|
26
27
|
permissions?: AppPermissions;
|
|
27
28
|
dist: {
|
|
29
|
+
kind?: AppDistributionMode;
|
|
30
|
+
artifact?: string;
|
|
28
31
|
bundle: string;
|
|
32
|
+
source?: string;
|
|
29
33
|
sha256: string;
|
|
30
34
|
};
|
|
31
35
|
};
|
|
@@ -45,6 +49,7 @@ type AppRemoteRegistryResolution = {
|
|
|
45
49
|
description?: string;
|
|
46
50
|
publisher?: AppPublisher;
|
|
47
51
|
permissions?: AppPermissions;
|
|
52
|
+
distributionMode: AppDistributionMode;
|
|
48
53
|
bundleUrl: string;
|
|
49
54
|
sha256: string;
|
|
50
55
|
};
|