@stalfh233/omc-fake-platform 0.4.76 → 0.4.78
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/dist/model.js +100 -4
- package/dist/state.d.ts +11 -0
- package/dist/state.js +4 -0
- package/package.json +2 -2
package/dist/model.js
CHANGED
|
@@ -20,10 +20,47 @@ export const modelRoute = (ctx, input) => {
|
|
|
20
20
|
// discover_environment with applicationCode returned no models. Consumers
|
|
21
21
|
// must flattenTreeRows (as resolveModelTreeNode already does); the fake
|
|
22
22
|
// must nest so a regression cannot pass.
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const folders = [...ctx.state.folders.values()].filter((folder) => appCode === undefined || folder.appCode === appCode);
|
|
24
|
+
// Every real application has at least one folder (the designer's default
|
|
25
|
+
// group). An app seeded without one still needs a resolvable folder or
|
|
26
|
+
// model.create could never run there — synthesize the default.
|
|
27
|
+
if (appCode !== undefined && !folders.some((folder) => folder.appCode === appCode))
|
|
28
|
+
folders.push({ id: `folder-${appCode}`, appCode, name: "General", code: "general" });
|
|
29
|
+
const models = [...ctx.state.models.values()].filter((model) => !model.treeHidden && (appCode === undefined || (model.appCode ?? "test") === appCode));
|
|
30
|
+
const ROOT = "folder-1";
|
|
31
|
+
const nodeOf = (folder) => ({
|
|
32
|
+
id: folder.id,
|
|
33
|
+
type: "Folder",
|
|
34
|
+
code: folder.code ?? null,
|
|
35
|
+
name: folder.name,
|
|
36
|
+
parentId: folder.parentId ?? ROOT,
|
|
37
|
+
children: [],
|
|
38
|
+
});
|
|
39
|
+
const nodes = new Map();
|
|
40
|
+
for (const folder of folders)
|
|
41
|
+
nodes.set(folder.id, nodeOf(folder));
|
|
42
|
+
const rootChildren = [];
|
|
43
|
+
for (const folder of folders) {
|
|
44
|
+
const node = nodes.get(folder.id);
|
|
45
|
+
const parent = folder.parentId ? nodes.get(folder.parentId) : undefined;
|
|
46
|
+
if (parent)
|
|
47
|
+
parent.children.push(node);
|
|
48
|
+
else
|
|
49
|
+
rootChildren.push(node);
|
|
50
|
+
}
|
|
51
|
+
for (const model of models) {
|
|
52
|
+
const node = { id: model.id, type: "BizModel", code: model.code, name: model.nodeName ?? model.name, parentId: model.parentId ?? ROOT };
|
|
53
|
+
const parent = model.parentId ? nodes.get(model.parentId) : undefined;
|
|
54
|
+
if (parent)
|
|
55
|
+
parent.children.push(node);
|
|
56
|
+
else
|
|
57
|
+
rootChildren.push(node);
|
|
58
|
+
}
|
|
59
|
+
// Live 1.1.25 fidelity (2026-10-23, folder.tree readback): the tree
|
|
60
|
+
// returns the TOP-LEVEL folders directly — no synthetic app-package
|
|
61
|
+
// container row. The fake must match, or a depth-0 assertion would pass
|
|
62
|
+
// against a shape the platform never returns.
|
|
63
|
+
return rootChildren;
|
|
27
64
|
}
|
|
28
65
|
case "/api/api/app/bizmodels/list_schema":
|
|
29
66
|
return [...ctx.state.models.values()].map((model) => ({ id: model.recordId, schemaCode: model.code, name: model.name }));
|
|
@@ -36,6 +73,7 @@ export const modelRoute = (ctx, input) => {
|
|
|
36
73
|
code,
|
|
37
74
|
name: String(body.name ?? code),
|
|
38
75
|
appCode: String(body.applicationCode ?? body.appCode ?? "test"),
|
|
76
|
+
...(body.folderId !== undefined && body.folderId !== null && String(body.folderId) !== "" ? { parentId: String(body.folderId) } : {}),
|
|
39
77
|
});
|
|
40
78
|
// Live fidelity (ticket 42): bizmodels/create seeds NO form — the model
|
|
41
79
|
// has no h_biz_sheet row until the form is created (bizsheet/create, or
|
|
@@ -105,6 +143,61 @@ export const modelRoute = (ctx, input) => {
|
|
|
105
143
|
const model = ctx.state.models.get(q.schemaCode);
|
|
106
144
|
return model ? { id: model.recordId, name: model.name, modelType: "LIST" } : null;
|
|
107
145
|
}
|
|
146
|
+
case "/api/api/app/folders/create": {
|
|
147
|
+
const appCode = String(body.appCode ?? "");
|
|
148
|
+
if (!appCode)
|
|
149
|
+
return businessRefusal(10005, "应用编码不能为空");
|
|
150
|
+
const name = String(body.name ?? "");
|
|
151
|
+
if (!name)
|
|
152
|
+
return businessRefusal(10005, "名称不能为空");
|
|
153
|
+
const parentId = body.parentId === undefined || body.parentId === null || String(body.parentId) === "" ? "folder-1" : String(body.parentId);
|
|
154
|
+
if (parentId !== "folder-1" && !ctx.state.folders.has(parentId))
|
|
155
|
+
return businessRefusal(10005, `目录不存在: ${parentId}`);
|
|
156
|
+
const id = `folder-${ctx.state.folders.size + 2}`;
|
|
157
|
+
ctx.state.folders.set(id, {
|
|
158
|
+
id,
|
|
159
|
+
appCode,
|
|
160
|
+
name,
|
|
161
|
+
...(typeof body.name_i18n === "string" ? { name_i18n: body.name_i18n } : {}),
|
|
162
|
+
...(typeof body.code === "string" ? { code: body.code } : {}),
|
|
163
|
+
...(parentId !== "folder-1" ? { parentId } : {}),
|
|
164
|
+
});
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
case "/api/api/app/folders/get": {
|
|
168
|
+
const folder = ctx.state.folders.get(String(q.folderId ?? ""));
|
|
169
|
+
if (!folder)
|
|
170
|
+
return businessRefusal(10005, "目录不存在");
|
|
171
|
+
return { ...folder, type: "Folder" };
|
|
172
|
+
}
|
|
173
|
+
case "/api/api/app/folders/update": {
|
|
174
|
+
const folder = ctx.state.folders.get(String(body.id ?? ""));
|
|
175
|
+
if (!folder)
|
|
176
|
+
return businessRefusal(10005, "目录不存在");
|
|
177
|
+
const parentId = body.parentId === undefined || body.parentId === null ? "" : String(body.parentId);
|
|
178
|
+
if (parentId !== "" && parentId === folder.id)
|
|
179
|
+
return businessRefusal(10005, "上级不能选择自己");
|
|
180
|
+
if (parentId !== "" && parentId !== "folder-1" && !ctx.state.folders.has(parentId))
|
|
181
|
+
return businessRefusal(10005, `目录不存在: ${parentId}`);
|
|
182
|
+
ctx.state.folders.set(folder.id, {
|
|
183
|
+
...folder,
|
|
184
|
+
...(body.name !== undefined ? { name: String(body.name) } : {}),
|
|
185
|
+
...(typeof body.name_i18n === "string" ? { name_i18n: body.name_i18n } : {}),
|
|
186
|
+
...(parentId !== "" ? { parentId: parentId === "folder-1" ? undefined : parentId } : {}),
|
|
187
|
+
});
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
case "/api/api/app/folders/delete": {
|
|
191
|
+
const folderId = String(q.folderId ?? "");
|
|
192
|
+
if (!ctx.state.folders.has(folderId))
|
|
193
|
+
return businessRefusal(10005, "目录不存在");
|
|
194
|
+
const hasChildFolder = [...ctx.state.folders.values()].some((folder) => folder.parentId === folderId);
|
|
195
|
+
const hasChildModel = [...ctx.state.models.values()].some((model) => model.parentId === folderId);
|
|
196
|
+
if (hasChildFolder || hasChildModel)
|
|
197
|
+
return businessRefusal(10005, "目录不为空,无法删除");
|
|
198
|
+
ctx.state.folders.delete(folderId);
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
108
201
|
case "/api/api/app/bizmodels/update": {
|
|
109
202
|
// Ticket 83 (source-pinned BizSchemaController.update :266-305): the
|
|
110
203
|
// endpoint patches the AppFunction MENU NODE — bizSchemaCode, id, name,
|
|
@@ -126,7 +219,10 @@ export const modelRoute = (ctx, input) => {
|
|
|
126
219
|
return businessRefusal(10005, "父id不可为空");
|
|
127
220
|
if (nodeId !== model.id)
|
|
128
221
|
return businessRefusal(10005, `id不是模型 ${schemaCode} 的应用树节点`);
|
|
222
|
+
if (parentId !== (model.parentId ?? "folder-1") && !ctx.state.folders.has(parentId) && parentId !== "folder-1")
|
|
223
|
+
return businessRefusal(10005, `目录不存在: ${parentId}`);
|
|
129
224
|
model.nodeName = name;
|
|
225
|
+
model.parentId = parentId;
|
|
130
226
|
return null;
|
|
131
227
|
}
|
|
132
228
|
default:
|
package/dist/state.d.ts
CHANGED
|
@@ -277,6 +277,15 @@ export interface FakeCallLogEntry {
|
|
|
277
277
|
bytes: number;
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
|
+
/** App-tree folder node (h_app_function type=Folder) — issue 2026-10-23. */
|
|
281
|
+
export interface FakeFolder {
|
|
282
|
+
id: string;
|
|
283
|
+
appCode: string;
|
|
284
|
+
name: string;
|
|
285
|
+
name_i18n?: string;
|
|
286
|
+
code?: string;
|
|
287
|
+
parentId?: string;
|
|
288
|
+
}
|
|
280
289
|
export interface FakeState {
|
|
281
290
|
fields: Map<string, FakeField>;
|
|
282
291
|
dictionaries: Map<string, FakeDictionary>;
|
|
@@ -289,6 +298,7 @@ export interface FakeState {
|
|
|
289
298
|
sheets: Map<string, FakeSheet>;
|
|
290
299
|
rules: Map<string, FakeRule>;
|
|
291
300
|
buttons: Map<string, FakeButton>;
|
|
301
|
+
folders: Map<string, FakeFolder>;
|
|
292
302
|
/** Schema codes for which bizproperty/list answers 601003 (see field.ts). */
|
|
293
303
|
fieldListUnavailable: Set<string>;
|
|
294
304
|
/**
|
|
@@ -406,6 +416,7 @@ export interface FakeState {
|
|
|
406
416
|
appCode?: string;
|
|
407
417
|
treeHidden?: boolean;
|
|
408
418
|
nodeName?: string;
|
|
419
|
+
parentId?: string;
|
|
409
420
|
}>;
|
|
410
421
|
apps: Map<string, FakeApp>;
|
|
411
422
|
appGroups: Map<string, FakeAppGroup>;
|
package/dist/state.js
CHANGED
|
@@ -34,6 +34,10 @@ export function createFakeState(options = {}) {
|
|
|
34
34
|
sheets: new Map(),
|
|
35
35
|
rules: new Map(),
|
|
36
36
|
buttons: new Map(),
|
|
37
|
+
// model.create resolves the first Folder in the tree when no folderId is
|
|
38
|
+
// given; this row is that default. Its parent is the app package (implicit
|
|
39
|
+
// root), so it is a top-level tree node.
|
|
40
|
+
folders: new Map([["folder-1", { id: "folder-1", appCode: "test", name: "General", code: "general" }]]),
|
|
37
41
|
fieldListUnavailable: new Set(),
|
|
38
42
|
ruleHistory: [],
|
|
39
43
|
ruleSeq: 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stalfh233/omc-fake-platform",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.78",
|
|
4
4
|
"description": "OMC 的内存假 CloudPivot 平台(wire 接缝的第二个适配器)+ HTTP 假服务器——@stalfh233/omc-cli 的测试与 bench 基准基座",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "tsc --project tsconfig.build.json"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"omc-core": "0.4.
|
|
21
|
+
"omc-core": "0.4.78"
|
|
22
22
|
},
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=22.13"
|