@pactor-app/schema 0.1.0 → 1.1.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/dist/index.cjs CHANGED
@@ -32,11 +32,16 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ACTION_CONFIG_SCHEMA_ID: () => ACTION_CONFIG_SCHEMA_ID,
34
34
  DSL_NODE_SCHEMA_ID: () => DSL_NODE_SCHEMA_ID,
35
+ DSL_SOURCE_REF_SCHEMA_ID: () => DSL_SOURCE_REF_SCHEMA_ID,
35
36
  DSL_VERSION: () => DSL_VERSION,
36
37
  PAGE_DSL_SCHEMA_ID: () => PAGE_DSL_SCHEMA_ID,
37
38
  actionConfigSchema: () => actionConfigSchema,
38
39
  dslNodeSchema: () => dslNodeSchema,
40
+ dslSourceRefSchema: () => dslSourceRefSchema,
39
41
  pageDslSchema: () => pageDslSchema,
42
+ validateDslNode: () => validateDslNode,
43
+ validateDslNodes: () => validateDslNodes,
44
+ validateDslSourceRef: () => validateDslSourceRef,
40
45
  validatePageDsl: () => validatePageDsl
41
46
  });
42
47
  module.exports = __toCommonJS(index_exports);
@@ -99,18 +104,71 @@ var actionOrArraySchema = {
99
104
  { type: "array", items: { $ref: ACTION_CONFIG_SCHEMA_ID } }
100
105
  ]
101
106
  };
