@easytwin/devkit 0.1.1 → 0.1.3
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 +6 -5
- package/dist/bin.js +1873 -165
- package/dist/index.d.ts +440 -54
- package/dist/index.js +2133 -332
- package/dist/runtime/twin-app-host.js +265 -0
- package/dist/runtime/twin-apps.js +48 -0
- package/dist/runtime/twin-runtime.js +128301 -0
- package/dist/runtime-types/index.d.ts +6 -1
- package/package.json +5 -3
- package/skills/easytwin-bootstrap/SKILL.md +7 -5
- package/skills/easytwin-core/SKILL.md +2 -2
- package/skills/easytwin-core/references/engine.md +2 -2
- package/skills/easytwin-develop/SKILL.md +9 -6
- package/skills/easytwin-render/SKILL.md +56 -17
- package/skills/easytwin-render/references/intro.md +8 -4
- package/skills/easytwin-render/references/scene-and-assets.md +1 -1
- package/skills/easytwin-scene/SKILL.md +57 -54
- package/skills/easytwin-test/SKILL.md +47 -0
- package/skills/easytwin-upload/SKILL.md +39 -25
- package/dist/bin.js.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ declare const CONFIG_FILE_NAME = "easytwin.config.json";
|
|
|
5
5
|
*/
|
|
6
6
|
declare const DEFAULT_BASE_URL = "http://saas-twin.k8s.dtstack.cn/";
|
|
7
7
|
/** 官方测试环境域名。 */
|
|
8
|
-
declare const TEST_BASE_URL = "http://
|
|
8
|
+
declare const TEST_BASE_URL = "http://172.16.125.3:10100/";
|
|
9
9
|
/**
|
|
10
10
|
* 官方 OSS(twin runtime baseOSSUrl)。系统资产由此拼出:
|
|
11
11
|
* `{ossUrl}/easytwin/system/libs/webp-wasm.wasm`、
|
|
@@ -30,6 +30,20 @@ interface EasyTwinConfig {
|
|
|
30
30
|
baseUrl?: string;
|
|
31
31
|
/** twin runtime 资产根(baseOSSUrl);缺省官方 OSS,可覆盖为 CDN/自建存储。 */
|
|
32
32
|
ossUrl?: string;
|
|
33
|
+
/**
|
|
34
|
+
* 关联场景摘要,由 scene list / 场景树刷新写入(D17)。
|
|
35
|
+
* 不含场景 JSON 本体;下次 list 全量覆盖。
|
|
36
|
+
*/
|
|
37
|
+
scenes?: ConfigScene[];
|
|
38
|
+
}
|
|
39
|
+
/** 写入 easytwin.config.json 的关联场景摘要(对应 listScenes 的可序列化子集)。 */
|
|
40
|
+
interface ConfigScene {
|
|
41
|
+
/** Scene Key,与 `easytwin scene pull <id>` 对应。 */
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
linkedSceneId?: string;
|
|
45
|
+
snapshotUrl?: string;
|
|
46
|
+
defaultLoading?: boolean;
|
|
33
47
|
}
|
|
34
48
|
/** 解析 + 环境变量覆盖后的最终配置。 */
|
|
35
49
|
interface ResolvedConfig {
|
|
@@ -38,7 +52,7 @@ interface ResolvedConfig {
|
|
|
38
52
|
baseUrl: string;
|
|
39
53
|
/** twin runtime baseOSSUrl(系统库 draco/basis/webp、custom script 与相对路径资产);缺省官方 OSS。 */
|
|
40
54
|
ossUrl: string;
|
|
41
|
-
/** 本地测试模式:appId/appSecret 均为 "test" 时启用,scene/upload 走本地 mock 不发请求。 */
|
|
55
|
+
/** 本地测试模式:appId/appSecret 均为 "test" 时启用,scene/upload/pull 走本地 mock 不发请求。 */
|
|
42
56
|
mock: boolean;
|
|
43
57
|
source: "file" | "env";
|
|
44
58
|
}
|
|
@@ -67,19 +81,25 @@ interface InitResult {
|
|
|
67
81
|
}
|
|
68
82
|
/** init 的 lib 实现:生成配置文件 + 追加 gitignore(与插件配置向导共用同一实现)。 */
|
|
69
83
|
declare function initConfig(input: EasyTwinConfig, cwd: string): Promise<InitResult>;
|
|
84
|
+
/** 把场景摘要写入配置 `scenes`(全量覆盖该数组,保留其余字段)。 */
|
|
85
|
+
declare function writeConfigScenes(cwd: string, scenes: ConfigScene[]): Promise<void>;
|
|
70
86
|
|
|
71
87
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
88
|
+
* 认证与路径以内部 swagger 为准(标签:SDK 应用场景 / 分享相关 / SDK 应用代码)。
|
|
89
|
+
* 全仓唯一认证头注入点:`x-app-id` = App ID,`x-app-secret` = App Secret(D20)。
|
|
90
|
+
* share 代码与场景列表接口无路径参数(D21 / D22);上传不请求仍走 OP 网关的 workspace-config(D24)。
|
|
74
91
|
*/
|
|
75
|
-
declare const
|
|
76
|
-
declare const
|
|
77
|
-
/** TODO(swagger): 应用标识头名待定(上传目标空间由 App ID 决定)。 */
|
|
78
|
-
declare const APP_ID_HEADER = "X-Easytwin-App-Id";
|
|
92
|
+
declare const APP_ID_HEADER = "x-app-id";
|
|
93
|
+
declare const AUTH_HEADER = "x-app-secret";
|
|
79
94
|
declare const ENDPOINTS: {
|
|
80
|
-
|
|
81
|
-
readonly
|
|
82
|
-
|
|
95
|
+
/** POST 已关联场景列表(分享路径,空 body)。 */
|
|
96
|
+
readonly linkedScenes: () => string;
|
|
97
|
+
/** POST 拉取工作区全部代码文件(分享路径,空 body)。 */
|
|
98
|
+
readonly workspaceCodePull: () => string;
|
|
99
|
+
/** POST 一次推送 create/update/delete(分享路径)。 */
|
|
100
|
+
readonly workspaceCodePush: () => string;
|
|
101
|
+
/** GET 工作区文件约束(仍带 applicationId,走 OP 网关;上传不调用,拉取失败则降级)。 */
|
|
102
|
+
readonly workspaceConfig: (applicationId: string) => string;
|
|
83
103
|
};
|
|
84
104
|
declare class EasyTwinApiError extends Error {
|
|
85
105
|
readonly status: number;
|
|
@@ -87,16 +107,19 @@ declare class EasyTwinApiError extends Error {
|
|
|
87
107
|
constructor(status: number, message: string, body?: unknown);
|
|
88
108
|
}
|
|
89
109
|
interface RequestOptions {
|
|
90
|
-
method?: "GET" | "POST" | "PUT" | "DELETE";
|
|
110
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
91
111
|
headers?: Record<string, string>;
|
|
92
112
|
body?: string | null;
|
|
93
113
|
signal?: AbortSignal;
|
|
94
114
|
}
|
|
95
115
|
declare class EasyTwinClient {
|
|
96
116
|
readonly baseUrl: string;
|
|
97
|
-
/**
|
|
117
|
+
/** twin runtime / 场景快照资产根(baseOSSUrl)。 */
|
|
118
|
+
readonly ossUrl: string;
|
|
119
|
+
/** 接入凭证 App ID;写入 `x-app-id`,workspace-config 路径仍可用。 */
|
|
120
|
+
readonly appId: string;
|
|
121
|
+
/** 本地测试模式:true 时 scene/upload/pull 走本地 mock,不发网络请求(见 config.ts)。 */
|
|
98
122
|
readonly mock: boolean;
|
|
99
|
-
private readonly appId;
|
|
100
123
|
private readonly appSecret;
|
|
101
124
|
constructor(config: ResolvedConfig);
|
|
102
125
|
/** 全仓唯一认证头注入点。 */
|
|
@@ -115,21 +138,49 @@ declare class EasyTwinClient {
|
|
|
115
138
|
private handleStatus;
|
|
116
139
|
}
|
|
117
140
|
|
|
141
|
+
/** swagger `SdkApplicationLinkedSceneVo`。 */
|
|
142
|
+
interface LinkedScene {
|
|
143
|
+
/** 关联记录 ID。 */
|
|
144
|
+
id: string;
|
|
145
|
+
/** SDK 业务标识 Scene Key(list/pull 的主键)。 */
|
|
146
|
+
sceneKey: string;
|
|
147
|
+
name: string;
|
|
148
|
+
defaultLoading: boolean;
|
|
149
|
+
sourceSceneId: string;
|
|
150
|
+
sourceProjectId: string;
|
|
151
|
+
sourceSceneName: string;
|
|
152
|
+
sourceProjectName: string;
|
|
153
|
+
sourceLost: boolean;
|
|
154
|
+
/** 场景快照 JSON 的 OSS 相对路径(或绝对 URL)。 */
|
|
155
|
+
snapshotUrl: string;
|
|
156
|
+
snapshotUpdatedAt: string;
|
|
157
|
+
}
|
|
118
158
|
interface SceneSummary {
|
|
159
|
+
/** Scene Key,与 `easytwin scene pull <id>` 对应。 */
|
|
119
160
|
id: string;
|
|
120
161
|
name: string;
|
|
162
|
+
linkedSceneId?: string;
|
|
163
|
+
snapshotUrl?: string;
|
|
164
|
+
defaultLoading?: boolean;
|
|
121
165
|
}
|
|
122
166
|
interface SceneDetail {
|
|
123
167
|
id: string;
|
|
124
168
|
name: string;
|
|
125
169
|
/**
|
|
126
|
-
*
|
|
170
|
+
* 场景快照 JSON 原始内容。
|
|
127
171
|
* 结构以 easytwin-runtime 的 SceneJson 为准(见 skills/easytwin-scene)。
|
|
128
172
|
*/
|
|
129
173
|
payload: unknown;
|
|
130
174
|
}
|
|
175
|
+
/** 从信封/Runtime VO/数组中取出场景列表。 */
|
|
176
|
+
declare function extractSceneArray(data: unknown): unknown[];
|
|
177
|
+
/** 把 swagger 关联场景 / Runtime scenes 规范为 LinkedScene[]。 */
|
|
178
|
+
declare function normalizeLinkedScenes(data: unknown): LinkedScene[];
|
|
131
179
|
declare function normalizeSceneList(data: unknown): SceneSummary[];
|
|
132
|
-
|
|
180
|
+
/** 把 list 结果收成配置里的 scenes 摘要(省略空可选字段)。 */
|
|
181
|
+
declare function toConfigScenes(scenes: SceneSummary[]): ConfigScene[];
|
|
182
|
+
/** 拼接场景快照地址:绝对 URL 原样使用,否则挂到 ossUrl 下。 */
|
|
183
|
+
declare function resolveSnapshotUrl(ossUrl: string, snapshotUrl: string): string;
|
|
133
184
|
/** devkit 包内本地测试场景文件名(4.4 本地测试模式)。 */
|
|
134
185
|
declare const EXAMPLE_SCENE_FILE = "scene.example.json";
|
|
135
186
|
/** 本地测试模式下场景列表展示的名字(示例文件本身不含场景级 name)。 */
|
|
@@ -147,6 +198,7 @@ declare function deriveExampleSceneId(payload: unknown): string;
|
|
|
147
198
|
declare function exampleSceneSummary(exampleFile?: string): Promise<SceneSummary>;
|
|
148
199
|
declare function listScenes(client: EasyTwinClient, options?: {
|
|
149
200
|
exampleFile?: string;
|
|
201
|
+
cwd?: string;
|
|
150
202
|
}): Promise<SceneSummary[]>;
|
|
151
203
|
declare function pullScene(client: EasyTwinClient, id: string, options?: {
|
|
152
204
|
exampleFile?: string;
|
|
@@ -177,19 +229,69 @@ interface UploadProgress {
|
|
|
177
229
|
}
|
|
178
230
|
interface UploadOptions {
|
|
179
231
|
onProgress?: (progress: UploadProgress) => void;
|
|
180
|
-
/**
|
|
232
|
+
/** 额外忽略规则;默认已跳过插件产物与相关文件(D23)。 */
|
|
181
233
|
ignore?: (relPath: string) => boolean;
|
|
182
234
|
}
|
|
235
|
+
interface CollectedFile {
|
|
236
|
+
relPath: string;
|
|
237
|
+
absPath: string;
|
|
238
|
+
size: number;
|
|
239
|
+
}
|
|
183
240
|
interface UploadResult {
|
|
184
241
|
fileCount: number;
|
|
185
242
|
byteCount: number;
|
|
243
|
+
created: number;
|
|
244
|
+
updated: number;
|
|
245
|
+
deleted: number;
|
|
246
|
+
unchanged: number;
|
|
186
247
|
/** 本地测试模式(dry-run)时置 true:未真正上传。 */
|
|
187
248
|
mock?: boolean;
|
|
188
249
|
}
|
|
189
|
-
interface
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
250
|
+
interface UploadCreate {
|
|
251
|
+
file: CollectedFile;
|
|
252
|
+
content: string;
|
|
253
|
+
}
|
|
254
|
+
interface UploadUpdate {
|
|
255
|
+
file: CollectedFile;
|
|
256
|
+
id: string;
|
|
257
|
+
content: string;
|
|
258
|
+
}
|
|
259
|
+
interface UploadDelete {
|
|
260
|
+
id: string;
|
|
261
|
+
filePath: string;
|
|
262
|
+
}
|
|
263
|
+
/** 对照远端文件,本地区分新增 / 更新 / 删除(D21,一次 push)。 */
|
|
264
|
+
interface WorkspaceUploadPlan {
|
|
265
|
+
creates: UploadCreate[];
|
|
266
|
+
updates: UploadUpdate[];
|
|
267
|
+
deletes: UploadDelete[];
|
|
268
|
+
unchanged: CollectedFile[];
|
|
269
|
+
}
|
|
270
|
+
/** 上传/拉取共同跳过:插件产物、agent 目录、构建产物与凭据。 */
|
|
271
|
+
declare const WORKSPACE_IGNORED_DIRS: Set<string>;
|
|
272
|
+
declare const WORKSPACE_IGNORED_FILES: Set<string>;
|
|
273
|
+
/** 与 push 服务端一致的工作区代码扩展名(D25)。 */
|
|
274
|
+
declare const WORKSPACE_CODE_EXTENSIONS: readonly [".ts", ".tsx", ".js", ".json"];
|
|
275
|
+
/** 工作区本地预览测试文件:不参与 pull/upload(D27)。 */
|
|
276
|
+
declare function isWorkspaceSpecFile(relPath: string): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* 插件产物、凭据、构建目录与场景快照。
|
|
279
|
+
* 不含 `*.spec.ts`(预览测试扫描需要读这些文件)。
|
|
280
|
+
*/
|
|
281
|
+
declare function isIgnoredWorkspacePath(relPath: string): boolean;
|
|
282
|
+
/** 跳过插件产物/凭据/场景快照,以及本地预览测试文件 `*.spec.ts`(D23 / D26 / D27)。 */
|
|
283
|
+
declare function defaultWorkspaceIgnore(relPath: string): boolean;
|
|
284
|
+
/** swagger `SdkApplicationWorkspaceCodeConfigVo`。 */
|
|
285
|
+
interface WorkspaceCodeConfig {
|
|
286
|
+
allowedFileExtensions: string[];
|
|
287
|
+
maxCodeFiles: number;
|
|
288
|
+
maxCodeDirectoryDepth: number;
|
|
289
|
+
}
|
|
290
|
+
/** swagger `SdkApplicationWorkspaceCodeFileVo`。 */
|
|
291
|
+
interface WorkspaceCodeFile {
|
|
292
|
+
id: string;
|
|
293
|
+
filePath: string;
|
|
294
|
+
content: string;
|
|
193
295
|
}
|
|
194
296
|
/** 递归收集目录下全部文件(默认跳过 .git),按相对路径升序排列,保证顺序稳定。 */
|
|
195
297
|
declare function collectFiles(dir: string, ignore?: (relPath: string) => boolean): Promise<CollectedFile[]>;
|
|
@@ -197,13 +299,151 @@ declare function buildMultipartBody(boundary: string, fields: Record<string, str
|
|
|
197
299
|
name: string;
|
|
198
300
|
content: Buffer;
|
|
199
301
|
}): Buffer;
|
|
200
|
-
|
|
302
|
+
declare function normalizePath(relPath: string): string;
|
|
303
|
+
declare function normalizeWorkspaceConfig(data: unknown): WorkspaceCodeConfig;
|
|
304
|
+
declare function normalizeWorkspaceFiles(data: unknown): WorkspaceCodeFile[];
|
|
305
|
+
/** 是否为可同步的工作区代码文件(`.ts` / `.tsx` / `.js` / `.json`)。 */
|
|
306
|
+
declare function isWorkspaceCodeFile(relPath: string): boolean;
|
|
307
|
+
/** 目录深度:根文件为 0,`src/a.ts` 为 1,`src/utils/a.ts` 为 2。 */
|
|
308
|
+
declare function directoryDepth(relPath: string): number;
|
|
309
|
+
declare function assertUploadable(files: CollectedFile[], config: WorkspaceCodeConfig): void;
|
|
310
|
+
/**
|
|
311
|
+
* 对照远端工作区文件,把本地文件分成新增 / 更新 / 删除 / 未变。
|
|
312
|
+
* 不做本地清单:每次上传以本次 GET 的远端列表为准。
|
|
313
|
+
*/
|
|
314
|
+
declare function planWorkspaceUpload(local: {
|
|
315
|
+
file: CollectedFile;
|
|
316
|
+
content: string;
|
|
317
|
+
}[], remote: WorkspaceCodeFile[]): WorkspaceUploadPlan;
|
|
318
|
+
declare function formatUploadResult(result: UploadResult): string;
|
|
319
|
+
/** swagger `PushSdkApplicationWorkspaceCodeDto`:字段均可选,有变更才带上。 */
|
|
320
|
+
declare function buildWorkspacePushBody(plan: WorkspaceUploadPlan): Record<string, unknown> | null;
|
|
321
|
+
/**
|
|
322
|
+
* 全量对齐上传目录:对照远端工作区,本地 diff 后一次 push(create/update/delete)。
|
|
323
|
+
* 不请求仍走 OP 网关的 workspace-config(D24);只收集 `.ts`/`.tsx`/`.js`/`.json`(D25)。本地测试模式(mock)时退化为 dry-run。
|
|
324
|
+
*/
|
|
201
325
|
declare function uploadDirectory(client: EasyTwinClient, dir: string, options?: UploadOptions): Promise<UploadResult>;
|
|
202
326
|
|
|
327
|
+
declare const DEFAULT_ENTRY_PATH = "src/main.ts";
|
|
328
|
+
/** 与 easytwin-render 可上传子集示例对齐的默认 TwinApp 子类入口。 */
|
|
329
|
+
declare const DEFAULT_MAIN_TS = "import { TwinApp, type TwinAppContext } from \"@easytwin/apps\";\n\nexport default class App extends TwinApp {\n async init(ctx: TwinAppContext) {\n // engine / container \u5DF2\u6709;scene / camera \u4E3A null\n void ctx;\n }\n\n async onSceneLoaded(ctx: TwinAppContext) {\n // \u573A\u666F\u5B57\u6BB5\u6709\u503C;\u5728\u6B64\u52A0\u7269\u4F53 / \u7ED1\u4E8B\u4EF6,\u5E76\u7528 ctx.sceneCleanup \u5BF9\u79F0\u62C6\u9664\n void ctx;\n }\n\n onUpdate(ctx: TwinAppContext, delta: number, elapsed: number) {\n void ctx;\n void delta;\n void elapsed;\n }\n\n onDispose(ctx: TwinAppContext) {\n void ctx;\n }\n}\n";
|
|
330
|
+
type WorkspaceChangeKind = "identical" | "remote-only" | "local-only" | "modified" | "seed";
|
|
331
|
+
interface WorkspaceFileChange {
|
|
332
|
+
path: string;
|
|
333
|
+
kind: WorkspaceChangeKind;
|
|
334
|
+
localContent?: string;
|
|
335
|
+
remoteContent?: string;
|
|
336
|
+
}
|
|
337
|
+
interface WorkspacePullPlan {
|
|
338
|
+
remoteEmpty: boolean;
|
|
339
|
+
seededDefaults: boolean;
|
|
340
|
+
mock?: boolean;
|
|
341
|
+
skippedRemotePaths: string[];
|
|
342
|
+
changes: WorkspaceFileChange[];
|
|
343
|
+
}
|
|
344
|
+
interface WorkspacePullOptions {
|
|
345
|
+
/** 用远端内容覆盖内容冲突的本地文件;仅本地文件仍不删除。 */
|
|
346
|
+
force?: boolean;
|
|
347
|
+
/** 只算计划,不写盘。 */
|
|
348
|
+
dryRun?: boolean;
|
|
349
|
+
ignore?: (relPath: string) => boolean;
|
|
350
|
+
}
|
|
351
|
+
interface WorkspacePullResult {
|
|
352
|
+
plan: WorkspacePullPlan;
|
|
353
|
+
written: string[];
|
|
354
|
+
skippedConflicts: string[];
|
|
355
|
+
dryRun?: boolean;
|
|
356
|
+
mock?: boolean;
|
|
357
|
+
}
|
|
358
|
+
declare function defaultPullIgnore(relPath: string): boolean;
|
|
359
|
+
/** 拒绝逃逸、空路径与凭据文件,避免远端路径写到工作区外。 */
|
|
360
|
+
declare function isSafeRelPath(relPath: string): boolean;
|
|
361
|
+
/**
|
|
362
|
+
* 对照远端工作区代码与本地目录,算出 diff 计划。
|
|
363
|
+
* mock 或远端无有效文件时,本地缺省入口视为 seed。
|
|
364
|
+
*/
|
|
365
|
+
declare function planWorkspacePull(client: EasyTwinClient, dir: string, options?: Pick<WorkspacePullOptions, "ignore">): Promise<WorkspacePullPlan>;
|
|
366
|
+
interface WorkspacePullApplyResult {
|
|
367
|
+
written: string[];
|
|
368
|
+
skippedConflicts: string[];
|
|
369
|
+
}
|
|
370
|
+
/** 按计划写盘:seed 与 remote-only 始终写入;modified 仅 force 时覆盖;不删 local-only。 */
|
|
371
|
+
declare function applyWorkspacePull(dir: string, plan: WorkspacePullPlan, options?: {
|
|
372
|
+
force?: boolean;
|
|
373
|
+
}): Promise<WorkspacePullApplyResult>;
|
|
374
|
+
declare function pullWorkspace(client: EasyTwinClient, dir: string, options?: WorkspacePullOptions): Promise<WorkspacePullResult>;
|
|
375
|
+
declare function formatWorkspacePullPlan(plan: WorkspacePullPlan): string;
|
|
376
|
+
declare function formatWorkspacePullResult(result: WorkspacePullResult): string;
|
|
377
|
+
declare function workspacePullHasConflicts(plan: WorkspacePullPlan): boolean;
|
|
378
|
+
declare function workspacePullPendingWrites(plan: WorkspacePullPlan, force?: boolean): string[];
|
|
379
|
+
|
|
380
|
+
/** 用户代码固定入口(相对工作区根)。 */
|
|
381
|
+
declare const USER_ENTRY = "src/main.ts";
|
|
382
|
+
/** CLI 缺省输出路径(相对工作区根)。 */
|
|
383
|
+
declare const DEFAULT_BUNDLE_OUT = "dist/main.js";
|
|
384
|
+
/** 白名单允许的裸模块。 */
|
|
385
|
+
declare const RUNTIME_MODULE = "@easytwin/runtime";
|
|
386
|
+
declare const APPS_MODULE = "@easytwin/apps";
|
|
387
|
+
declare class BundleError extends Error {
|
|
388
|
+
constructor(message: string);
|
|
389
|
+
}
|
|
390
|
+
interface BundleUserCodeOptions {
|
|
391
|
+
cwd: string;
|
|
392
|
+
/** 缺省不落盘,只返回产物字符串(插件内存编译);CLI 传入绝对/相对路径。 */
|
|
393
|
+
outFile?: string;
|
|
394
|
+
}
|
|
395
|
+
interface BundleWorkspaceModuleOptions extends BundleUserCodeOptions {
|
|
396
|
+
/** 相对 cwd 的入口文件(posix 或当前平台分隔符均可)。 */
|
|
397
|
+
entry: string;
|
|
398
|
+
/** 入口缺失时的报错文案;缺省按路径拼一条。 */
|
|
399
|
+
missingEntryMessage?: string;
|
|
400
|
+
}
|
|
401
|
+
interface BundleResult {
|
|
402
|
+
code: string;
|
|
403
|
+
warnings: string[];
|
|
404
|
+
}
|
|
405
|
+
/** 打包工作区任意入口。产物标准 ESM + inline sourcemap;仅允许 @easytwin/runtime 与 @easytwin/apps。 */
|
|
406
|
+
declare function bundleWorkspaceModule(options: BundleWorkspaceModuleOptions): Promise<BundleResult>;
|
|
407
|
+
/** 打包工作区 src/main.ts。产物标准 ESM + inline sourcemap;仅允许 @easytwin/runtime 与 @easytwin/apps。 */
|
|
408
|
+
declare function bundleUserCode(options: BundleUserCodeOptions): Promise<BundleResult>;
|
|
409
|
+
/** 若工作区尚未同步 runtime 类型,返回提示文案;已同步则返回 undefined。 */
|
|
410
|
+
declare function typesMissingHint(cwd: string): Promise<string | undefined>;
|
|
411
|
+
interface SourceMapJson {
|
|
412
|
+
sources?: string[];
|
|
413
|
+
mappings?: string;
|
|
414
|
+
}
|
|
415
|
+
declare function extractInlineSourceMap(code: string): SourceMapJson | undefined;
|
|
416
|
+
/**
|
|
417
|
+
* 把 bundled JS 的 stack(blob: 行号)映射回 TS 源码行号。
|
|
418
|
+
* 映射失败时原样返回。
|
|
419
|
+
*/
|
|
420
|
+
declare function remapErrorStack(stack: string, bundledCode: string): string;
|
|
421
|
+
|
|
422
|
+
interface WorkspaceTestCase {
|
|
423
|
+
/** `${file}:${name}`,文件内唯一。 */
|
|
424
|
+
id: string;
|
|
425
|
+
/** 相对工作区根的 posix 路径。 */
|
|
426
|
+
file: string;
|
|
427
|
+
name: string;
|
|
428
|
+
/** 除 ctx 外还有参数时,预览显示输入框。 */
|
|
429
|
+
hasInput: boolean;
|
|
430
|
+
/** 第二个参数名,作输入框占位。 */
|
|
431
|
+
inputName?: string;
|
|
432
|
+
}
|
|
433
|
+
/** 从 spec 源码解析命名导出的函数(跳过 default / type / class / 再导出)。 */
|
|
434
|
+
declare function parseExportedTestFunctions(source: string): Omit<WorkspaceTestCase, "id" | "file">[];
|
|
435
|
+
declare function workspaceTestId(file: string, name: string): string;
|
|
436
|
+
/** 扫描工作区 `*.spec.ts` 的命名导出函数。跳过插件产物目录,不跳过 spec 本身。 */
|
|
437
|
+
declare function listWorkspaceTests(cwd: string): Promise<WorkspaceTestCase[]>;
|
|
438
|
+
declare function bundleWorkspaceTestFile(options: {
|
|
439
|
+
cwd: string;
|
|
440
|
+
file: string;
|
|
441
|
+
}): Promise<BundleResult>;
|
|
442
|
+
|
|
203
443
|
type SyncTarget = "cursor" | "claude" | "codex" | "qoder";
|
|
204
444
|
type SyncTargetArg = SyncTarget | "all";
|
|
205
|
-
/**
|
|
206
|
-
declare const SKILL_NAMES: readonly ["easytwin-render", "easytwin-core", "easytwin-develop", "easytwin-bootstrap", "easytwin-scene", "easytwin-upload"];
|
|
445
|
+
/** 七件套清单(5.1),顺序即输出顺序。 */
|
|
446
|
+
declare const SKILL_NAMES: readonly ["easytwin-render", "easytwin-core", "easytwin-develop", "easytwin-bootstrap", "easytwin-scene", "easytwin-upload", "easytwin-test"];
|
|
207
447
|
type SyncAction = "created" | "updated" | "unchanged";
|
|
208
448
|
interface SyncEntrySummary {
|
|
209
449
|
name: string;
|
|
@@ -229,7 +469,9 @@ declare const META_FILE_NAME = ".easytwin-meta.json";
|
|
|
229
469
|
/** 用户项目内 runtime 类型落地目录(posix)。 */
|
|
230
470
|
declare const EASYTWIN_TYPES_DIR = ".easytwin/types";
|
|
231
471
|
declare const MINIMAL_TSCONFIG: string;
|
|
232
|
-
declare const TSCONFIG_PATHS_HINT = "\u5DF2\u6709 tsconfig.json,\u672A\u6539\u52A8\u3002\u8BF7\u5728 compilerOptions \u4E2D\u52A0\u5165:\n \"skipLibCheck\": true,\n \"paths\": {\n \"@easytwin/runtime\": [\".easytwin/types\"]\n }";
|
|
472
|
+
declare const TSCONFIG_PATHS_HINT = "\u5DF2\u6709 tsconfig.json,\u672A\u6539\u52A8\u3002\u8BF7\u5728 compilerOptions \u4E2D\u52A0\u5165:\n \"skipLibCheck\": true,\n \"paths\": {\n \"@easytwin/runtime\": [\".easytwin/types\"],\n \"@easytwin/apps\": [\".easytwin/types/apps\"]\n }";
|
|
473
|
+
declare const APPS_TYPES_FILE = "apps.d.ts";
|
|
474
|
+
declare const APPS_DTS = "import type { RuntimeEngine, RuntimeScene, SceneManager } from \"@easytwin/runtime\";\n\nexport type TwinAppContext = {\n app: {\n id: string;\n mode: \"preview\" | \"publish\";\n };\n engine: RuntimeEngine;\n container: HTMLElement;\n runtimeScene: RuntimeScene | null;\n scene: RuntimeScene[\"sceneObject\"] | null;\n camera: RuntimeScene[\"camera\"][\"main\"] | null;\n sceneManager: {\n currentSceneId: string;\n runtime: SceneManager | null;\n loadScene(sceneId: string): Promise<void>;\n };\n logger: {\n log(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n };\n assets: {\n text(path: string): Promise<string>;\n json<T = unknown>(path: string): Promise<T>;\n };\n cleanup(fn: () => void | Promise<void>): void;\n sceneCleanup(fn: () => void | Promise<void>): void;\n};\n\nexport declare abstract class TwinApp {\n init?(ctx: TwinAppContext): void | Promise<void>;\n onUpdate?(ctx: TwinAppContext, delta: number, elapsed: number): void;\n onBeforeSceneUnload?(ctx: TwinAppContext): void | Promise<void>;\n onSceneLoaded?(ctx: TwinAppContext): void | Promise<void>;\n onDispose?(ctx: TwinAppContext): void | Promise<void>;\n onError?(ctx: TwinAppContext, error: unknown): boolean | void;\n}\n\nexport declare function defineApp<T>(app: T): T;\n";
|
|
233
475
|
declare function buildRuntimeTypesContent(sourceDts: string): string;
|
|
234
476
|
declare function normalizeTargets(target?: SyncTargetArg | SyncTarget[]): SyncTarget[];
|
|
235
477
|
/** skills 源目录默认解析:CLI 下为 devkit 包内 skills/。插件 bundle 到 CJS 后 import.meta.url 为空,
|
|
@@ -261,37 +503,181 @@ interface SkillsStatus {
|
|
|
261
503
|
/** 供插件"缺失/过期时提示一次"使用:检测各目标当前同步状态。 */
|
|
262
504
|
declare function detectSkillsStatus(cwd: string, sourceDir?: string): Promise<SkillsStatus>;
|
|
263
505
|
|
|
264
|
-
/**
|
|
265
|
-
declare const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
506
|
+
/** 在线 TwinApp 编译 stub 露出的 `@easytwin/runtime` 导出名。本地整包 external,超出此集合只 warning。 */
|
|
507
|
+
declare const PORTABLE_RUNTIME_EXPORTS: readonly ["THREE", "RuntimeEngine", "SceneManager", "LoadSceneMode", "convertObjToComponentJson"];
|
|
508
|
+
type PortableRuntimeExport = (typeof PORTABLE_RUNTIME_EXPORTS)[number];
|
|
509
|
+
type TwinAppEngine = {
|
|
510
|
+
container: HTMLElement;
|
|
511
|
+
time: {
|
|
512
|
+
deltaTime: number;
|
|
513
|
+
elapsedTime: number;
|
|
514
|
+
};
|
|
515
|
+
mainScene?: TwinAppRuntimeScene | null;
|
|
516
|
+
getManager(ctor: unknown): TwinAppSceneManager | null;
|
|
517
|
+
destroy(): void;
|
|
518
|
+
};
|
|
519
|
+
type TwinAppRuntimeScene = {
|
|
520
|
+
sceneObject?: {
|
|
521
|
+
add(object: unknown): void;
|
|
522
|
+
remove(object: unknown): void;
|
|
523
|
+
} | null;
|
|
524
|
+
camera?: {
|
|
525
|
+
main?: unknown;
|
|
526
|
+
} | null;
|
|
527
|
+
};
|
|
528
|
+
type TwinAppSceneManager = {
|
|
529
|
+
loadScene(...args: unknown[]): Promise<unknown>;
|
|
530
|
+
};
|
|
531
|
+
type TwinAppContext = {
|
|
532
|
+
app: {
|
|
533
|
+
id: string;
|
|
534
|
+
mode: "preview" | "publish";
|
|
535
|
+
};
|
|
536
|
+
engine: TwinAppEngine;
|
|
537
|
+
container: HTMLElement;
|
|
538
|
+
runtimeScene: TwinAppRuntimeScene | null;
|
|
539
|
+
scene: TwinAppRuntimeScene["sceneObject"] | null;
|
|
540
|
+
camera: unknown | null;
|
|
541
|
+
sceneManager: {
|
|
542
|
+
currentSceneId: string;
|
|
543
|
+
runtime: TwinAppSceneManager | null;
|
|
544
|
+
loadScene(sceneId: string): Promise<void>;
|
|
545
|
+
};
|
|
546
|
+
logger: {
|
|
547
|
+
log(...args: unknown[]): void;
|
|
548
|
+
info(...args: unknown[]): void;
|
|
549
|
+
warn(...args: unknown[]): void;
|
|
550
|
+
error(...args: unknown[]): void;
|
|
551
|
+
};
|
|
552
|
+
assets: {
|
|
553
|
+
text(path: string): Promise<string>;
|
|
554
|
+
json<T = unknown>(path: string): Promise<T>;
|
|
555
|
+
};
|
|
556
|
+
cleanup(fn: () => void | Promise<void>): void;
|
|
557
|
+
sceneCleanup(fn: () => void | Promise<void>): void;
|
|
558
|
+
};
|
|
559
|
+
declare abstract class TwinApp {
|
|
560
|
+
init?(ctx: TwinAppContext): void | Promise<void>;
|
|
561
|
+
onUpdate?(ctx: TwinAppContext, delta: number, elapsed: number): void;
|
|
562
|
+
onBeforeSceneUnload?(ctx: TwinAppContext): void | Promise<void>;
|
|
563
|
+
onSceneLoaded?(ctx: TwinAppContext): void | Promise<void>;
|
|
564
|
+
onDispose?(ctx: TwinAppContext): void | Promise<void>;
|
|
565
|
+
onError?(ctx: TwinAppContext, error: unknown): boolean | void;
|
|
281
566
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
declare function
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
567
|
+
declare function defineApp<T>(app: T): T;
|
|
568
|
+
/** 把用户模块 default 导出收成 TwinApp 实例。函数式 `main` 不认。 */
|
|
569
|
+
declare function createAppInstance(appExport: unknown): TwinApp;
|
|
570
|
+
declare function portableRuntimeWarning(names: Iterable<string>): string | undefined;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* 把 ctx.assets 的相对路径落到工作区磁盘。规范化后必须仍在 cwd 内。
|
|
574
|
+
*/
|
|
575
|
+
declare function resolveWorkspaceAssetPath(cwd: string, relPath: string): string;
|
|
576
|
+
|
|
577
|
+
declare const LOCAL_LOAD_SCENE_ERROR = "\u672C\u5730\u9884\u89C8\u5355\u573A\u666F,\u4E0D\u80FD\u8C03\u7528 sceneManager.loadScene";
|
|
578
|
+
declare const MISSING_TICK_ERROR = "\u5F53\u524D runtime \u4E0D\u652F\u6301\u5F15\u64CE\u65F6\u949F(\u7F3A\u5C11 registerEngineTickListener)\u3002\u65E0\u6CD5\u8FD0\u884C onUpdate\u3002";
|
|
579
|
+
type TwinAppTickListener = (engine: TwinAppEngine) => void;
|
|
580
|
+
type TwinAppRuntimeModule = {
|
|
581
|
+
RuntimeEngine: {
|
|
582
|
+
create(config: Record<string, unknown>): Promise<TwinAppEngine>;
|
|
583
|
+
};
|
|
584
|
+
SceneManager: unknown;
|
|
585
|
+
LoadSceneMode: {
|
|
586
|
+
Single: unknown;
|
|
587
|
+
};
|
|
588
|
+
RuntimeSceneMode: {
|
|
589
|
+
Publish: unknown;
|
|
590
|
+
};
|
|
591
|
+
registerEngineTickListener?: (engine: TwinAppEngine, listener: TwinAppTickListener) => void;
|
|
592
|
+
unregisterEngineTickListener?: (engine: TwinAppEngine, listener: TwinAppTickListener) => void;
|
|
593
|
+
};
|
|
594
|
+
type TwinAppPreviewHostOptions = {
|
|
595
|
+
runtime: TwinAppRuntimeModule;
|
|
596
|
+
containerId: string;
|
|
597
|
+
ossUrl: string;
|
|
598
|
+
appId: string;
|
|
599
|
+
sceneId: string;
|
|
600
|
+
sceneJson: unknown;
|
|
601
|
+
customComponentDeps: Record<string, unknown>;
|
|
602
|
+
loadScene(engine: TwinAppEngine, sceneJson: unknown): Promise<void>;
|
|
603
|
+
readAsset(path: string): Promise<string>;
|
|
604
|
+
importUserModule?(code: string): Promise<{
|
|
605
|
+
default: unknown;
|
|
606
|
+
}>;
|
|
607
|
+
log?: (line: string) => void;
|
|
608
|
+
};
|
|
609
|
+
declare class TwinAppPreviewHost {
|
|
610
|
+
private readonly options;
|
|
611
|
+
private app;
|
|
612
|
+
private engine;
|
|
613
|
+
private disposed;
|
|
614
|
+
/** 用户应用已经成功 onSceneLoaded。 */
|
|
615
|
+
private scenePresented;
|
|
616
|
+
private tickAttached;
|
|
617
|
+
private sceneLoadTask;
|
|
618
|
+
private ctx;
|
|
619
|
+
private cleanups;
|
|
620
|
+
private sceneCleanups;
|
|
621
|
+
private warnedAsyncUpdate;
|
|
622
|
+
private userBlobUrl;
|
|
623
|
+
private currentSceneId;
|
|
624
|
+
private readonly onEngineTick;
|
|
625
|
+
constructor(options: TwinAppPreviewHostOptions);
|
|
626
|
+
getEngine(): TwinAppEngine | null;
|
|
627
|
+
/** 给 spec 调用:场景字段取当前引擎主场景(不要求已 Run TwinApp)。 */
|
|
628
|
+
getTestContext(): TwinAppContext;
|
|
629
|
+
invokeTest(fn: (ctx: TwinAppContext, input?: string) => unknown, input?: string): Promise<unknown>;
|
|
630
|
+
boot(): Promise<void>;
|
|
631
|
+
run(code: string): Promise<void>;
|
|
632
|
+
dispose(): Promise<void>;
|
|
633
|
+
private assertTickApi;
|
|
634
|
+
private importUser;
|
|
635
|
+
private loadCurrentScene;
|
|
636
|
+
private handleTick;
|
|
637
|
+
private handleUpdateError;
|
|
638
|
+
private failRun;
|
|
639
|
+
private attachTick;
|
|
640
|
+
private detachTick;
|
|
641
|
+
private teardownApp;
|
|
642
|
+
private unloadUserScene;
|
|
643
|
+
private runHooks;
|
|
644
|
+
private getContext;
|
|
289
645
|
}
|
|
290
|
-
|
|
646
|
+
|
|
647
|
+
type PreviewHostKind = "vscode" | "http";
|
|
291
648
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
649
|
+
* 纯函数:构造场景预览页 HTML(插件 webview 与 CLI localhost HTTP 共用,D28)。
|
|
650
|
+
* 单栏三维场景页:module script 动态 import twin runtime,
|
|
651
|
+
* 用场景数据经 convertObjToComponentJson + RuntimeEngine.create + loadScene 真实渲染。
|
|
652
|
+
* baseOSSUrl 必须是 ossUrl(缺省官方 OSS),不是 API baseUrl。
|
|
653
|
+
* host=vscode 且页面为 HTTPS 时,HTTP 资源经扩展宿主代理,规避 mixed content。
|
|
654
|
+
* host=http(CLI preview)时直连 API 与 OSS,走同源 `/api/*` 做 bundle/tests/assets。
|
|
655
|
+
* 底部 Run 走 TwinAppPreviewHost(D14):import map 注入 @easytwin/runtime 与 @easytwin/apps。
|
|
656
|
+
* 工作区 *.spec.ts 命名导出在 Run 栏上方列出(D27)。
|
|
294
657
|
*/
|
|
295
|
-
declare function
|
|
658
|
+
declare function escapeHtml(text: string): string;
|
|
659
|
+
/**
|
|
660
|
+
* 把 JSON 文本安全嵌入 `<script type="application/json">`。
|
|
661
|
+
* script 元素的内容是 raw text,HTML 实体不会解码,因此不能使用 escapeHtml;
|
|
662
|
+
* 只需把 `<`/`>` 与 U+2028/U+2029 转成 JSON 字面转义。
|
|
663
|
+
*/
|
|
664
|
+
declare function escapeJsonForScript(json: string): string;
|
|
665
|
+
/** 纯状态页:预览加载中 / 加载失败时的兜底内容,避免空白 webview。 */
|
|
666
|
+
declare function buildStatusHtml(message: string): string;
|
|
667
|
+
declare function buildPreviewHtml(options: {
|
|
668
|
+
baseUrl: string;
|
|
669
|
+
ossUrl: string;
|
|
670
|
+
sceneJson: string;
|
|
671
|
+
mock?: boolean;
|
|
672
|
+
runtimeUri: string;
|
|
673
|
+
appsUri?: string;
|
|
674
|
+
hostUri?: string;
|
|
675
|
+
appId?: string;
|
|
676
|
+
/** vscode=webview postMessage+混合内容代理;http=CLI 同源 /api/*。缺省 vscode。 */
|
|
677
|
+
host?: PreviewHostKind;
|
|
678
|
+
/** VSCode webview.cspSource;缺省回退 runtimeUri 的 origin(单测用)。 */
|
|
679
|
+
cspSource?: string;
|
|
680
|
+
tests?: WorkspaceTestCase[];
|
|
681
|
+
}): string;
|
|
296
682
|
|
|
297
|
-
export { APP_ID_HEADER, AUTH_HEADER,
|
|
683
|
+
export { APPS_DTS, APPS_MODULE, APPS_TYPES_FILE, APP_ID_HEADER, AUTH_HEADER, BundleError, type BundleResult, type BundleUserCodeOptions, type BundleWorkspaceModuleOptions, CODEX_MARKER_BEGIN, CODEX_MARKER_END, CONFIG_FILE_NAME, type CollectedFile, ConfigError, type ConfigScene, DEFAULT_BASE_URL, DEFAULT_BUNDLE_OUT, DEFAULT_ENTRY_PATH, DEFAULT_MAIN_TS, DEFAULT_OSS_URL, EASYTWIN_TYPES_DIR, ENDPOINTS, EXAMPLE_SCENE_FILE, EasyTwinApiError, EasyTwinClient, type EasyTwinConfig, type EasyTwinEnv, GITIGNORE_ENTRY, GITIGNORE_FILE_NAME, type GitignoreResult, type InitResult, LOCAL_LOAD_SCENE_ERROR, type LinkedScene, META_FILE_NAME, MINIMAL_TSCONFIG, MISSING_TICK_ERROR, MOCK_APP_ID, MOCK_APP_SECRET, MOCK_SCENE_NAME, PORTABLE_RUNTIME_EXPORTS, type PortableRuntimeExport, type PreviewHostKind, RUNTIME_MODULE, type RequestOptions, type ResolvedConfig, SKILL_NAMES, type SceneDetail, type SceneSummary, type SceneTreeNode, type SkillsStatus, type SkillsTargetStatus, type SyncAction, type SyncEntrySummary, type SyncOptions, type SyncSkillsResult, type SyncSummary, type SyncTarget, type SyncTargetArg, TEST_BASE_URL, TSCONFIG_PATHS_HINT, TwinApp, type TwinAppContext, type TwinAppEngine, TwinAppPreviewHost, type TwinAppPreviewHostOptions, type TwinAppRuntimeModule, type TwinAppRuntimeScene, type TwinAppSceneManager, type TwinAppTickListener, type TypesSyncSummary, USER_ENTRY, type UploadCreate, type UploadDelete, type UploadOptions, type UploadProgress, type UploadResult, type UploadUpdate, WORKSPACE_CODE_EXTENSIONS, WORKSPACE_IGNORED_DIRS, WORKSPACE_IGNORED_FILES, type WorkspaceChangeKind, type WorkspaceCodeConfig, type WorkspaceCodeFile, type WorkspaceFileChange, type WorkspacePullApplyResult, type WorkspacePullOptions, type WorkspacePullPlan, type WorkspacePullResult, type WorkspaceTestCase, type WorkspaceUploadPlan, appendGitignore, applyWorkspacePull, assertUploadable, buildMultipartBody, buildPreviewHtml, buildRuntimeTypesContent, buildStatusHtml, buildWorkspacePushBody, bundleUserCode, bundleWorkspaceModule, bundleWorkspaceTestFile, collectFiles, configFilePath, createAppInstance, defaultPullIgnore, defaultWorkspaceIgnore, defineApp, deriveExampleSceneId, detectSkillsStatus, directoryDepth, escapeHtml, escapeJsonForScript, exampleSceneSummary, extractInlineSourceMap, extractSceneArray, formatUploadResult, formatWorkspacePullPlan, formatWorkspacePullResult, initConfig, isIgnoredWorkspacePath, isMockCredentials, isSafeRelPath, isWorkspaceCodeFile, isWorkspaceSpecFile, listScenes, listWorkspaceTests, loadConfig, loadExampleScene, normalizeLinkedScenes, normalizePath, normalizeSceneList, normalizeTargets, normalizeWorkspaceConfig, normalizeWorkspaceFiles, parseConfig, parseExportedTestFunctions, parseSceneStructure, planWorkspacePull, planWorkspaceUpload, portableRuntimeWarning, pullScene, pullWorkspace, readConfigFile, readDevkitVersion, remapErrorStack, resolveConfig, resolveExampleScenePath, resolveRuntimeTypesSourceFile, resolveSkillsSourceDir, resolveSnapshotUrl, resolveWorkspaceAssetPath, saveSceneJson, syncSkills, toConfigScenes, typesMissingHint, uploadDirectory, validateConfigShape, workspacePullHasConflicts, workspacePullPendingWrites, workspaceTestId, writeConfigFile, writeConfigScenes };
|