openxiangda-devkit-core 2.0.0-alpha.51 → 2.0.0-alpha.53

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.
Files changed (31) hide show
  1. package/dist/compiler/ai-catalog.d.ts.map +1 -1
  2. package/dist/compiler/ai-catalog.js +76 -20
  3. package/dist/compiler/ai-catalog.js.map +1 -1
  4. package/dist/compiler/bundle.d.ts.map +1 -1
  5. package/dist/compiler/bundle.js +88 -37
  6. package/dist/compiler/bundle.js.map +1 -1
  7. package/dist/compiler/config.d.ts +9 -3
  8. package/dist/compiler/config.d.ts.map +1 -1
  9. package/dist/compiler/config.js +189 -32
  10. package/dist/compiler/config.js.map +1 -1
  11. package/dist/compiler/field-codec.d.ts +7 -0
  12. package/dist/compiler/field-codec.d.ts.map +1 -0
  13. package/dist/compiler/field-codec.js +124 -0
  14. package/dist/compiler/field-codec.js.map +1 -0
  15. package/dist/compiler/field-physical-plan.d.ts +9 -0
  16. package/dist/compiler/field-physical-plan.d.ts.map +1 -0
  17. package/dist/compiler/field-physical-plan.js +59 -0
  18. package/dist/compiler/field-physical-plan.js.map +1 -0
  19. package/dist/compiler/field-policy-path.d.ts +10 -0
  20. package/dist/compiler/field-policy-path.d.ts.map +1 -0
  21. package/dist/compiler/field-policy-path.js +264 -0
  22. package/dist/compiler/field-policy-path.js.map +1 -0
  23. package/dist/compiler/field-query-plan.d.ts +13 -0
  24. package/dist/compiler/field-query-plan.d.ts.map +1 -0
  25. package/dist/compiler/field-query-plan.js +122 -0
  26. package/dist/compiler/field-query-plan.js.map +1 -0
  27. package/dist/compiler/field-surface.d.ts +5 -5
  28. package/dist/compiler/field-surface.d.ts.map +1 -1
  29. package/dist/compiler/field-surface.js +41 -24
  30. package/dist/compiler/field-surface.js.map +1 -1
  31. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { type AppApiOperationDeclaration, type AppAuthorizationTransitionDeclaration, type AppBackendSecretDeclaration, type AppCapabilityDeclaration, type AppDataPolicyDeclaration, type AppDataPolicyRuleDeclaration, type AppFrontendRouteDeclaration, type AppRoleDeclaration, type AppScopeDimensionDeclaration, type AppScopeSourceDeclaration, type NativeWorkflowEditableParameterDeclaration, type DataFieldDefinition, type DataFieldPolicy, type DataFieldSurface, type DataFieldSurfaceWidget, type DataResourceSurface, type DataResource, type Diagnostic, type EventSubscription, type TimerSubscription, type WorkflowBinding, type WorkflowDefinition } from 'openxiangda-contracts';
