openxiangda-devkit-core 2.69.1 → 2.71.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/application-services.d.ts.map +1 -1
- package/dist/compiler/bundle.d.ts.map +1 -1
- package/dist/compiler/bundle.js +87 -1
- package/dist/compiler/bundle.js.map +1 -1
- package/dist/compiler/config.d.ts.map +1 -1
- package/dist/compiler/config.js +110 -0
- package/dist/compiler/config.js.map +1 -1
- package/dist/compiler/permission-review.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/compiler/config.js
CHANGED
|
@@ -2911,6 +2911,8 @@ function validateBackendOperations(rawOperations, declaredResources, declaredRes
|
|
|
2911
2911
|
const allowedAccessKeys = new Set([
|
|
2912
2912
|
'directory',
|
|
2913
2913
|
'selectedDepartments',
|
|
2914
|
+
'directoryClasses',
|
|
2915
|
+
'transactionTime',
|
|
2914
2916
|
'managedFiles',
|
|
2915
2917
|
'managedFileCopies',
|
|
2916
2918
|
'notification',
|
|
@@ -2993,6 +2995,21 @@ function validateBackendOperations(rawOperations, declaredResources, declaredRes
|
|
|
2993
2995
|
fields.some(field => !allowedFields.has(string(field))) ||
|
|
2994
2996
|
Object.keys(directory).some(key => !['mode', 'fields'].includes(key));
|
|
2995
2997
|
}
|
|
2998
|
+
if (access.directoryClasses !== undefined) {
|
|
2999
|
+
const classes = object(access.directoryClasses);
|
|
3000
|
+
invalid ||= !isRecord(access.directoryClasses) ||
|
|
3001
|
+
!Number.isSafeInteger(classes.maxIds) ||
|
|
3002
|
+
Number(classes.maxIds) < 1 || Number(classes.maxIds) > 20 ||
|
|
3003
|
+
Object.keys(classes).some(key => key !== 'maxIds');
|
|
3004
|
+
}
|
|
3005
|
+
if (access.transactionTime !== undefined) {
|
|
3006
|
+
const time = object(access.transactionTime);
|
|
3007
|
+
invalid ||= !isRecord(access.transactionTime) ||
|
|
3008
|
+
time.mode !== 'database-accepted' ||
|
|
3009
|
+
object(access.dataCommands).mode !== 'recoverable-native' ||
|
|
3010
|
+
(time.recordSetAssertions !== undefined && time.recordSetAssertions !== true) ||
|
|
3011
|
+
Object.keys(time).some(key => !['mode', 'recordSetAssertions'].includes(key));
|
|
3012
|
+
}
|
|
2996
3013
|
if (access.selectedDepartments !== undefined) {
|
|
2997
3014
|
const departments = object(access.selectedDepartments);
|
|
2998
3015
|
const fields = Array.isArray(departments.fields) ? departments.fields : [];
|
|
@@ -3710,6 +3727,7 @@ const ANONYMOUS_PUBLIC_OPERATIONS = new Set([
|
|
|
3710
3727
|
'own.read',
|
|
3711
3728
|
'public.list',
|
|
3712
3729
|
'public.read',
|
|
3730
|
+
'public.query',
|
|
3713
3731
|
]);
|
|
3714
3732
|
function validateAnonymousPublicAccess(config, diagnostics) {
|
|
3715
3733
|
const frontend = object(config.frontend);
|
|
@@ -3859,6 +3877,90 @@ function validateAnonymousPublicAccess(config, diagnostics) {
|
|
|
3859
3877
|
childFields.some(field => !childResource.fields.has(field)) ||
|
|
3860
3878
|
childFields.some(field => ['signature', 'subtable'].includes(childResource.fields.get(field) || '')));
|
|
3861
3879
|
});
|
|
3880
|
+
const publicQueries = Array.isArray(policy.publicQueries)
|
|
3881
|
+
? policy.publicQueries
|
|
3882
|
+
: [];
|
|
3883
|
+
const publicQueryInvalid = publicQueries.length > 16 ||
|
|
3884
|
+
new Set(publicQueries.map(item => string(object(item).code))).size !== publicQueries.length ||
|
|
3885
|
+
publicQueries.some(rawQuery => {
|
|
3886
|
+
const query = object(rawQuery);
|
|
3887
|
+
const queryFields = Array.isArray(query.fields)
|
|
3888
|
+
? query.fields.map(string)
|
|
3889
|
+
: [];
|
|
3890
|
+
const sort = Array.isArray(query.sort) ? query.sort : [];
|
|
3891
|
+
const parameters = Array.isArray(query.parameters) ? query.parameters : [];
|
|
3892
|
+
const sortFields = sort.map(item => string(object(item).field));
|
|
3893
|
+
const parameterNames = parameters.map(item => string(object(item).name));
|
|
3894
|
+
const aggregate = query.aggregate === undefined ? undefined : object(query.aggregate);
|
|
3895
|
+
const dimensions = aggregate && Array.isArray(aggregate.dimensions) ? aggregate.dimensions : [];
|
|
3896
|
+
const measures = aggregate && Array.isArray(aggregate.measures) ? aggregate.measures : [];
|
|
3897
|
+
const aggregateOrder = aggregate && Array.isArray(aggregate.order) ? aggregate.order : [];
|
|
3898
|
+
const aggregateAliases = [
|
|
3899
|
+
...dimensions.map(item => string(object(item).as)),
|
|
3900
|
+
...measures.map(item => string(object(item).as)),
|
|
3901
|
+
];
|
|
3902
|
+
const aggregateInvalid = query.aggregate !== undefined && (string(query.kind) !== 'aggregate' ||
|
|
3903
|
+
Object.keys(aggregate || {}).some(key => !['dimensions', 'measures', 'order'].includes(key)) ||
|
|
3904
|
+
!Array.isArray(aggregate?.measures) ||
|
|
3905
|
+
dimensions.length > 3 ||
|
|
3906
|
+
measures.length < 1 || measures.length > 8 ||
|
|
3907
|
+
new Set(aggregateAliases).size !== aggregateAliases.length ||
|
|
3908
|
+
aggregateAliases.some(alias => !/^[A-Za-z][A-Za-z0-9_]{0,62}$/.test(alias)) ||
|
|
3909
|
+
dimensions.some(item => {
|
|
3910
|
+
const value = object(item);
|
|
3911
|
+
return Object.keys(value).some(key => !['field', 'as', 'bucket'].includes(key)) ||
|
|
3912
|
+
!queryFields.includes(string(value.field)) ||
|
|
3913
|
+
!['day', 'week', 'month', 'quarter', 'year'].includes(string(value.bucket)) && value.bucket !== undefined;
|
|
3914
|
+
}) ||
|
|
3915
|
+
measures.some(item => {
|
|
3916
|
+
const value = object(item);
|
|
3917
|
+
const type = string(value.type);
|
|
3918
|
+
return Object.keys(value).some(key => !['type', 'field', 'as'].includes(key)) ||
|
|
3919
|
+
!['count', 'countDistinct', 'sum', 'avg', 'min', 'max'].includes(type) ||
|
|
3920
|
+
(type === 'count' ? value.field !== undefined : !queryFields.includes(string(value.field)));
|
|
3921
|
+
}) ||
|
|
3922
|
+
aggregateOrder.length > 10 ||
|
|
3923
|
+
new Set(aggregateOrder.map(item => string(object(item).field))).size !== aggregateOrder.length ||
|
|
3924
|
+
aggregateOrder.some(item => {
|
|
3925
|
+
const value = object(item);
|
|
3926
|
+
return Object.keys(value).some(key => !['field', 'direction', 'nulls'].includes(key)) ||
|
|
3927
|
+
!aggregateAliases.includes(string(value.field)) ||
|
|
3928
|
+
value.direction !== undefined && !['asc', 'desc'].includes(string(value.direction)) ||
|
|
3929
|
+
value.nulls !== undefined && !['first', 'last'].includes(string(value.nulls));
|
|
3930
|
+
}));
|
|
3931
|
+
return (Object.keys(query).some(key => !['code', 'kind', 'resourceCode', 'fields', 'defaultLimit', 'maxLimit', 'sort', 'parameters', 'aggregate'].includes(key)) ||
|
|
3932
|
+
!OPERATION_CODE_PATTERN.test(string(query.code)) ||
|
|
3933
|
+
!['records', 'aggregate'].includes(string(query.kind)) ||
|
|
3934
|
+
string(query.resourceCode) !== resourceCode ||
|
|
3935
|
+
queryFields.length < 1 ||
|
|
3936
|
+
queryFields.length > 64 ||
|
|
3937
|
+
new Set(queryFields).size !== queryFields.length ||
|
|
3938
|
+
queryFields.some(field => !fields.includes(field) || !Array.isArray(policy.publicRecordFields) || !policy.publicRecordFields.map(string).includes(field)) ||
|
|
3939
|
+
!Number.isSafeInteger(query.defaultLimit) ||
|
|
3940
|
+
!Number.isSafeInteger(query.maxLimit) ||
|
|
3941
|
+
Number(query.defaultLimit) < 1 ||
|
|
3942
|
+
Number(query.maxLimit) < Number(query.defaultLimit) ||
|
|
3943
|
+
Number(query.maxLimit) > 100 ||
|
|
3944
|
+
sort.length > 4 ||
|
|
3945
|
+
new Set(sortFields).size !== sortFields.length ||
|
|
3946
|
+
sort.some(item => {
|
|
3947
|
+
const value = object(item);
|
|
3948
|
+
return Object.keys(value).some(key => !['field', 'direction'].includes(key)) ||
|
|
3949
|
+
!queryFields.includes(string(value.field)) ||
|
|
3950
|
+
!['asc', 'desc'].includes(string(value.direction));
|
|
3951
|
+
}) ||
|
|
3952
|
+
parameters.length > 8 ||
|
|
3953
|
+
new Set(parameterNames).size !== parameterNames.length ||
|
|
3954
|
+
parameters.some(item => {
|
|
3955
|
+
const value = object(item);
|
|
3956
|
+
return Object.keys(value).some(key => !['name', 'field', 'operator', 'type'].includes(key)) ||
|
|
3957
|
+
!OPERATION_CODE_PATTERN.test(string(value.name)) ||
|
|
3958
|
+
!queryFields.includes(string(value.field)) ||
|
|
3959
|
+
!['eq', 'contains', 'in'].includes(string(value.operator)) ||
|
|
3960
|
+
!['string', 'number', 'boolean', 'string[]'].includes(string(value.type));
|
|
3961
|
+
}) ||
|
|
3962
|
+
aggregateInvalid);
|
|
3963
|
+
});
|
|
3862
3964
|
const draft = object(policy.draft);
|
|
3863
3965
|
const validations = Array.isArray(policy.validations)
|
|
3864
3966
|
? policy.validations
|
|
@@ -3877,6 +3979,7 @@ function validateAnonymousPublicAccess(config, diagnostics) {
|
|
|
3877
3979
|
'serverGeneratedFields',
|
|
3878
3980
|
'schedule',
|
|
3879
3981
|
'publicSubtableFields',
|
|
3982
|
+
'publicQueries',
|
|
3880
3983
|
'draft',
|
|
3881
3984
|
'validations',
|
|
3882
3985
|
];
|
|
@@ -3979,6 +4082,13 @@ function validateAnonymousPublicAccess(config, diagnostics) {
|
|
|
3979
4082
|
pointer: `${path}.publicSubtableFields`,
|
|
3980
4083
|
});
|
|
3981
4084
|
}
|
|
4085
|
+
if (publicQueryInvalid) {
|
|
4086
|
+
anonymousPolicyProblems.push({
|
|
4087
|
+
code: 'APP_CONFIG_ANONYMOUS_PUBLIC_POLICY_QUERIES_INVALID',
|
|
4088
|
+
message: 'publicQueries 必须是同一资源的有界公开字段查询,limit 不超过 100,参数和排序只能引用查询字段',
|
|
4089
|
+
pointer: path + '.publicQueries',
|
|
4090
|
+
});
|
|
4091
|
+
}
|
|
3982
4092
|
if (publicFilterInvalid) {
|
|
3983
4093
|
anonymousPolicyProblems.push({
|
|
3984
4094
|
code: 'APP_CONFIG_ANONYMOUS_PUBLIC_POLICY_FILTERS_INVALID',
|