openxiangda-devkit-core 2.0.0-alpha.81 → 2.0.0-alpha.84
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/compiler/authorization-transition.d.ts +7 -0
- package/dist/compiler/authorization-transition.d.ts.map +1 -0
- package/dist/compiler/authorization-transition.js +27 -0
- package/dist/compiler/authorization-transition.js.map +1 -0
- package/dist/compiler/bundle.d.ts +1 -1
- package/dist/compiler/bundle.d.ts.map +1 -1
- package/dist/compiler/bundle.js +59 -13
- package/dist/compiler/bundle.js.map +1 -1
- package/dist/compiler/config.d.ts +36 -1
- package/dist/compiler/config.d.ts.map +1 -1
- package/dist/compiler/config.js +75 -15
- package/dist/compiler/config.js.map +1 -1
- package/dist/compiler/package-compiler.d.ts.map +1 -1
- package/dist/compiler/package-compiler.js +15 -7
- package/dist/compiler/package-compiler.js.map +1 -1
- package/dist/workspace-loader.d.ts.map +1 -1
- package/dist/workspace-loader.js +12 -1
- package/dist/workspace-loader.js.map +1 -1
- package/package.json +2 -2
package/dist/compiler/config.js
CHANGED
|
@@ -7,6 +7,7 @@ import { physicalPlanForField } from './field-physical-plan.js';
|
|
|
7
7
|
import { SEMANTIC_FIELD_PATH_PATTERN, semanticFieldPathRoot, validateAuthzSemanticBindings, } from './field-policy-path.js';
|
|
8
8
|
import { compatibleWidgets, isCompatibleFieldWidget, resolveDataFieldSurfaceWidget, } from './field-surface.js';
|
|
9
9
|
import { DATA_POLICY_EXPRESSION_MAX_DEPTH, DATA_POLICY_EXPRESSION_MAX_GROUP_ITEMS, DATA_POLICY_EXPRESSION_MAX_LEAVES, dataPolicyExpressionToCnf, } from './data-policy-expression.js';
|
|
10
|
+
import { AUTHORIZATION_TRANSITION_CAPABILITY_CODE_PATTERN, AUTHORIZATION_TRANSITION_KEYS, AUTHORIZATION_TRANSITION_ROLE_CODE_PATTERN, exactKeys, isExactStringArray, isPlainRecord, } from './authorization-transition.js';
|
|
10
11
|
// The compiler owns the application source contract. Devkit and every adapter
|
|
11
12
|
// re-export this module instead of maintaining separate configuration models.
|
|
12
13
|
import { validateWorkflowBinding, validateWorkflowDefinition, } from '../internal/workflow.js';
|
|
@@ -269,6 +270,43 @@ const relationshipGrantSourceInputSchema = {
|
|
|
269
270
|
...authorizationProjectionControlProperties,
|
|
270
271
|
},
|
|
271
272
|
};
|
|
273
|
+
const authorizationTransitionInputSchema = {
|
|
274
|
+
type: 'object',
|
|
275
|
+
additionalProperties: false,
|
|
276
|
+
required: ['fromAuthzDigest', 'reason'],
|
|
277
|
+
properties: {
|
|
278
|
+
fromAuthzDigest: {
|
|
279
|
+
type: 'string',
|
|
280
|
+
pattern: '^[0-9a-f]{64}$',
|
|
281
|
+
},
|
|
282
|
+
removeRoleCodes: {
|
|
283
|
+
type: 'array',
|
|
284
|
+
maxItems: 2000,
|
|
285
|
+
uniqueItems: true,
|
|
286
|
+
items: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
pattern: '^[a-z][a-z0-9]*(?:[-_.][a-z0-9]+)*$',
|
|
289
|
+
maxLength: 128,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
removeCapabilityCodes: {
|
|
293
|
+
type: 'array',
|
|
294
|
+
maxItems: 2000,
|
|
295
|
+
uniqueItems: true,
|
|
296
|
+
items: {
|
|
297
|
+
type: 'string',
|
|
298
|
+
pattern: '^[A-Za-z*][A-Za-z0-9:._*-]{0,254}$',
|
|
299
|
+
maxLength: 255,
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
reason: {
|
|
303
|
+
type: 'string',
|
|
304
|
+
minLength: 1,
|
|
305
|
+
maxLength: 2000,
|
|
306
|
+
pattern: '\\S',
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
};
|
|
272
310
|
export const openXiangdaAppConfigSchema = {
|
|
273
311
|
$id: 'openxiangda.app-config/v3',
|
|
274
312
|
type: 'object',
|
|
@@ -443,7 +481,7 @@ export const openXiangdaAppConfigSchema = {
|
|
|
443
481
|
authorizationTransitions: {
|
|
444
482
|
type: 'array',
|
|
445
483
|
maxItems: 100,
|
|
446
|
-
items:
|
|
484
|
+
items: authorizationTransitionInputSchema,
|
|
447
485
|
},
|
|
448
486
|
},
|
|
449
487
|
},
|
|
@@ -1625,6 +1663,16 @@ export function validateAppConfig(value) {
|
|
|
1625
1663
|
referencedFields.forEach(field => captured.add(field));
|
|
1626
1664
|
captureFieldsByResource.set(resourceCode, captured);
|
|
1627
1665
|
}
|
|
1666
|
+
if (subscription.platformAccess !== undefined) {
|
|
1667
|
+
const access = object(subscription.platformAccess);
|
|
1668
|
+
const notification = object(access.notification);
|
|
1669
|
+
if (Object.keys(access).some(key => key !== 'notification') ||
|
|
1670
|
+
access.notification === undefined ||
|
|
1671
|
+
notification.mode !== 'business-standard' ||
|
|
1672
|
+
Object.keys(notification).some(key => key !== 'mode')) {
|
|
1673
|
+
diagnostics.push(diagnostic('APP_CONFIG_EVENT_PLATFORM_ACCESS_INVALID', '事件订阅 platformAccess 只能显式声明标准业务通知依赖', `${path}.platformAccess`));
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1628
1676
|
const delivery = {
|
|
1629
1677
|
timeoutMs: 10_000,
|
|
1630
1678
|
maxAttempts: 8,
|
|
@@ -2724,23 +2772,35 @@ function validateAuthorizationTransitions(rawTransitions, _roleCodes, diagnostic
|
|
|
2724
2772
|
}
|
|
2725
2773
|
const digests = new Set();
|
|
2726
2774
|
(Array.isArray(rawTransitions) ? rawTransitions : []).forEach((raw, index) => {
|
|
2727
|
-
const transition = object(raw);
|
|
2728
|
-
const digest = string(transition.fromAuthzDigest);
|
|
2729
2775
|
const path = `authz.authorizationTransitions[${index}]`;
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2776
|
+
if (!isPlainRecord(raw)) {
|
|
2777
|
+
diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_TRANSITION_INVALID', '授权 transition 必须是只含 canonical 字段的对象', path));
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
if (!exactKeys(raw, AUTHORIZATION_TRANSITION_KEYS)) {
|
|
2781
|
+
const unknownKey = Object.keys(raw).find(key => !AUTHORIZATION_TRANSITION_KEYS.includes(key));
|
|
2782
|
+
diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_TRANSITION_INVALID', '授权 transition 只允许 fromAuthzDigest、removeRoleCodes、removeCapabilityCodes、reason', unknownKey ? `${path}.${unknownKey}` : path));
|
|
2783
|
+
return;
|
|
2784
|
+
}
|
|
2785
|
+
const transition = raw;
|
|
2786
|
+
const digest = transition.fromAuthzDigest;
|
|
2787
|
+
const removeRolesValid = transition.removeRoleCodes === undefined ||
|
|
2788
|
+
isExactStringArray(transition.removeRoleCodes, AUTHORIZATION_TRANSITION_ROLE_CODE_PATTERN, 128);
|
|
2789
|
+
const removeCapabilitiesValid = transition.removeCapabilityCodes === undefined ||
|
|
2790
|
+
isExactStringArray(transition.removeCapabilityCodes, AUTHORIZATION_TRANSITION_CAPABILITY_CODE_PATTERN, 255);
|
|
2791
|
+
if (typeof digest !== 'string' ||
|
|
2792
|
+
!/^[0-9a-f]{64}$/.test(digest) ||
|
|
2737
2793
|
digests.has(digest) ||
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2794
|
+
typeof transition.reason !== 'string' ||
|
|
2795
|
+
!transition.reason.trim() ||
|
|
2796
|
+
transition.reason.length > 2000 ||
|
|
2797
|
+
!removeRolesValid ||
|
|
2798
|
+
!removeCapabilitiesValid) {
|
|
2799
|
+
diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_TRANSITION_INVALID', '授权 transition 必须按来源摘要唯一,并使用有界、不重复的 canonical 移除项和 reason', path));
|
|
2800
|
+
}
|
|
2801
|
+
if (typeof digest === 'string' && /^[0-9a-f]{64}$/.test(digest)) {
|
|
2802
|
+
digests.add(digest);
|
|
2742
2803
|
}
|
|
2743
|
-
digests.add(digest);
|
|
2744
2804
|
});
|
|
2745
2805
|
}
|
|
2746
2806
|
function validateCapabilityClosure(appCode, config, declarations, diagnostics) {
|