107
+ var DSL_SOURCE_REF_SCHEMA_ID = "pactor:dsl-source-ref";
108
+ var dslSourceRefSchema = {
109
+ $id: DSL_SOURCE_REF_SCHEMA_ID,
110
+ type: "object",
111
+ required: ["source"],
112
+ properties: {
113
+ source: {
114
+ anyOf: [
115
+ {
116
+ type: "object",
117
+ required: ["type", "service"],
118
+ properties: {
119
+ type: { const: "service" },
120
+ service: { type: "string", minLength: 1 },
121
+ params: { type: "object" }
122
+ },
123
+ additionalProperties: false
124
+ },
125
+ {
126
+ type: "object",
127
+ required: ["type", "request"],
128
+ properties: {
129
+ type: { const: "http" },
130
+ request: {
131
+ type: "object",
132
+ required: ["url"],
133
+ properties: {
134
+ method: { type: "string" },
135
+ url: { type: "string", minLength: 1 },
136
+ params: { type: "object" },
137
+ headers: { type: "object", additionalProperties: { type: "string" } }
138
+ },
139
+ additionalProperties: false
140
+ }
141
+ },
142
+ additionalProperties: false
143
+ }
144
+ ]
145
+ },
146
+ placeholder: { $ref: DSL_NODE_SCHEMA_ID }
147
+ },
148
+ additionalProperties: false
149
+ };
150
+ var dslChildrenSchema = {
151
+ anyOf: [
152
+ {
153
+ type: "array",
154
+ items: {
155
+ anyOf: [{ $ref: DSL_NODE_SCHEMA_ID }, { $ref: DSL_SOURCE_REF_SCHEMA_ID }]
156
+ }
157
+ },
158
+ { $ref: DSL_SOURCE_REF_SCHEMA_ID }
159
+ ]
160
+ };
102
161
  var dslNodeSchema = {
103
162
  $id: DSL_NODE_SCHEMA_ID,
104
163
  type: "object",
105
- required: ["type"],
164
+ anyOf: [{ required: ["type"] }, { required: ["component"] }],
106
165
  properties: {
107
166
  id: { type: "string" },
108
167
  type: { type: "string", minLength: 1 },
168
+ /** 引用节点:页面级命名组件(PageDsl.components)的 key */
169
+ component: { type: "string", minLength: 1 },
109
170
  props: { type: "object" },
110
- children: {
111
- type: "array",
112
- items: { $ref: DSL_NODE_SCHEMA_ID }
113
- },
171
+ children: dslChildrenSchema,
114
172
  events: {
115
173
  type: "object",
116
174
  additionalProperties: actionOrArraySchema
@@ -157,6 +215,11 @@ var dataSourceSchema = {
157
215
  service: { type: "string", minLength: 1 },
158
216
  autoLoad: { type: "boolean" },
159
217
  params: { type: "object" },
218
+ /** 选项字段映射(该数据源用作选项源时声明) */
219
+ valueField: { type: "string", minLength: 1 },
220
+ labelField: { type: "string", minLength: 1 },
221
+ /** 选项禁用标记字段 */
222
+ disabledField: { type: "string", minLength: 1 },
160
223
  request: {
161
224
  type: "object",
162
225
  required: ["url"],
@@ -207,16 +270,34 @@ var pageDslSchema = {
207
270
  properties: {
208
271
  id: { type: "string", minLength: 1 },
209
272
  title: { type: "string" },
273
+ /** 页面名称(标识用途) */
274
+ name: { type: "string" },
275
+ /** 页面描述 */
276
+ description: { type: "string" },
210
277
  type: { type: "string" },
211
278
  permission: permissionSchema2
212
279
  },
213
280
  additionalProperties: false
214
281
  },
282
+ /** 页面扩展元数据(自由键值,如 version / author),Runtime 不消费 */
283
+ meta: { type: "object" },
215
284
  state: { type: "object" },
216
285
  dataSources: {
217
286
  type: "object",
218
287
  additionalProperties: dataSourceSchema
219
288
  },
289
+ /** 页面级命名动作定义(供 call 动作按名引用复用) */
290
+ actions: {
291
+ type: "object",
292
+ additionalProperties: actionOrArraySchema2
293
+ },
294
+ /** 页面级命名组件定义(子树复用;值可为 DslSourceRef 远端惰性加载) */
295
+ components: {
296
+ type: "object",
297
+ additionalProperties: {
298
+ anyOf: [{ $ref: DSL_NODE_SCHEMA_ID }, { $ref: DSL_SOURCE_REF_SCHEMA_ID }]
299
+ }
300
+ },
220
301
  lifecycle: {
221
302
  type: "object",
222
303
  properties: {
@@ -229,7 +310,12 @@ var pageDslSchema = {
229
310
  },
230
311
  additionalProperties: false
231
312
  },
232
- body: { $ref: DSL_NODE_SCHEMA_ID }
313
+ body: { $ref: DSL_NODE_SCHEMA_ID },
314
+ /**
315
+ * UI 树根(节点数组形态,或 DslSourceRef 动态引用):`body` 缺失时作为替代,
316
+ * 用于 DSL 描述页面局部(无需 Page 等包装节点)
317
+ */
318
+ children: dslChildrenSchema
233
319
  },
234
320
  additionalProperties: false
235
321
  };
@@ -238,6 +324,7 @@ var pageDslSchema = {
238
324
  var import_ajv = __toESM(require("ajv"), 1);
239
325
  var ajv = new import_ajv.default({ allErrors: true, strict: false });
240
326
  ajv.addSchema(actionConfigSchema);
327
+ ajv.addSchema(dslSourceRefSchema);
241
328
  ajv.addSchema(dslNodeSchema);
242
329
  ajv.addSchema(pageDslSchema);
243
330
  function toStructuredErrors(errors) {
@@ -266,16 +353,70 @@ function getValidator() {
266
353
  function validatePageDsl(document) {
267
354
  const validate = getValidator();
268
355
  const valid = validate(document);
269
- return { valid, errors: valid ? [] : toStructuredErrors(validate.errors ?? []) };
356
+ return {
357
+ valid,
358
+ errors: valid ? [] : toStructuredErrors(validate.errors ?? []),
359
+ warnings: collectWarnings(document)
360
+ };
361
+ }
362
+ function collectWarnings(document) {
363
+ if (typeof document !== "object" || document === null) {
364
+ return [];
365
+ }
366
+ const doc = document;
367
+ if (doc.body !== void 0 && doc.children !== void 0) {
368
+ return [
369
+ {
370
+ path: "/children",
371
+ message: "body \u4E0E\u6839\u7EA7 children \u540C\u65F6\u58F0\u660E\uFF0Cchildren \u5C06\u88AB\u5FFD\u7565\uFF08body \u4F18\u5148\uFF09",
372
+ keyword: "conflict"
373
+ }
374
+ ];
375
+ }
376
+ return [];
377
+ }
378
+ function validateDslNode(value) {
379
+ const validate = ajv.getSchema(DSL_NODE_SCHEMA_ID);
380
+ if (!validate) {
381
+ throw new Error(`schema not registered: ${DSL_NODE_SCHEMA_ID}`);
382
+ }
383
+ const valid = validate(value);
384
+ return valid ? [] : toStructuredErrors(validate.errors ?? []);
385
+ }
386
+ function validateDslSourceRef(value) {
387
+ const validate = ajv.getSchema(DSL_SOURCE_REF_SCHEMA_ID);
388
+ if (!validate) {
389
+ throw new Error(`schema not registered: ${DSL_SOURCE_REF_SCHEMA_ID}`);
390
+ }
391
+ const valid = validate(value);
392
+ return valid ? [] : toStructuredErrors(validate.errors ?? []);
393
+ }
394
+ function validateDslNodes(value) {
395
+ if (!Array.isArray(value)) {
396
+ return [{ path: "/", message: "\u5FC5\u987B\u662F DslNode \u6570\u7EC4", keyword: "type" }];
397
+ }
398
+ return value.flatMap((item, index) => {
399
+ const isRef = typeof item === "object" && item !== null && !Array.isArray(item) && "source" in item;
400
+ const errors = isRef ? validateDslSourceRef(item) : validateDslNode(item);
401
+ return errors.map((error) => ({
402
+ ...error,
403
+ path: `/${index}${error.path === "/" ? "" : error.path}`
404
+ }));
405
+ });
270
406
  }
271
407
  // Annotate the CommonJS export names for ESM import in node:
272
408
  0 && (module.exports = {
273
409
  ACTION_CONFIG_SCHEMA_ID,
274
410
  DSL_NODE_SCHEMA_ID,
411
+ DSL_SOURCE_REF_SCHEMA_ID,
275
412
  DSL_VERSION,
276
413
  PAGE_DSL_SCHEMA_ID,
277
414
  actionConfigSchema,
278
415
  dslNodeSchema,
416
+ dslSourceRefSchema,
279
417
  pageDslSchema,
418
+ validateDslNode,
419
+ validateDslNodes,
420
+ validateDslSourceRef,
280
421
  validatePageDsl
281
422
  });
package/dist/index.d.cts CHANGED
@@ -80,11 +80,79 @@ declare const actionConfigSchema: {
80
80
  };
81
81
  readonly additionalProperties: false;
82
82
  };
83
- /** DslNode:type 必填,children 递归 */
83
+ /** DslSourceRef:动态 DSL 引用(service / http 二选一)+ 可选占位子树 */
84
+ declare const DSL_SOURCE_REF_SCHEMA_ID = "pactor:dsl-source-ref";
85
+ declare const dslSourceRefSchema: {
86
+ readonly $id: "pactor:dsl-source-ref";
87
+ readonly type: "object";
88
+ readonly required: readonly ["source"];
89
+ readonly properties: {
90
+ readonly source: {
91
+ readonly anyOf: readonly [{
92
+ readonly type: "object";
93
+ readonly required: readonly ["type", "service"];
94
+ readonly properties: {
95
+ readonly type: {
96
+ readonly const: "service";
97
+ };
98
+ readonly service: {
99
+ readonly type: "string";
100
+ readonly minLength: 1;
101
+ };
102
+ readonly params: {
103
+ readonly type: "object";
104
+ };
105
+ };
106
+ readonly additionalProperties: false;
107
+ }, {
108
+ readonly type: "object";
109
+ readonly required: readonly ["type", "request"];
110
+ readonly properties: {
111
+ readonly type: {
112
+ readonly const: "http";
113
+ };
114
+ readonly request: {
115
+ readonly type: "object";
116
+ readonly required: readonly ["url"];
117
+ readonly properties: {
118
+ readonly method: {
119
+ readonly type: "string";
120
+ };
121
+ readonly url: {
122
+ readonly type: "string";
123
+ readonly minLength: 1;
124
+ };
125
+ readonly params: {
126
+ readonly type: "object";
127
+ };
128
+ readonly headers: {
129
+ readonly type: "object";
130
+ readonly additionalProperties: {
131
+ readonly type: "string";
132
+ };
133
+ };
134
+ };
135
+ readonly additionalProperties: false;
136
+ };
137
+ };
138
+ readonly additionalProperties: false;
139
+ }];
140
+ };
141
+ readonly placeholder: {
142
+ readonly $ref: "pactor:dsl-node";
143
+ };
144
+ };
145
+ readonly additionalProperties: false;
146
+ };
147
+ /** DslNode:type(组件节点)或 component(引用页面级命名组件)二选一,children 递归 */
84
148
  declare const dslNodeSchema: {
85
149
  readonly $id: "pactor:dsl-node";
86
150
  readonly type: "object";
87
- readonly required: readonly ["type"];
151
+ readonly anyOf: readonly [{
152
+ readonly required: readonly ["type"];
153
+ }, {
154
+ readonly required: readonly ["component"];
155
+ }];
88
156
  readonly properties: {
89
157
  readonly id: {
90
158
  readonly type: "string";
@@ -93,14 +161,27 @@ declare const dslNodeSchema: {
93
161
  readonly type: "string";
94
162
  readonly minLength: 1;
95
163
  };
164
+ /** 引用节点:页面级命名组件(PageDsl.components)的 key */
165
+ readonly component: {
166
+ readonly type: "string";
167
+ readonly minLength: 1;
168
+ };
96
169
  readonly props: {
97
170
  readonly type: "object";
98
171
  };
99
172
  readonly children: {
100
- readonly type: "array";
101
- readonly items: {
102
- readonly $ref: "pactor:dsl-node";
103
- };
173
+ readonly anyOf: readonly [{
174
+ readonly type: "array";
175
+ readonly items: {
176
+ readonly anyOf: readonly [{
177
+ readonly $ref: "pactor:dsl-node";
178
+ }, {
179
+ readonly $ref: "pactor:dsl-source-ref";
180
+ }];
181
+ };
182
+ }, {
183
+ readonly $ref: "pactor:dsl-source-ref";
184
+ }];
104
185
  };
105
186
  readonly events: {
106
187
  readonly type: "object";
@@ -210,6 +291,14 @@ declare const pageDslSchema: {
210
291
  readonly title: {
211
292
  readonly type: "string";
212
293
  };
294
+ /** 页面名称(标识用途) */
295
+ readonly name: {
296
+ readonly type: "string";
297
+ };
298
+ /** 页面描述 */
299
+ readonly description: {
300
+ readonly type: "string";
301
+ };
213
302
  readonly type: {
214
303
  readonly type: "string";
215
304
  };
@@ -249,6 +338,10 @@ declare const pageDslSchema: {
249
338
  };
250
339
  readonly additionalProperties: false;
251
340
  };
341
+ /** 页面扩展元数据(自由键值,如 version / author),Runtime 不消费 */
342
+ readonly meta: {
343
+ readonly type: "object";
344
+ };
252
345
  readonly state: {
253
346
  readonly type: "object";
254
347
  };
@@ -271,6 +364,20 @@ declare const pageDslSchema: {
271
364
  readonly params: {
272
365
  readonly type: "object";
273
366
  };
367
+ /** 选项字段映射(该数据源用作选项源时声明) */
368
+ readonly valueField: {
369
+ readonly type: "string";
370
+ readonly minLength: 1;
371
+ };
372
+ readonly labelField: {
373
+ readonly type: "string";
374
+ readonly minLength: 1;
375
+ };
376
+ /** 选项禁用标记字段 */
377
+ readonly disabledField: {
378
+ readonly type: "string";
379
+ readonly minLength: 1;
380
+ };
274
381
  readonly request: {
275
382
  readonly type: "object";
276
383
  readonly required: readonly ["url"];
@@ -308,6 +415,31 @@ declare const pageDslSchema: {
308
415
  readonly additionalProperties: false;
309
416
  };
310
417
  };
418
+ /** 页面级命名动作定义(供 call 动作按名引用复用) */
419
+ readonly actions: {
420
+ readonly type: "object";
421
+ readonly additionalProperties: {
422
+ readonly anyOf: readonly [{
423
+ readonly $ref: "pactor:action-config";
424
+ }, {
425
+ readonly type: "array";
426
+ readonly items: {
427
+ readonly $ref: "pactor:action-config";
428
+ };
429
+ }];
430
+ };
431
+ };
432
+ /** 页面级命名组件定义(子树复用;值可为 DslSourceRef 远端惰性加载) */
433
+ readonly components: {
434
+ readonly type: "object";
435
+ readonly additionalProperties: {
436
+ readonly anyOf: readonly [{
437
+ readonly $ref: "pactor:dsl-node";
438
+ }, {
439
+ readonly $ref: "pactor:dsl-source-ref";
440
+ }];
441
+ };
442
+ };
311
443
  readonly lifecycle: {
312
444
  readonly type: "object";
313
445
  readonly properties: {
@@ -377,6 +509,24 @@ declare const pageDslSchema: {
377
509
  readonly body: {
378
510
  readonly $ref: "pactor:dsl-node";
379
511
  };
512
+ /**
513
+ * UI 树根(节点数组形态,或 DslSourceRef 动态引用):`body` 缺失时作为替代,
514
+ * 用于 DSL 描述页面局部(无需 Page 等包装节点)
515
+ */
516
+ readonly children: {
517
+ readonly anyOf: readonly [{
518
+ readonly type: "array";
519
+ readonly items: {
520
+ readonly anyOf: readonly [{
521
+ readonly $ref: "pactor:dsl-node";
522
+ }, {
523
+ readonly $ref: "pactor:dsl-source-ref";
524
+ }];
525
+ };
526
+ }, {
527
+ readonly $ref: "pactor:dsl-source-ref";
528
+ }];
529
+ };
380
530
  };
381
531
  readonly additionalProperties: false;
382
532
  };
@@ -393,11 +543,24 @@ interface DslValidationError {
393
543
  interface DslValidationResult {
394
544
  valid: boolean;
395
545
  errors: DslValidationError[];
546
+ /** 提示级信息(不阻断校验),如 body 与根级 children 共存 */
547
+ warnings: DslValidationError[];
396
548
  }
397
549
  /**
398
550
  * 校验 Page DSL 文档是否符合根结构 Schema。
399
- * 校验通过时 errors 为空数组。
551
+ * 校验通过时 errors 为空数组;warnings 为提示级信息(不阻断校验)。
400
552
  */
401
553
  declare function validatePageDsl(document: unknown): DslValidationResult;
554
+ /**
555
+ * 校验单个 DslNode(如远端动态加载的子树),返回结构化错误列表(空数组为通过)。
556
+ */
557
+ declare function validateDslNode(value: unknown): DslValidationError[];
558
+ /** 校验单个 DslSourceRef(children 数组中的引用元素) */
559
+ declare function validateDslSourceRef(value: unknown): DslValidationError[];
560
+ /**
561
+ * 校验 DslChildrenItem 数组(如远端动态加载的根级/节点级 children),
562
+ * 元素可为 DslNode 或 DslSourceRef 混排。返回结构化错误列表(空数组为通过)。
563
+ */
564
+ declare function validateDslNodes(value: unknown): DslValidationError[];
402
565
 
403
- export { ACTION_CONFIG_SCHEMA_ID, DSL_NODE_SCHEMA_ID, DSL_VERSION, type DslValidationError, type DslValidationResult, PAGE_DSL_SCHEMA_ID, actionConfigSchema, dslNodeSchema, pageDslSchema, validatePageDsl };
566
+ export { ACTION_CONFIG_SCHEMA_ID, DSL_NODE_SCHEMA_ID, DSL_SOURCE_REF_SCHEMA_ID, DSL_VERSION, type DslValidationError, type DslValidationResult, PAGE_DSL_SCHEMA_ID, actionConfigSchema, dslNodeSchema, dslSourceRefSchema, pageDslSchema, validateDslNode, validateDslNodes, validateDslSourceRef, validatePageDsl };
package/dist/index.d.ts CHANGED
@@ -80,11 +80,79 @@ declare const actionConfigSchema: {
80
80
  };
81
81
  readonly additionalProperties: false;
82
82
  };
83
- /** DslNode:type 必填,children 递归 */
83
+ /** DslSourceRef:动态 DSL 引用(service / http 二选一)+ 可选占位子树 */
84
+ declare const DSL_SOURCE_REF_SCHEMA_ID = "pactor:dsl-source-ref";
85
+ declare const dslSourceRefSchema: {
86
+ readonly $id: "pactor:dsl-source-ref";
87
+ readonly type: "object";
88
+ readonly required: readonly ["source"];
89
+ readonly properties: {
90
+ readonly source: {
91
+ readonly anyOf: readonly [{
92
+ readonly type: "object";
93
+ readonly required: readonly ["type", "service"];
94
+ readonly properties: {
95
+ readonly type: {
96
+ readonly const: "service";
97
+ };
98
+ readonly service: {
99
+ readonly type: "string";
100
+ readonly minLength: 1;
101
+ };
102
+ readonly params: {
103
+ readonly type: "object";
104
+ };
105
+ };
106
+ readonly additionalProperties: false;
107
+ }, {
108
+ readonly type: "object";
109
+ readonly required: readonly ["type", "request"];
110
+ readonly properties: {
111
+ readonly type: {
112
+ readonly const: "http";
113
+ };
114
+ readonly request: {
115
+ readonly type: "object";
116
+ readonly required: readonly ["url"];
117
+ readonly properties: {
118
+ readonly method: {
119
+ readonly type: "string";
120
+ };
121
+ readonly url: {
122
+ readonly type: "string";
123
+ readonly minLength: 1;
124
+ };
125
+ readonly params: {
126
+ readonly type: "object";
127
+ };
128
+ readonly headers: {
129
+ readonly type: "object";
130
+ readonly additionalProperties: {
131
+ readonly type: "string";
132
+ };
133
+ };
134
+ };
135
+ readonly additionalProperties: false;
136
+ };
137
+ };
138
+ readonly additionalProperties: false;
139
+ }];
140
+ };
141
+ readonly placeholder: {
142
+ readonly $ref: "pactor:dsl-node";
143
+ };
144
+ };
145
+ readonly additionalProperties: false;
146
+ };
147
+ /** DslNode:type(组件节点)或 component(引用页面级命名组件)二选一,children 递归 */
84
148
  declare const dslNodeSchema: {
85
149
  readonly $id: "pactor:dsl-node";
86
150
  readonly type: "object";
87
- readonly required: readonly ["type"];
151
+ readonly anyOf: readonly [{
152
+ readonly required: readonly ["type"];
153
+ }, {
154
+ readonly required: readonly ["component"];
155
+ }];
88
156
  readonly properties: {
89
157
  readonly id: {
90
158
  readonly type: "string";
@@ -93,14 +161,27 @@ declare const dslNodeSchema: {
93
161
  readonly type: "string";
94
162
  readonly minLength: 1;
95
163
  };
164
+ /** 引用节点:页面级命名组件(PageDsl.components)的 key */
165
+ readonly component: {
166
+ readonly type: "string";
167
+ readonly minLength: 1;
168
+ };
96
169
  readonly props: {
97
170
  readonly type: "object";
98
171
  };
99
172
  readonly children: {
100
- readonly type: "array";
101
- readonly items: {
102
- readonly $ref: "pactor:dsl-node";
103
- };
173
+ readonly anyOf: readonly [{
174
+ readonly type: "array";
175
+ readonly items: {
176
+ readonly anyOf: readonly [{
177
+ readonly $ref: "pactor:dsl-node";
178
+ }, {
179
+ readonly $ref: "pactor:dsl-source-ref";
180
+ }];
181
+ };
182
+ }, {
183
+ readonly $ref: "pactor:dsl-source-ref";
184
+ }];
104
185
  };
105
186
  readonly events: {
106
187
  readonly type: "object";
@@ -210,6 +291,14 @@ declare const pageDslSchema: {
210
291
  readonly title: {
211
292
  readonly type: "string";
212
293
  };
294
+ /** 页面名称(标识用途) */
295
+ readonly name: {
296
+ readonly type: "string";
297
+ };
298
+ /** 页面描述 */
299
+ readonly description: {
300
+ readonly type: "string";
301
+ };
213
302
  readonly type: {
214
303
  readonly type: "string";
215
304
  };
@@ -249,6 +338,10 @@ declare const pageDslSchema: {
249
338
  };
250
339
  readonly additionalProperties: false;
251
340
  };
341
+ /** 页面扩展元数据(自由键值,如 version / author),Runtime 不消费 */
342
+ readonly meta: {
343
+ readonly type: "object";
344
+ };
252
345
  readonly state: {
253
346
  readonly type: "object";
254
347
  };
@@ -271,6 +364,20 @@ declare const pageDslSchema: {
271
364
  readonly params: {
272
365
  readonly type: "object";
273
366
  };
367
+ /** 选项字段映射(该数据源用作选项源时声明) */
368
+ readonly valueField: {
369
+ readonly type: "string";
370
+ readonly minLength: 1;
371
+ };
372
+ readonly labelField: {
373
+ readonly type: "string";
374
+ readonly minLength: 1;
375
+ };
376
+ /** 选项禁用标记字段 */
377
+ readonly disabledField: {
378
+ readonly type: "string";
379
+ readonly minLength: 1;
380
+ };
274
381
  readonly request: {
275
382
  readonly type: "object";
276
383
  readonly required: readonly ["url"];
@@ -308,6 +415,31 @@ declare const pageDslSchema: {
308
415
  readonly additionalProperties: false;
309
416
  };
310
417
  };
418
+ /** 页面级命名动作定义(供 call 动作按名引用复用) */
419
+ readonly actions: {
420
+ readonly type: "object";
421
+ readonly additionalProperties: {
422
+ readonly anyOf: readonly [{
423
+ readonly $ref: "pactor:action-config";
424
+ }, {
425
+ readonly type: "array";
426
+ readonly items: {
427
+ readonly $ref: "pactor:action-config";
428
+ };
429
+ }];
430
+ };
431
+ };
432
+ /** 页面级命名组件定义(子树复用;值可为 DslSourceRef 远端惰性加载) */
433
+ readonly components: {
434
+ readonly type: "object";
435
+ readonly additionalProperties: {
436
+ readonly anyOf: readonly [{
437
+ readonly $ref: "pactor:dsl-node";
438
+ }, {
439
+ readonly $ref: "pactor:dsl-source-ref";
440
+ }];
441
+ };
442
+ };
311
443
  readonly lifecycle: {
312
444
  readonly type: "object";
313
445
  readonly properties: {
@@ -377,6 +509,24 @@ declare const pageDslSchema: {
377
509
  readonly body: {
378
510
  readonly $ref: "pactor:dsl-node";
379
511
  };
512
+ /**
513
+ * UI 树根(节点数组形态,或 DslSourceRef 动态引用):`body` 缺失时作为替代,
514
+ * 用于 DSL 描述页面局部(无需 Page 等包装节点)
515
+ */
516
+ readonly children: {
517
+ readonly anyOf: readonly [{
518
+ readonly type: "array";
519
+ readonly items: {
520
+ readonly anyOf: readonly [{
521
+ readonly $ref: "pactor:dsl-node";
522
+ }, {
523
+ readonly $ref: "pactor:dsl-source-ref";
524
+ }];
525
+ };
526
+ }, {
527
+ readonly $ref: "pactor:dsl-source-ref";
528
+ }];
529
+ };
380
530
  };
381
531
  readonly additionalProperties: false;
382
532
  };
@@ -393,11 +543,24 @@ interface DslValidationError {
393
543
  interface DslValidationResult {
394
544
  valid: boolean;
395
545
  errors: DslValidationError[];
546
+ /** 提示级信息(不阻断校验),如 body 与根级 children 共存 */
547
+ warnings: DslValidationError[];
396
548
  }
397
549
  /**
398
550
  * 校验 Page DSL 文档是否符合根结构 Schema。
399
- * 校验通过时 errors 为空数组。
551
+ * 校验通过时 errors 为空数组;warnings 为提示级信息(不阻断校验)。
400
552
  */
401
553
  declare function validatePageDsl(document: unknown): DslValidationResult;
554
+ /**
555
+ * 校验单个 DslNode(如远端动态加载的子树),返回结构化错误列表(空数组为通过)。
556
+ */
557
+ declare function validateDslNode(value: unknown): DslValidationError[];
558
+ /** 校验单个 DslSourceRef(children 数组中的引用元素) */
559
+ declare function validateDslSourceRef(value: unknown): DslValidationError[];
560
+ /**
561
+ * 校验 DslChildrenItem 数组(如远端动态加载的根级/节点级 children),
562
+ * 元素可为 DslNode 或 DslSourceRef 混排。返回结构化错误列表(空数组为通过)。
563
+ */
564
+ declare function validateDslNodes(value: unknown): DslValidationError[];
402
565
 
403
- export { ACTION_CONFIG_SCHEMA_ID, DSL_NODE_SCHEMA_ID, DSL_VERSION, type DslValidationError, type DslValidationResult, PAGE_DSL_SCHEMA_ID, actionConfigSchema, dslNodeSchema, pageDslSchema, validatePageDsl };
566
+ export { ACTION_CONFIG_SCHEMA_ID, DSL_NODE_SCHEMA_ID, DSL_SOURCE_REF_SCHEMA_ID, DSL_VERSION, type DslValidationError, type DslValidationResult, PAGE_DSL_SCHEMA_ID, actionConfigSchema, dslNodeSchema, dslSourceRefSchema, pageDslSchema, validateDslNode, validateDslNodes, validateDslSourceRef, validatePageDsl };
package/dist/index.js CHANGED
@@ -56,18 +56,71 @@ var actionOrArraySchema = {
56
56
  { type: "array", items: { $ref: ACTION_CONFIG_SCHEMA_ID } }
57
57
  ]
58
58
  };
59
+ var DSL_SOURCE_REF_SCHEMA_ID = "pactor:dsl-source-ref";
60
+ var dslSourceRefSchema = {
61
+ $id: DSL_SOURCE_REF_SCHEMA_ID,
62
+ type: "object",
63
+ required: ["source"],
64
+ properties: {
65
+ source: {
66
+ anyOf: [
67
+ {
68
+ type: "object",
69
+ required: ["type", "service"],
70
+ properties: {
71
+ type: { const: "service" },
72
+ service: { type: "string", minLength: 1 },
73
+ params: { type: "object" }
74
+ },
75
+ additionalProperties: false
76
+ },
77
+ {
78
+ type: "object",
79
+ required: ["type", "request"],
80
+ properties: {
81
+ type: { const: "http" },
82
+ request: {
83
+ type: "object",
84
+ required: ["url"],
85
+ properties: {
86
+ method: { type: "string" },
87
+ url: { type: "string", minLength: 1 },
88
+ params: { type: "object" },
89
+ headers: { type: "object", additionalProperties: { type: "string" } }
90
+ },
91
+ additionalProperties: false
92
+ }
93
+ },
94
+ additionalProperties: false
95
+ }
96
+ ]
97
+ },
98
+ placeholder: { $ref: DSL_NODE_SCHEMA_ID }
99
+ },
100
+ additionalProperties: false
101
+ };
102
+ var dslChildrenSchema = {
103
+ anyOf: [
104
+ {
105
+ type: "array",
106
+ items: {
107
+ anyOf: [{ $ref: DSL_NODE_SCHEMA_ID }, { $ref: DSL_SOURCE_REF_SCHEMA_ID }]
108
+ }
109
+ },
110
+ { $ref: DSL_SOURCE_REF_SCHEMA_ID }
111
+ ]
112
+ };
59
113
  var dslNodeSchema = {
60
114
  $id: DSL_NODE_SCHEMA_ID,
61
115
  type: "object",
62
- required: ["type"],
116
+ anyOf: [{ required: ["type"] }, { required: ["component"] }],
63
117
  properties: {
64
118
  id: { type: "string" },
65
119
  type: { type: "string", minLength: 1 },
120
+ /** 引用节点:页面级命名组件(PageDsl.components)的 key */
121
+ component: { type: "string", minLength: 1 },
66
122
  props: { type: "object" },
67
- children: {
68
- type: "array",
69
- items: { $ref: DSL_NODE_SCHEMA_ID }
70
- },
123
+ children: dslChildrenSchema,
71
124
  events: {
72
125
  type: "object",
73
126
  additionalProperties: actionOrArraySchema
@@ -114,6 +167,11 @@ var dataSourceSchema = {
114
167
  service: { type: "string", minLength: 1 },
115
168
  autoLoad: { type: "boolean" },
116
169
  params: { type: "object" },
170
+ /** 选项字段映射(该数据源用作选项源时声明) */
171
+ valueField: { type: "string", minLength: 1 },
172
+ labelField: { type: "string", minLength: 1 },
173
+ /** 选项禁用标记字段 */
174
+ disabledField: { type: "string", minLength: 1 },
117
175
  request: {
118
176
  type: "object",
119
177
  required: ["url"],
@@ -164,16 +222,34 @@ var pageDslSchema = {
164
222
  properties: {
165
223
  id: { type: "string", minLength: 1 },
166
224
  title: { type: "string" },
225
+ /** 页面名称(标识用途) */
226
+ name: { type: "string" },
227
+ /** 页面描述 */
228
+ description: { type: "string" },
167
229
  type: { type: "string" },
168
230
  permission: permissionSchema2
169
231
  },
170
232
  additionalProperties: false
171
233
  },
234
+ /** 页面扩展元数据(自由键值,如 version / author),Runtime 不消费 */
235
+ meta: { type: "object" },
172
236
  state: { type: "object" },
173
237
  dataSources: {
174
238
  type: "object",
175
239
  additionalProperties: dataSourceSchema
176
240
  },
241
+ /** 页面级命名动作定义(供 call 动作按名引用复用) */
242
+ actions: {
243
+ type: "object",
244
+ additionalProperties: actionOrArraySchema2
245
+ },
246
+ /** 页面级命名组件定义(子树复用;值可为 DslSourceRef 远端惰性加载) */
247
+ components: {
248
+ type: "object",
249
+ additionalProperties: {
250
+ anyOf: [{ $ref: DSL_NODE_SCHEMA_ID }, { $ref: DSL_SOURCE_REF_SCHEMA_ID }]
251
+ }
252
+ },
177
253
  lifecycle: {
178
254
  type: "object",
179
255
  properties: {
@@ -186,7 +262,12 @@ var pageDslSchema = {
186
262
  },
187
263
  additionalProperties: false
188
264
  },
189
- body: { $ref: DSL_NODE_SCHEMA_ID }
265
+ body: { $ref: DSL_NODE_SCHEMA_ID },
266
+ /**
267
+ * UI 树根(节点数组形态,或 DslSourceRef 动态引用):`body` 缺失时作为替代,
268
+ * 用于 DSL 描述页面局部(无需 Page 等包装节点)
269
+ */
270
+ children: dslChildrenSchema
190
271
  },
191
272
  additionalProperties: false
192
273
  };
@@ -195,6 +276,7 @@ var pageDslSchema = {
195
276
  import Ajv from "ajv";
196
277
  var ajv = new Ajv({ allErrors: true, strict: false });
197
278
  ajv.addSchema(actionConfigSchema);
279
+ ajv.addSchema(dslSourceRefSchema);
198
280
  ajv.addSchema(dslNodeSchema);
199
281
  ajv.addSchema(pageDslSchema);
200
282
  function toStructuredErrors(errors) {
@@ -223,15 +305,69 @@ function getValidator() {
223
305
  function validatePageDsl(document) {
224
306
  const validate = getValidator();
225
307
  const valid = validate(document);
226
- return { valid, errors: valid ? [] : toStructuredErrors(validate.errors ?? []) };
308
+ return {
309
+ valid,
310
+ errors: valid ? [] : toStructuredErrors(validate.errors ?? []),
311
+ warnings: collectWarnings(document)
312
+ };
313
+ }
314
+ function collectWarnings(document) {
315
+ if (typeof document !== "object" || document === null) {
316
+ return [];
317
+ }
318
+ const doc = document;
319
+ if (doc.body !== void 0 && doc.children !== void 0) {
320
+ return [
321
+ {
322
+ path: "/children",
323
+ message: "body \u4E0E\u6839\u7EA7 children \u540C\u65F6\u58F0\u660E\uFF0Cchildren \u5C06\u88AB\u5FFD\u7565\uFF08body \u4F18\u5148\uFF09",
324
+ keyword: "conflict"
325
+ }
326
+ ];
327
+ }
328
+ return [];
329
+ }
330
+ function validateDslNode(value) {
331
+ const validate = ajv.getSchema(DSL_NODE_SCHEMA_ID);
332
+ if (!validate) {
333
+ throw new Error(`schema not registered: ${DSL_NODE_SCHEMA_ID}`);
334
+ }
335
+ const valid = validate(value);
336
+ return valid ? [] : toStructuredErrors(validate.errors ?? []);
337
+ }
338
+ function validateDslSourceRef(value) {
339
+ const validate = ajv.getSchema(DSL_SOURCE_REF_SCHEMA_ID);
340
+ if (!validate) {
341
+ throw new Error(`schema not registered: ${DSL_SOURCE_REF_SCHEMA_ID}`);
342
+ }
343
+ const valid = validate(value);
344
+ return valid ? [] : toStructuredErrors(validate.errors ?? []);
345
+ }
346
+ function validateDslNodes(value) {
347
+ if (!Array.isArray(value)) {
348
+ return [{ path: "/", message: "\u5FC5\u987B\u662F DslNode \u6570\u7EC4", keyword: "type" }];
349
+ }
350
+ return value.flatMap((item, index) => {
351
+ const isRef = typeof item === "object" && item !== null && !Array.isArray(item) && "source" in item;
352
+ const errors = isRef ? validateDslSourceRef(item) : validateDslNode(item);
353
+ return errors.map((error) => ({
354
+ ...error,
355
+ path: `/${index}${error.path === "/" ? "" : error.path}`
356
+ }));
357
+ });
227
358
  }
228
359
  export {
229
360
  ACTION_CONFIG_SCHEMA_ID,
230
361
  DSL_NODE_SCHEMA_ID,
362
+ DSL_SOURCE_REF_SCHEMA_ID,
231
363
  DSL_VERSION,
232
364
  PAGE_DSL_SCHEMA_ID,
233
365
  actionConfigSchema,
234
366
  dslNodeSchema,
367
+ dslSourceRefSchema,
235
368
  pageDslSchema,
369
+ validateDslNode,
370
+ validateDslNodes,
371
+ validateDslSourceRef,
236
372
  validatePageDsl
237
373
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactor-app/schema",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "description": "Pactor schema: DSL version constants, JSON Schemas and Ajv-based validator",
5
5
  "keywords": [
6
6
  "pactor",
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "ajv": "^8.17.1",
49
- "@pactor-app/core": "0.1.0"
49
+ "@pactor-app/core": "1.1.0"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup",