@lingfan-engine/editor 0.1.0 → 0.1.2

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.
@@ -1,374 +1,374 @@
1
- /**
2
- * op 负载 schema 全集:每条命令一个 `z.strictObject`,`.strict()` 拒绝未知字段
3
- * (编辑期 fail-closed)。字段面以执行器为权威(packages/core/src/runtime/ops/)。
4
- */
5
- import { z } from "zod";
6
- import { isValidSayColor } from "@lingfan-engine/core";
7
- import {
8
- Body,
9
- Fade,
10
- Finite,
11
- InstanceZ,
12
- NonEmpty,
13
- SlotName,
14
- StateValue,
15
- Value,
16
- } from "./fragments.ts";
17
-
18
- const saySchema = z.strictObject({
19
- text: NonEmpty,
20
- speaker: z.string().optional(),
21
- /**
22
- * 说话人颜色覆盖(覆盖整句/说话人)。
23
- *
24
- * **判据直接复用引擎的 `isValidSayColor`**(不在此重写正则)——
25
- * 两处各写一份判据 ⇒ 必然漂移——
26
- * 判据只此一份,投影/校验读同一份。
27
- * 与**行内标记** `{color=…}`(写在文本内部)是两件事。
28
- */
29
- color: z
30
- .string()
31
- .refine(isValidSayColor, {
32
- message: "必须为十六进制颜色(如 #FFD700 / #888 / #FFD700CC)",
33
- })
34
- .optional(),
35
- /**
36
- * 本句字体(字体名 = Resources/Fonts 文件名去扩展名)。
37
- * 名字是否在注册表内不在此校验(schema 看不见资源目录)——构建期 fail-closed +
38
- * 运行期渲染闸门回退负责,这里只收非空字符串。
39
- */
40
- font: NonEmpty.optional(),
41
- clickable: z.boolean().optional(),
42
- noskip: z.boolean().optional(),
43
- instant: z.boolean().optional(),
44
- typewriter: z.number().optional(),
45
- voice: NonEmpty.optional(),
46
- template: NonEmpty.optional(),
47
- z: InstanceZ, // dialogue 层实例 z
48
- });
49
-
50
- const menuSchema = z.strictObject({
51
- prompt: z.string().optional(),
52
- options: z.array(z.strictObject({ text: NonEmpty, target: NonEmpty })).min(1),
53
- z: InstanceZ, // choices 层实例 z
54
- });
55
-
56
- const inputSchema = z.strictObject({
57
- prompt: NonEmpty,
58
- store: NonEmpty,
59
- z: InstanceZ, // choices 层实例 z
60
- });
61
-
62
- const notifySchema = z.strictObject({
63
- text: NonEmpty,
64
- type: z.string().optional(),
65
- duration: z.number().optional(),
66
- z: InstanceZ, // notifications 层实例 z
67
- });
68
-
69
- const nvlSchema = z.strictObject({
70
- mode: z.enum(["enter", "auto", "clear", "exit"]).optional(),
71
- });
72
-
73
- const characterSchema = z.strictObject({
74
- key: NonEmpty,
75
- name: z.string().optional(),
76
- color: z.string().optional(),
77
- size: z.string().optional(),
78
- font: z.string().optional(),
79
- textColor: z.string().optional(),
80
- screen: NonEmpty.optional(),
81
- });
82
-
83
- const uncharacterSchema = z.strictObject({ key: NonEmpty });
84
-
85
- const waitSchema = z.strictObject({
86
- seconds: z.number(),
87
- skipable: z.boolean().optional(),
88
- });
89
-
90
- const pauseSchema = z.strictObject({
91
- seconds: z.number(),
92
- });
93
-
94
- const randomSchema = z.strictObject({
95
- seed: z.number().int(),
96
- range: z.tuple([z.number(), z.number()]),
97
- var: NonEmpty,
98
- });
99
-
100
- const jumpSchema = z.strictObject({
101
- target: NonEmpty,
102
- });
103
-
104
- const navigateSchema = z.strictObject({
105
- path: NonEmpty,
106
- scene: NonEmpty.optional(),
107
- });
108
-
109
- /** `call`:target 必填;`into` 为结果绑定名(ret 带值返回时声明成调用方局部变量,无带值 ret 则绑 `null`) */
110
- const callSchema = z.strictObject({
111
- target: NonEmpty,
112
- args: z.array(Value).optional(),
113
- into: NonEmpty.optional(),
114
- });
115
-
116
- const returnSchema = z.strictObject({
117
- value: Value.optional(),
118
- });
119
- /** 函数定义:name/params/body 三者引擎均必填(`data/format/validate/blocks.ts` `case "func"`) */
120
- const funcSchema = z.strictObject({
121
- name: NonEmpty,
122
- params: z.array(NonEmpty),
123
- body: Body,
124
- });
125
-
126
- const ifSchema = z.strictObject({
127
- cond: NonEmpty,
128
- then: Body,
129
- elif: z.array(z.strictObject({ cond: NonEmpty, then: Body })).optional(),
130
- else: Body.optional(),
131
- });
132
-
133
- const whileSchema = z.strictObject({
134
- cond: NonEmpty,
135
- body: Body,
136
- });
137
-
138
- const assertSchema = z.strictObject({
139
- cond: NonEmpty,
140
- message: z.string().optional(),
141
- });
142
-
143
- const guardSchema = z.strictObject({
144
- fn: NonEmpty,
145
- /**
146
- * 原样**运输**的宿主参数:嵌套 JSON 合法(同 `minigame.config` 口径;运行期
147
- * `findJsonValueError` 兜底 JSON 安全)。值口径原则:**被求值的走 `Value`
148
- * (call args / reward / set),被运输的走 JSON**(guard args / minigame config)。
149
- */
150
- args: z.record(z.string(), z.unknown()).optional(),
151
- });
152
-
153
- const forSchema = z.strictObject({
154
- var: NonEmpty,
155
- in: NonEmpty,
156
- body: Body,
157
- });
158
-
159
- const foreachSchema = z.strictObject({
160
- var: NonEmpty,
161
- key: NonEmpty,
162
- body: Body,
163
- });
164
-
165
- const switchSchema = z.strictObject({
166
- on: NonEmpty,
167
- cases: z.array(z.strictObject({ value: Value, body: Body })).min(1),
168
- default: Body.optional(),
169
- });
170
-
171
- const emptySchema = z.strictObject({});
172
-
173
- const assignSchema = z.strictObject({ key: NonEmpty, value: StateValue });
174
-
175
- const undefSchema = z.strictObject({ key: NonEmpty });
176
-
177
- const arraySchema = z.strictObject({
178
- key: NonEmpty,
179
- items: z.array(StateValue),
180
- once: z.boolean().optional(),
181
- });
182
-
183
- const arrayPushSchema = z.strictObject({ key: NonEmpty, value: StateValue });
184
-
185
- const arrayPopSchema = z.strictObject({ key: NonEmpty });
186
-
187
- const dictSchema = z.strictObject({
188
- key: NonEmpty,
189
- value: z.record(z.string(), StateValue),
190
- once: z.boolean().optional(),
191
- });
192
-
193
- const dictSetSchema = z.strictObject({
194
- key: NonEmpty,
195
- field: NonEmpty,
196
- value: StateValue,
197
- });
198
-
199
- const saveSchema = z.strictObject({
200
- slot: SlotName,
201
- title: z.string().optional(),
202
- });
203
-
204
- const loadSchema = z.strictObject({ slot: NonEmpty });
205
-
206
- const autoSaveSchema = z.strictObject({
207
- enabled: z.boolean(),
208
- });
209
-
210
- const saveDeleteSchema = z.strictObject({ slot: SlotName });
211
-
212
- const playFields = {
213
- resource: NonEmpty,
214
- volume: Finite.optional(),
215
- };
216
- const bgmSchema = z.strictObject({
217
- ...playFields,
218
- loop: z.boolean().optional(),
219
- fade: Fade.optional(),
220
- restart: z.boolean().optional(),
221
- });
222
- const seSchema = z.strictObject({ ...playFields });
223
- const voiceSchema = z.strictObject({
224
- ...playFields,
225
- auto_stop: z.boolean().optional(),
226
- restart: z.boolean().optional(),
227
- });
228
- const stopSchema = z.strictObject({ fade: Fade.optional() });
229
-
230
- const videoSchema = z.strictObject({
231
- ...playFields,
232
- loop: z.boolean().optional(),
233
- z: InstanceZ, // video 层实例 z
234
- });
235
- const cutsceneSchema = z.strictObject({
236
- ...playFields,
237
- skipable: z.boolean().optional(),
238
- z: InstanceZ, // video 层实例 z
239
- });
240
- const seekVideoSchema = z.strictObject({
241
- seconds: z.number().finite().min(0),
242
- });
243
- const videoSkipableSchema = z.strictObject({ value: z.boolean() });
244
-
245
- /** minigame:config 原样透传 UI(任意 JSON);reward 键值数组(value 执行期求值 → 标量/{expr}) */
246
- const minigameSchema = z.strictObject({
247
- game: NonEmpty,
248
- config: z.record(z.string(), z.unknown()).optional(),
249
- on_success: NonEmpty.optional(),
250
- on_fail: NonEmpty.optional(),
251
- reward: z.array(z.strictObject({ key: NonEmpty, value: Value })).optional(),
252
- z: InstanceZ, // minigame 层实例 z
253
- });
254
-
255
- /** 外部玩法系统接管(与 minigame 同形;无 reward——那是小游戏专属语义) */
256
- const interactionSchema = z.strictObject({
257
- system: NonEmpty,
258
- config: z.record(z.string(), z.unknown()).optional(),
259
- on_success: NonEmpty.optional(),
260
- on_fail: NonEmpty.optional(),
261
- z: InstanceZ, // 与 minigame 同层(外部系统整屏接管)
262
- });
263
-
264
- // ====== 元素系统(元素增删改 + 表现类)======
265
- // 字段面以执行器为权威(runtime/ops/element/visual.ts 的 ELEMENT_OP_FIELDS);x/y 允许数字或 CSS 长度串。
266
-
267
- /** 元素增删改(`show` / `hide` / `background` / `bg_switch` / `zindex` / `style` / `window`) */
268
- const showSchema = z.strictObject({
269
- target: NonEmpty,
270
- x: z.union([Finite, z.string()]).optional(),
271
- y: z.union([Finite, z.string()]).optional(),
272
- id: NonEmpty.optional(),
273
- name: NonEmpty.optional(),
274
- background: z.boolean().optional(),
275
- });
276
- const hideSchema = z.strictObject({ target: NonEmpty });
277
- const backgroundSchema = z.strictObject({ resource: NonEmpty });
278
- const bgSwitchSchema = z.strictObject({ resource: NonEmpty });
279
- const zindexSchema = z.strictObject({ target: NonEmpty, value: Finite });
280
- const styleSchema = z.strictObject({
281
- target: NonEmpty,
282
- props: z.record(z.string(), Value),
283
- });
284
- const windowSchema = z.strictObject({ mode: z.enum(["auto", "show", "hide"]) });
285
-
286
- /** 帧驱动表现类(`animate` / `animate_block` / `transition` / `shake` / `text_typewriter`) */
287
- const animateSchema = z.strictObject({
288
- target: NonEmpty,
289
- property: NonEmpty,
290
- value: Finite,
291
- duration: Fade.optional(),
292
- easing: NonEmpty.optional(),
293
- });
294
- const animateBlockSchema = z.strictObject({
295
- target: NonEmpty,
296
- x: Finite.optional(),
297
- y: Finite.optional(),
298
- opacity: Finite.optional(),
299
- rotation: Finite.optional(),
300
- scale: Finite.optional(),
301
- duration: Fade.optional(),
302
- easing: NonEmpty.optional(),
303
- });
304
- const transitionSchema = z.strictObject({
305
- type: NonEmpty,
306
- duration: Fade.optional(),
307
- });
308
- const shakeSchema = z.strictObject({
309
- intensity: Finite.optional(),
310
- duration: Fade.optional(),
311
- });
312
- const textTypewriterSchema = z.strictObject({
313
- enabled: z.boolean().optional(),
314
- speed: z.number().finite().positive().optional(),
315
- });
316
-
317
- export {
318
- saySchema,
319
- menuSchema,
320
- inputSchema,
321
- notifySchema,
322
- nvlSchema,
323
- characterSchema,
324
- uncharacterSchema,
325
- waitSchema,
326
- pauseSchema,
327
- randomSchema,
328
- jumpSchema,
329
- navigateSchema,
330
- callSchema,
331
- returnSchema,
332
- funcSchema,
333
- ifSchema,
334
- whileSchema,
335
- assertSchema,
336
- guardSchema,
337
- forSchema,
338
- foreachSchema,
339
- switchSchema,
340
- emptySchema,
341
- assignSchema,
342
- undefSchema,
343
- arraySchema,
344
- arrayPushSchema,
345
- arrayPopSchema,
346
- dictSchema,
347
- dictSetSchema,
348
- saveSchema,
349
- loadSchema,
350
- autoSaveSchema,
351
- saveDeleteSchema,
352
- bgmSchema,
353
- seSchema,
354
- voiceSchema,
355
- stopSchema,
356
- videoSchema,
357
- cutsceneSchema,
358
- seekVideoSchema,
359
- videoSkipableSchema,
360
- minigameSchema,
361
- interactionSchema,
362
- showSchema,
363
- hideSchema,
364
- backgroundSchema,
365
- bgSwitchSchema,
366
- zindexSchema,
367
- styleSchema,
368
- windowSchema,
369
- animateSchema,
370
- animateBlockSchema,
371
- transitionSchema,
372
- shakeSchema,
373
- textTypewriterSchema,
374
- };
1
+ /**
2
+ * op 负载 schema 全集:每条命令一个 `z.strictObject`,`.strict()` 拒绝未知字段
3
+ * (编辑期 fail-closed)。字段面以执行器为权威(packages/core/src/runtime/ops/)。
4
+ */
5
+ import { z } from "zod";
6
+ import { isValidSayColor } from "@lingfan-engine/core";
7
+ import {
8
+ Body,
9
+ Fade,
10
+ Finite,
11
+ InstanceZ,
12
+ NonEmpty,
13
+ SlotName,
14
+ StateValue,
15
+ Value,
16
+ } from "./fragments.ts";
17
+
18
+ const saySchema = z.strictObject({
19
+ text: NonEmpty,
20
+ speaker: z.string().optional(),
21
+ /**
22
+ * 说话人颜色覆盖(覆盖整句/说话人)。
23
+ *
24
+ * **判据直接复用引擎的 `isValidSayColor`**(不在此重写正则)——
25
+ * 两处各写一份判据 ⇒ 必然漂移——
26
+ * 判据只此一份,投影/校验读同一份。
27
+ * 与**行内标记** `{color=…}`(写在文本内部)是两件事。
28
+ */
29
+ color: z
30
+ .string()
31
+ .refine(isValidSayColor, {
32
+ message: "必须为十六进制颜色(如 #FFD700 / #888 / #FFD700CC)",
33
+ })
34
+ .optional(),
35
+ /**
36
+ * 本句字体(字体名 = Resources/Fonts 文件名去扩展名)。
37
+ * 名字是否在注册表内不在此校验(schema 看不见资源目录)——构建期 fail-closed +
38
+ * 运行期渲染闸门回退负责,这里只收非空字符串。
39
+ */
40
+ font: NonEmpty.optional(),
41
+ clickable: z.boolean().optional(),
42
+ noskip: z.boolean().optional(),
43
+ instant: z.boolean().optional(),
44
+ typewriter: z.number().optional(),
45
+ voice: NonEmpty.optional(),
46
+ template: NonEmpty.optional(),
47
+ z: InstanceZ, // dialogue 层实例 z
48
+ });
49
+
50
+ const menuSchema = z.strictObject({
51
+ prompt: z.string().optional(),
52
+ options: z.array(z.strictObject({ text: NonEmpty, target: NonEmpty })).min(1),
53
+ z: InstanceZ, // choices 层实例 z
54
+ });
55
+
56
+ const inputSchema = z.strictObject({
57
+ prompt: NonEmpty,
58
+ store: NonEmpty,
59
+ z: InstanceZ, // choices 层实例 z
60
+ });
61
+
62
+ const notifySchema = z.strictObject({
63
+ text: NonEmpty,
64
+ type: z.string().optional(),
65
+ duration: z.number().optional(),
66
+ z: InstanceZ, // notifications 层实例 z
67
+ });
68
+
69
+ const nvlSchema = z.strictObject({
70
+ mode: z.enum(["enter", "auto", "clear", "exit"]).optional(),
71
+ });
72
+
73
+ const characterSchema = z.strictObject({
74
+ key: NonEmpty,
75
+ name: z.string().optional(),
76
+ color: z.string().optional(),
77
+ size: z.string().optional(),
78
+ font: z.string().optional(),
79
+ textColor: z.string().optional(),
80
+ screen: NonEmpty.optional(),
81
+ });
82
+
83
+ const uncharacterSchema = z.strictObject({ key: NonEmpty });
84
+
85
+ const waitSchema = z.strictObject({
86
+ seconds: z.number(),
87
+ skipable: z.boolean().optional(),
88
+ });
89
+
90
+ const pauseSchema = z.strictObject({
91
+ seconds: z.number(),
92
+ });
93
+
94
+ const randomSchema = z.strictObject({
95
+ seed: z.number().int(),
96
+ range: z.tuple([z.number(), z.number()]),
97
+ var: NonEmpty,
98
+ });
99
+
100
+ const jumpSchema = z.strictObject({
101
+ target: NonEmpty,
102
+ });
103
+
104
+ const navigateSchema = z.strictObject({
105
+ path: NonEmpty,
106
+ scene: NonEmpty.optional(),
107
+ });
108
+
109
+ /** `call`:target 必填;`into` 为结果绑定名(ret 带值返回时声明成调用方局部变量,无带值 ret 则绑 `null`) */
110
+ const callSchema = z.strictObject({
111
+ target: NonEmpty,
112
+ args: z.array(Value).optional(),
113
+ into: NonEmpty.optional(),
114
+ });
115
+
116
+ const returnSchema = z.strictObject({
117
+ value: Value.optional(),
118
+ });
119
+ /** 函数定义:name/params/body 三者引擎均必填(`data/format/validate/blocks.ts` `case "func"`) */
120
+ const funcSchema = z.strictObject({
121
+ name: NonEmpty,
122
+ params: z.array(NonEmpty),
123
+ body: Body,
124
+ });
125
+
126
+ const ifSchema = z.strictObject({
127
+ cond: NonEmpty,
128
+ then: Body,
129
+ elif: z.array(z.strictObject({ cond: NonEmpty, then: Body })).optional(),
130
+ else: Body.optional(),
131
+ });
132
+
133
+ const whileSchema = z.strictObject({
134
+ cond: NonEmpty,
135
+ body: Body,
136
+ });
137
+
138
+ const assertSchema = z.strictObject({
139
+ cond: NonEmpty,
140
+ message: z.string().optional(),
141
+ });
142
+
143
+ const guardSchema = z.strictObject({
144
+ fn: NonEmpty,
145
+ /**
146
+ * 原样**运输**的宿主参数:嵌套 JSON 合法(同 `minigame.config` 口径;运行期
147
+ * `findJsonValueError` 兜底 JSON 安全)。值口径原则:**被求值的走 `Value`
148
+ * (call args / reward / set),被运输的走 JSON**(guard args / minigame config)。
149
+ */
150
+ args: z.record(z.string(), z.unknown()).optional(),
151
+ });
152
+
153
+ const forSchema = z.strictObject({
154
+ var: NonEmpty,
155
+ in: NonEmpty,
156
+ body: Body,
157
+ });
158
+
159
+ const foreachSchema = z.strictObject({
160
+ var: NonEmpty,
161
+ key: NonEmpty,
162
+ body: Body,
163
+ });
164
+
165
+ const switchSchema = z.strictObject({
166
+ on: NonEmpty,
167
+ cases: z.array(z.strictObject({ value: Value, body: Body })).min(1),
168
+ default: Body.optional(),
169
+ });
170
+
171
+ const emptySchema = z.strictObject({});
172
+
173
+ const assignSchema = z.strictObject({ key: NonEmpty, value: StateValue });
174
+
175
+ const undefSchema = z.strictObject({ key: NonEmpty });
176
+
177
+ const arraySchema = z.strictObject({
178
+ key: NonEmpty,
179
+ items: z.array(StateValue),
180
+ once: z.boolean().optional(),
181
+ });
182
+
183
+ const arrayPushSchema = z.strictObject({ key: NonEmpty, value: StateValue });
184
+
185
+ const arrayPopSchema = z.strictObject({ key: NonEmpty });
186
+
187
+ const dictSchema = z.strictObject({
188
+ key: NonEmpty,
189
+ value: z.record(z.string(), StateValue),
190
+ once: z.boolean().optional(),
191
+ });
192
+
193
+ const dictSetSchema = z.strictObject({
194
+ key: NonEmpty,
195
+ field: NonEmpty,
196
+ value: StateValue,
197
+ });
198
+
199
+ const saveSchema = z.strictObject({
200
+ slot: SlotName,
201
+ title: z.string().optional(),
202
+ });
203
+
204
+ const loadSchema = z.strictObject({ slot: NonEmpty });
205
+
206
+ const autoSaveSchema = z.strictObject({
207
+ enabled: z.boolean(),
208
+ });
209
+
210
+ const saveDeleteSchema = z.strictObject({ slot: SlotName });
211
+
212
+ const playFields = {
213
+ resource: NonEmpty,
214
+ volume: Finite.optional(),
215
+ };
216
+ const bgmSchema = z.strictObject({
217
+ ...playFields,
218
+ loop: z.boolean().optional(),
219
+ fade: Fade.optional(),
220
+ restart: z.boolean().optional(),
221
+ });
222
+ const seSchema = z.strictObject({ ...playFields });
223
+ const voiceSchema = z.strictObject({
224
+ ...playFields,
225
+ auto_stop: z.boolean().optional(),
226
+ restart: z.boolean().optional(),
227
+ });
228
+ const stopSchema = z.strictObject({ fade: Fade.optional() });
229
+
230
+ const videoSchema = z.strictObject({
231
+ ...playFields,
232
+ loop: z.boolean().optional(),
233
+ z: InstanceZ, // video 层实例 z
234
+ });
235
+ const cutsceneSchema = z.strictObject({
236
+ ...playFields,
237
+ skipable: z.boolean().optional(),
238
+ z: InstanceZ, // video 层实例 z
239
+ });
240
+ const seekVideoSchema = z.strictObject({
241
+ seconds: z.number().finite().min(0),
242
+ });
243
+ const videoSkipableSchema = z.strictObject({ value: z.boolean() });
244
+
245
+ /** minigame:config 原样透传 UI(任意 JSON);reward 键值数组(value 执行期求值 → 标量/{expr}) */
246
+ const minigameSchema = z.strictObject({
247
+ game: NonEmpty,
248
+ config: z.record(z.string(), z.unknown()).optional(),
249
+ on_success: NonEmpty.optional(),
250
+ on_fail: NonEmpty.optional(),
251
+ reward: z.array(z.strictObject({ key: NonEmpty, value: Value })).optional(),
252
+ z: InstanceZ, // minigame 层实例 z
253
+ });
254
+
255
+ /** 外部玩法系统接管(与 minigame 同形;无 reward——那是小游戏专属语义) */
256
+ const interactionSchema = z.strictObject({
257
+ system: NonEmpty,
258
+ config: z.record(z.string(), z.unknown()).optional(),
259
+ on_success: NonEmpty.optional(),
260
+ on_fail: NonEmpty.optional(),
261
+ z: InstanceZ, // 与 minigame 同层(外部系统整屏接管)
262
+ });
263
+
264
+ // ====== 元素系统(元素增删改 + 表现类)======
265
+ // 字段面以执行器为权威(runtime/ops/element/visual.ts 的 ELEMENT_OP_FIELDS);x/y 允许数字或 CSS 长度串。
266
+
267
+ /** 元素增删改(`show` / `hide` / `background` / `bg_switch` / `zindex` / `style` / `window`) */
268
+ const showSchema = z.strictObject({
269
+ target: NonEmpty,
270
+ x: z.union([Finite, z.string()]).optional(),
271
+ y: z.union([Finite, z.string()]).optional(),
272
+ id: NonEmpty.optional(),
273
+ name: NonEmpty.optional(),
274
+ background: z.boolean().optional(),
275
+ });
276
+ const hideSchema = z.strictObject({ target: NonEmpty });
277
+ const backgroundSchema = z.strictObject({ resource: NonEmpty });
278
+ const bgSwitchSchema = z.strictObject({ resource: NonEmpty });
279
+ const zindexSchema = z.strictObject({ target: NonEmpty, value: Finite });
280
+ const styleSchema = z.strictObject({
281
+ target: NonEmpty,
282
+ props: z.record(z.string(), Value),
283
+ });
284
+ const windowSchema = z.strictObject({ mode: z.enum(["auto", "show", "hide"]) });
285
+
286
+ /** 帧驱动表现类(`animate` / `animate_block` / `transition` / `shake` / `text_typewriter`) */
287
+ const animateSchema = z.strictObject({
288
+ target: NonEmpty,
289
+ property: NonEmpty,
290
+ value: Finite,
291
+ duration: Fade.optional(),
292
+ easing: NonEmpty.optional(),
293
+ });
294
+ const animateBlockSchema = z.strictObject({
295
+ target: NonEmpty,
296
+ x: Finite.optional(),
297
+ y: Finite.optional(),
298
+ opacity: Finite.optional(),
299
+ rotation: Finite.optional(),
300
+ scale: Finite.optional(),
301
+ duration: Fade.optional(),
302
+ easing: NonEmpty.optional(),
303
+ });
304
+ const transitionSchema = z.strictObject({
305
+ type: NonEmpty,
306
+ duration: Fade.optional(),
307
+ });
308
+ const shakeSchema = z.strictObject({
309
+ intensity: Finite.optional(),
310
+ duration: Fade.optional(),
311
+ });
312
+ const textTypewriterSchema = z.strictObject({
313
+ enabled: z.boolean().optional(),
314
+ speed: z.number().finite().positive().optional(),
315
+ });
316
+
317
+ export {
318
+ saySchema,
319
+ menuSchema,
320
+ inputSchema,
321
+ notifySchema,
322
+ nvlSchema,
323
+ characterSchema,
324
+ uncharacterSchema,
325
+ waitSchema,
326
+ pauseSchema,
327
+ randomSchema,
328
+ jumpSchema,
329
+ navigateSchema,
330
+ callSchema,
331
+ returnSchema,
332
+ funcSchema,
333
+ ifSchema,
334
+ whileSchema,
335
+ assertSchema,
336
+ guardSchema,
337
+ forSchema,
338
+ foreachSchema,
339
+ switchSchema,
340
+ emptySchema,
341
+ assignSchema,
342
+ undefSchema,
343
+ arraySchema,
344
+ arrayPushSchema,
345
+ arrayPopSchema,
346
+ dictSchema,
347
+ dictSetSchema,
348
+ saveSchema,
349
+ loadSchema,
350
+ autoSaveSchema,
351
+ saveDeleteSchema,
352
+ bgmSchema,
353
+ seSchema,
354
+ voiceSchema,
355
+ stopSchema,
356
+ videoSchema,
357
+ cutsceneSchema,
358
+ seekVideoSchema,
359
+ videoSkipableSchema,
360
+ minigameSchema,
361
+ interactionSchema,
362
+ showSchema,
363
+ hideSchema,
364
+ backgroundSchema,
365
+ bgSwitchSchema,
366
+ zindexSchema,
367
+ styleSchema,
368
+ windowSchema,
369
+ animateSchema,
370
+ animateBlockSchema,
371
+ transitionSchema,
372
+ shakeSchema,
373
+ textTypewriterSchema,
374
+ };