1
+ import { type AppApiOperationDeclaration, type AppAuthorizationTransitionDeclaration, type AppBackendSecretDeclaration, type AppCapabilityDeclaration, type AppDataPolicyDeclaration, type AppDataPolicyRuleDeclaration, type AppFrontendRouteDeclaration, type AppRoleDeclaration, type AppScopeDimensionDeclaration, type AppScopeSourceDeclaration, type NativeWorkflowEditableParameterDeclaration, type DataFieldDefinition, type DataFieldPolicy, type DataFieldSurfaceWidget, type DataResourceSurface, type DataResource, type Diagnostic, type EventSubscription, type TimerSubscription, type WorkflowBinding, type WorkflowDefinition } from 'openxiangda-contracts';
2
2
  export type EventSubscriptionDeclaration = Pick<EventSubscription, 'code' | 'eventTypes' | 'subjectFilters' | 'endpointPath'> & {
3
3
  description?: string;
4
4
  delivery?: Partial<EventSubscription['delivery']>;
@@ -45,8 +45,15 @@ export interface AppDataFieldDeclaration {
45
45
  label: string;
46
46
  required?: boolean;
47
47
  indexed?: boolean;
48
- reference?: DataFieldDefinition['reference'];
48
+ options?: DataFieldDefinition['options'];
49
+ source?: DataFieldDefinition['source'];
50
+ maxLength?: DataFieldDefinition['maxLength'];
51
+ precision?: DataFieldDefinition['precision'];
52
+ scale?: DataFieldDefinition['scale'];
53
+ timePrecision?: DataFieldDefinition['timePrecision'];
49
54
  file?: DataFieldDefinition['file'];
55
+ serial?: DataFieldDefinition['serial'];
56
+ subtable?: DataFieldDefinition['subtable'];
50
57
  widget?: DataFieldSurfaceWidget;
51
58
  section?: string;
52
59
  system?: boolean;
@@ -54,7 +61,6 @@ export interface AppDataFieldDeclaration {
54
61
  filter?: boolean;
55
62
  searchable?: boolean;
56
63
  sortable?: boolean;
57
- options?: DataFieldSurface['options'];
58
64
  access?: AppDataFieldAccessDeclaration;
59
65
  }
60
66
  export interface AppDataResourceDeclaration {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/compiler/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/compiler/config.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,10 @@
1
1
  import { SCHEMA_VERSIONS, DATA_FIELD_TYPES, nativePlatformCapabilityCatalog, validateDataResource, } from 'openxiangda-contracts';
2
2
  import { CronExpressionParser } from 'cron-parser';
3
- import { resolveDataFieldSurfaceWidget } from './field-surface.js';
3
+ import { fieldNullable, isGeneratedField } from './field-codec.js';
4
+ import { supportsFilter, supportsSearch, supportsSort, } from './field-query-plan.js';
5
+ import { physicalPlanForField } from './field-physical-plan.js';
6
+ import { SEMANTIC_FIELD_PATH_PATTERN, semanticFieldPathRoot, validateAuthzSemanticBindings, } from './field-policy-path.js';
7
+ import { compatibleWidgets, isCompatibleFieldWidget, resolveDataFieldSurfaceWidget, } from './field-surface.js';
4
8
  // The compiler owns the application source contract. Devkit and every adapter
5
9
  // re-export this module instead of maintaining separate configuration models.
6
10
  import { validateWorkflowBinding, validateWorkflowDefinition, } from '../internal/workflow.js';
@@ -379,22 +383,54 @@ export function validateAppConfig(value) {
379
383
  const fields = object(resourceRecord.schema).fields;
380
384
  (Array.isArray(fields) ? fields : []).forEach((rawField, fieldIndex) => {
381
385
  const field = object(rawField);
382
- const reference = object(field.reference);
383
- if (string(reference.kind) !== 'resource')
386
+ const source = object(field.source);
387
+ if (string(source.kind) !== 'resource')
384
388
  return;
385
- const targetCode = string(reference.resourceCode);
389
+ const targetCode = string(source.resourceCode);
386
390
  const target = resources.find(candidate => string(object(candidate).code) === targetCode);
387
- const referencePath = `data.resources[${index}].schema.fields[${fieldIndex}].reference`;
391
+ const sourcePath = `data.resources[${index}].schema.fields[${fieldIndex}].source`;
388
392
  if (!target) {
389
- diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_REFERENCE_TARGET_NOT_FOUND', `资源引用目标 ${targetCode} 必须在同一应用中声明`, `${referencePath}.resourceCode`));
393
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_TARGET_NOT_FOUND', `动态选项来源 ${targetCode} 必须在同一应用中声明`, `${sourcePath}.resourceCode`));
390
394
  return;
391
395
  }
392
396
  const targetFields = object(object(target).schema).fields;
393
- const labelField = string(reference.labelField);
397
+ const targetFieldList = Array.isArray(targetFields) ? targetFields : [];
398
+ const labelField = string(source.labelField);
394
399
  const label = (Array.isArray(targetFields) ? targetFields : []).find(candidate => string(object(candidate).code) === labelField);
395
- if (!label || !['string', 'text'].includes(string(object(label).type))) {
396
- diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_REFERENCE_LABEL_INVALID', `资源引用标签字段 ${labelField} 必须是 string 或 text`, `${referencePath}.labelField`));
400
+ if (!label ||
401
+ !['text.short', 'text.long', 'serial-number'].includes(string(object(label).type))) {
402
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_LABEL_INVALID', `动态选项标签字段 ${labelField} 必须是文本或流水号`, `${sourcePath}.labelField`));
397
403
  }
404
+ for (const key of [
405
+ 'searchFields',
406
+ 'descriptionFields',
407
+ 'snapshotFields',
408
+ ]) {
409
+ const values = Array.isArray(source[key]) ? source[key] : [];
410
+ values.forEach((value, valueIndex) => {
411
+ const targetField = targetFieldList.find(candidate => string(object(candidate).code) === string(value));
412
+ if (!targetField) {
413
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_FIELD_NOT_FOUND', `动态来源字段 ${String(value)} 未在 ${targetCode} 声明`, `${sourcePath}.${key}[${valueIndex}]`));
414
+ }
415
+ else if (key === 'searchFields' &&
416
+ !supportsSearch(string(object(targetField).type))) {
417
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_SEARCH_UNSUPPORTED', `动态来源字段 ${String(value)} 不支持搜索`, `${sourcePath}.${key}[${valueIndex}]`));
418
+ }
419
+ });
420
+ }
421
+ const sourceFilters = Array.isArray(source.filters) ? source.filters : [];
422
+ sourceFilters.forEach((rawFilter, filterIndex) => {
423
+ const filter = object(rawFilter);
424
+ const targetFieldCode = string(filter.field);
425
+ if (!targetFieldList.some(candidate => string(object(candidate).code) === targetFieldCode)) {
426
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_FILTER_FIELD_NOT_FOUND', `动态来源筛选字段 ${targetFieldCode} 未在 ${targetCode} 声明`, `${sourcePath}.filters[${filterIndex}].field`));
427
+ }
428
+ const bindingField = string(object(filter.binding).field);
429
+ if (bindingField &&
430
+ !(Array.isArray(fields) ? fields : []).some(candidate => string(object(candidate).code) === bindingField)) {
431
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_RESOURCE_SOURCE_BINDING_FIELD_NOT_FOUND', `动态来源绑定字段 ${bindingField} 未在当前资源声明`, `${sourcePath}.filters[${filterIndex}].binding.field`));
432
+ }
433
+ });
398
434
  });
399
435
  });
400
436
  }
@@ -514,10 +550,10 @@ export function validateAppConfig(value) {
514
550
  if (!declaredFieldTypes) {
515
551
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_DIMENSION_VALUE_SOURCE_RESOURCE_INVALID', 'native_resource valueSource 必须引用同一应用内已声明的 Data Resource', `${valueSourcePath}.resourceCode`));
516
552
  }
517
- else if (!['string', 'text'].includes(declaredFieldTypes.get(labelField) || '') ||
553
+ else if (!['text.short', 'text.long', 'serial-number'].includes(declaredFieldTypes.get(labelField) || '') ||
518
554
  (enabledField !== undefined &&
519
555
  declaredFieldTypes.get(enabledField) !== 'boolean')) {
520
- diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_DIMENSION_VALUE_SOURCE_FIELD_INVALID', 'valueSource 标签字段必须为 string/text,启用字段必须为 boolean', valueSourcePath));
556
+ diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_DIMENSION_VALUE_SOURCE_FIELD_INVALID', 'valueSource 标签字段必须为文本/流水号,启用字段必须为 boolean', valueSourcePath));
521
557
  }
522
558
  }
523
559
  dimensionCodes.add(code);
@@ -541,7 +577,7 @@ export function validateAppConfig(value) {
541
577
  !string(source.name) ||
542
578
  !/^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/.test(resourceCode) ||
543
579
  !['user', 'role_membership'].includes(subjectType) ||
544
- !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/.test(string(subject.userIdField)) ||
580
+ !SEMANTIC_FIELD_PATH_PATTERN.test(string(subject.userIdField)) ||
545
581
  (subjectType === 'role_membership' && !roleCodes.has(roleCode)) ||
546
582
  (subjectType === 'user' && Boolean(roleCode)) ||
547
583
  grants.length === 0 ||
@@ -554,9 +590,9 @@ export function validateAppConfig(value) {
554
590
  const dimensionCode = string(grant.dimensionCode);
555
591
  if (!dimensionCodes.has(dimensionCode) ||
556
592
  grantDimensions.has(dimensionCode) ||
557
- !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/.test(string(grant.valueField)) ||
593
+ !SEMANTIC_FIELD_PATH_PATTERN.test(string(grant.valueField)) ||
558
594
  (grant.parentValueField !== undefined &&
559
- !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/.test(string(grant.parentValueField)))) {
595
+ !SEMANTIC_FIELD_PATH_PATTERN.test(string(grant.parentValueField)))) {
560
596
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_SCOPE_SOURCE_GRANT_INVALID', 'scope source grant 必须引用唯一已声明维度及有效字段', `${sourcePath}.grants[${grantIndex}]`));
561
597
  }
562
598
  grantDimensions.add(dimensionCode);
@@ -593,7 +629,7 @@ export function validateAppConfig(value) {
593
629
  .map(string),
594
630
  ];
595
631
  if (!declaredFields ||
596
- referencedFields.some(field => !declaredFields.has(field))) {
632
+ referencedFields.some(field => !declaredFields.has(semanticFieldPathRoot(field)))) {
597
633
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_SCOPE_SOURCE_RESOURCE_INVALID', 'scope source 必须引用已声明 Data Resource 及其真实字段', sourcePath));
598
634
  }
599
635
  sourceCodes.add(code);
@@ -611,6 +647,9 @@ export function validateAppConfig(value) {
611
647
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_POLICY_INVALID', 'data policy 必须声明唯一 code、name、matchMode 和至少一条规则', `authz.dataPolicies[${index}]`));
612
648
  }
613
649
  policyCodes.add(code);
650
+ if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(string(policy.resourceCode))) {
651
+ diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_POLICY_RESOURCE_REQUIRED', 'data policy 必须声明唯一目标 resourceCode', `authz.dataPolicies[${index}].resourceCode`));
652
+ }
614
653
  if (policy.unrestrictedRoleCodes !== undefined) {
615
654
  const unrestrictedRoleCodes = Array.isArray(policy.unrestrictedRoleCodes)
616
655
  ? policy.unrestrictedRoleCodes
@@ -683,6 +722,12 @@ export function validateAppConfig(value) {
683
722
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_DATA_POLICY_NOT_FOUND', `DataResource 引用了未声明的数据策略: ${policyCode}`, `data.resources[${index}].dataPolicyCode`));
684
723
  }
685
724
  });
725
+ diagnostics.push(...validateAuthzSemanticBindings({
726
+ resources: dataResources,
727
+ dimensions,
728
+ scopeSources,
729
+ policies,
730
+ }));
686
731
  validateAuthorizationTransitions(authz.authorizationTransitions, roleCodes, diagnostics);
687
732
  }
688
733
  validateCapabilityClosure(appCode, config, declaredCapabilities, diagnostics);
@@ -1288,14 +1333,29 @@ export function currentUserDataPolicy(input) {
1288
1333
  }
1289
1334
  export function materializeDataResource(appCode, declaration) {
1290
1335
  const capabilities = resourceCapabilityCodes(appCode, declaration.code);
1291
- const fields = declaration.fields.map(field => ({
1292
- code: field.code,
1293
- type: field.type,
1294
- nullable: field.required !== true,
1295
- ...(field.indexed !== undefined ? { indexed: field.indexed } : {}),
1296
- ...(field.reference ? { reference: field.reference } : {}),
1297
- ...(field.file ? { file: field.file } : {}),
1298
- }));
1336
+ const fields = declaration.fields.map(field => {
1337
+ const definition = {
1338
+ code: field.code,
1339
+ type: field.type,
1340
+ nullable: fieldNullable({
1341
+ type: field.type,
1342
+ nullable: field.required !== true,
1343
+ }),
1344
+ indexed: field.indexed ??
1345
+ Boolean(field.filter || field.searchable || field.sortable),
1346
+ ...(field.options ? { options: field.options } : {}),
1347
+ ...(field.source ? { source: field.source } : {}),
1348
+ ...(field.maxLength !== undefined ? { maxLength: field.maxLength } : {}),
1349
+ ...(field.precision !== undefined ? { precision: field.precision } : {}),
1350
+ ...(field.scale !== undefined ? { scale: field.scale } : {}),
1351
+ ...(field.timePrecision ? { timePrecision: field.timePrecision } : {}),
1352
+ ...(field.file ? { file: field.file } : {}),
1353
+ ...(field.serial ? { serial: field.serial } : {}),
1354
+ ...(field.subtable ? { subtable: field.subtable } : {}),
1355
+ };
1356
+ physicalPlanForField(definition, field.searchable === true);
1357
+ return definition;
1358
+ });
1299
1359
  const visible = declaration.fields
1300
1360
  .filter(field => field.list !== false)
1301
1361
  .slice(0, 8);
@@ -1306,6 +1366,8 @@ export function materializeDataResource(appCode, declaration) {
1306
1366
  .filter(field => field.filter === true)
1307
1367
  .map(field => field.code);
1308
1368
  const access = (field, operation) => {
1369
+ if (isGeneratedField(field.type) && operation !== 'read')
1370
+ return [];
1309
1371
  const override = field.access?.[operation];
1310
1372
  if (override === false)
1311
1373
  return [];
@@ -1319,6 +1381,7 @@ export function materializeDataResource(appCode, declaration) {
1319
1381
  field.code,
1320
1382
  {
1321
1383
  label: field.label,
1384
+ type: field.type,
1322
1385
  widget: resolveDataFieldSurfaceWidget(field),
1323
1386
  ...(field.section ? { section: field.section } : {}),
1324
1387
  ...(field.required === true ? { requiredHint: true } : {}),
@@ -1326,16 +1389,21 @@ export function materializeDataResource(appCode, declaration) {
1326
1389
  readCapabilities: access(field, 'read'),
1327
1390
  createCapabilities: access(field, 'create'),
1328
1391
  updateCapabilities: access(field, 'update'),
1329
- ...(field.reference?.multiple !== undefined
1330
- ? { multiple: field.reference.multiple }
1331
- : field.file?.multiple !== undefined
1332
- ? { multiple: field.file.multiple }
1333
- : {}),
1392
+ ...(field.maxLength !== undefined ? { maxLength: field.maxLength } : {}),
1393
+ ...(field.precision !== undefined ? { precision: field.precision } : {}),
1394
+ ...(field.scale !== undefined ? { scale: field.scale } : {}),
1334
1395
  ...(field.file?.maxCount !== undefined
1335
1396
  ? { maxCount: field.file.maxCount }
1336
1397
  : {}),
1398
+ ...(field.file?.maxSizeMb !== undefined
1399
+ ? { maxSizeMb: field.file.maxSizeMb }
1400
+ : {}),
1337
1401
  ...(field.file?.accept ? { accept: field.file.accept } : {}),
1338
1402
  ...(field.options ? { options: field.options } : {}),
1403
+ ...(field.source ? { source: field.source } : {}),
1404
+ ...(field.timePrecision ? { timePrecision: field.timePrecision } : {}),
1405
+ ...(field.serial ? { serial: field.serial } : {}),
1406
+ ...(field.subtable ? { subtable: field.subtable } : {}),
1339
1407
  ...(visible.some(item => item.code === field.code)
1340
1408
  ? { list: true }
1341
1409
  : { list: false }),
@@ -1343,7 +1411,6 @@ export function materializeDataResource(appCode, declaration) {
1343
1411
  ? { searchable: field.searchable }
1344
1412
  : {}),
1345
1413
  ...(field.sortable !== undefined ? { sortable: field.sortable } : {}),
1346
- ...(field.reference ? { reference: field.reference } : {}),
1347
1414
  },
1348
1415
  ])),
1349
1416
  list: {
@@ -1404,8 +1471,15 @@ export function validateAppDeclaration(value) {
1404
1471
  'label',
1405
1472
  'required',
1406
1473
  'indexed',
1407
- 'reference',
1474
+ 'options',
1475
+ 'source',
1476
+ 'maxLength',
1477
+ 'precision',
1478
+ 'scale',
1479
+ 'timePrecision',
1408
1480
  'file',
1481
+ 'serial',
1482
+ 'subtable',
1409
1483
  'widget',
1410
1484
  'section',
1411
1485
  'system',
@@ -1413,7 +1487,6 @@ export function validateAppDeclaration(value) {
1413
1487
  'filter',
1414
1488
  'searchable',
1415
1489
  'sortable',
1416
- 'options',
1417
1490
  'access',
1418
1491
  ]);
1419
1492
  resources.forEach((rawResource, resourceIndex) => {
@@ -1443,7 +1516,34 @@ export function validateAppDeclaration(value) {
1443
1516
  const fieldType = string(field.type);
1444
1517
  if (!APP_DATA_FIELD_TYPES.has(fieldType)) {
1445
1518
  materializable = false;
1446
- diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_TYPE_INVALID', `${fieldPath}.type 必须是 string、text、integer、decimal、boolean、date、datetime、uuid、json file`, `${fieldPath}.type`, '数字字段使用 integer 或 decimal,不存在 number 类型'));
1519
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_TYPE_INVALID', `${fieldPath}.type 必须是 OpenXiangda 2.0 语义字段类型之一: ${DATA_FIELD_TYPES.join('、')}`, `${fieldPath}.type`, '直接声明业务语义类型,不声明 PostgreSQL 物理类型'));
1520
+ }
1521
+ else {
1522
+ const semanticType = fieldType;
1523
+ const widget = string(field.widget);
1524
+ if (widget && !isCompatibleFieldWidget({ type: semanticType, widget })) {
1525
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_WIDGET_INCOMPATIBLE', `${fieldPath}.widget 与 ${semanticType} 不兼容;允许 ${compatibleWidgets(semanticType).join('、')}`, `${fieldPath}.widget`));
1526
+ }
1527
+ if (field.filter === true && !supportsFilter(semanticType)) {
1528
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_FILTER_UNSUPPORTED', `${semanticType} 不支持作为父资源筛选字段`, `${fieldPath}.filter`));
1529
+ }
1530
+ if (field.searchable === true && !supportsSearch(semanticType)) {
1531
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_SEARCH_UNSUPPORTED', `${semanticType} 没有全文/模糊搜索和 trigram 索引计划`, `${fieldPath}.searchable`));
1532
+ }
1533
+ if (field.sortable === true && !supportsSort(semanticType)) {
1534
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_SORT_UNSUPPORTED', `${semanticType} 不支持稳定排序`, `${fieldPath}.sortable`));
1535
+ }
1536
+ if (field.indexed === false &&
1537
+ (field.filter === true ||
1538
+ field.searchable === true ||
1539
+ field.sortable === true)) {
1540
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_INDEX_REQUIRED', '启用筛选、搜索或排序时不能显式关闭索引', `${fieldPath}.indexed`));
1541
+ }
1542
+ if (['radio', 'checkbox'].includes(widget) &&
1543
+ object(field.source).loadMode !== 'all' &&
1544
+ field.source !== undefined) {
1545
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_SOURCE_LOAD_MODE_INVALID', '动态 Radio/Checkbox 必须声明 source.loadMode = all', `${fieldPath}.source.loadMode`));
1546
+ }
1447
1547
  }
1448
1548
  if (!string(field.label)) {
1449
1549
  diagnostics.push(diagnostic('APP_CONFIG_DATA_FIELD_LABEL_REQUIRED', '字段必须同时声明中文或业务 label', `${fieldPath}.label`));
@@ -1493,6 +1593,63 @@ export function validateAppDeclaration(value) {
1493
1593
  })));
1494
1594
  }
1495
1595
  });
1596
+ const declaredResources = new Map(resources.map((rawResource, resourceIndex) => {
1597
+ const resource = object(rawResource);
1598
+ return [
1599
+ string(resource.code),
1600
+ {
1601
+ resource,
1602
+ resourceIndex,
1603
+ fields: new Map((Array.isArray(resource.fields) ? resource.fields : []).map(rawField => {
1604
+ const field = object(rawField);
1605
+ return [string(field.code), field];
1606
+ })),
1607
+ },
1608
+ ];
1609
+ }));
1610
+ for (const [resourceCode, declaration] of declaredResources) {
1611
+ const fields = Array.isArray(declaration.resource.fields)
1612
+ ? declaration.resource.fields
1613
+ : [];
1614
+ const aggregateMaxRows = fields.reduce((total, rawField) => {
1615
+ const field = object(rawField);
1616
+ if (field.type !== 'subtable')
1617
+ return total;
1618
+ const configured = Number(object(field.subtable).maxRows);
1619
+ return total + (Number.isSafeInteger(configured) ? configured : 20);
1620
+ }, 0);
1621
+ if (aggregateMaxRows > 49) {
1622
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_SUBTABLE_AGGREGATE_MAX_ROWS_EXCEEDED', '同一父资源的所有子表 maxRows 总和不能超过 49', `data.resources[${declaration.resourceIndex}].fields`));
1623
+ }
1624
+ fields.forEach((rawField, fieldIndex) => {
1625
+ const field = object(rawField);
1626
+ if (field.type !== 'subtable')
1627
+ return;
1628
+ const path = `data.resources[${declaration.resourceIndex}].fields[${fieldIndex}].subtable`;
1629
+ const subtable = object(field.subtable);
1630
+ const targetCode = string(subtable.resourceCode);
1631
+ const target = declaredResources.get(targetCode);
1632
+ if (!target || targetCode === resourceCode) {
1633
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_SUBTABLE_TARGET_INVALID', '子表必须引用同一应用内不同的子资源', `${path}.resourceCode`));
1634
+ return;
1635
+ }
1636
+ const foreignKey = target.fields.get(string(subtable.foreignKey));
1637
+ if (!foreignKey ||
1638
+ foreignKey.type !== 'uuid' ||
1639
+ foreignKey.required !== true ||
1640
+ object(foreignKey.access).create === false) {
1641
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_SUBTABLE_FOREIGN_KEY_INVALID', '子表外键必须是子资源中可创建写入的必填 uuid 字段', `${path}.foreignKey`));
1642
+ }
1643
+ const orderField = target.fields.get(string(subtable.orderField));
1644
+ if (!orderField ||
1645
+ orderField.type !== 'number.integer' ||
1646
+ orderField.required !== true ||
1647
+ object(orderField.access).create === false ||
1648
+ object(orderField.access).update === false) {
1649
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_SUBTABLE_ORDER_FIELD_INVALID', '子表排序字段必须是子资源中可创建和更新的必填 number.integer 字段', `${path}.orderField`));
1650
+ }
1651
+ });
1652
+ }
1496
1653
  return diagnostics;
1497
1654
  }
1498
1655
  export function defineOpenXiangdaApp(declaration) {