openxiangda-contracts 2.11.0 → 2.12.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/native-compiler/compiler.js +211 -8
- package/dist/native-compiler/compiler.js.map +1 -1
- package/dist/native-compiler/index.cjs +3 -3
- package/dist/native-compiler/index.js +3 -3
- package/dist/native.d.ts +35 -1
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/schemas.d.ts +532 -40
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +87 -5
- package/dist/schemas.js.map +1 -1
- package/package.json +1 -1
|
@@ -1632,6 +1632,8 @@ const ANONYMOUS_PUBLIC_OPERATIONS = new Set([
|
|
|
1632
1632
|
'create',
|
|
1633
1633
|
'own.list',
|
|
1634
1634
|
'own.read',
|
|
1635
|
+
'public.list',
|
|
1636
|
+
'public.read',
|
|
1635
1637
|
]);
|
|
1636
1638
|
function validateAnonymousPublicAccess(value, config, pointer) {
|
|
1637
1639
|
const access = object(value, pointer);
|
|
@@ -1645,19 +1647,26 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1645
1647
|
resource,
|
|
1646
1648
|
]));
|
|
1647
1649
|
const policyCodes = new Set();
|
|
1648
|
-
const
|
|
1650
|
+
const declaredPolicyCodes = new Set(policies.map((rawPolicy) => String(rawPolicy?.code || '')));
|
|
1649
1651
|
policies.forEach((rawPolicy, index) => {
|
|
1650
1652
|
const policyPointer = `${pointer}/policies/${index}`;
|
|
1651
1653
|
const policy = object(rawPolicy, policyPointer);
|
|
1652
|
-
exactKeys(policy, ['code', 'routeCode', 'mode', 'resourceCode', 'operations', 'fields'], policyPointer, [
|
|
1654
|
+
exactKeys(policy, ['code', 'routeCode', 'mode', 'resourceCode', 'operations', 'fields'], policyPointer, [
|
|
1655
|
+
'requiredFields',
|
|
1656
|
+
'ownRecordFields',
|
|
1657
|
+
'publicRecordFields',
|
|
1658
|
+
'publicFilters',
|
|
1659
|
+
'serverGeneratedFields',
|
|
1660
|
+
'schedule',
|
|
1661
|
+
'publicSubtableFields',
|
|
1662
|
+
'draft',
|
|
1663
|
+
'validations',
|
|
1664
|
+
]);
|
|
1653
1665
|
const code = stableCode(policy.code, `${policyPointer}/code`);
|
|
1654
1666
|
if (policyCodes.has(code)) {
|
|
1655
1667
|
fail('NATIVE_PUBLIC_POLICY_DUPLICATE', `${policyPointer}/code`);
|
|
1656
1668
|
}
|
|
1657
1669
|
const routeCode = stableCode(policy.routeCode, `${policyPointer}/routeCode`);
|
|
1658
|
-
if (routeCodes.has(routeCode)) {
|
|
1659
|
-
fail('NATIVE_PUBLIC_ROUTE_DUPLICATE', `${policyPointer}/routeCode`);
|
|
1660
|
-
}
|
|
1661
1670
|
const route = routes.get(routeCode);
|
|
1662
1671
|
if (!route ||
|
|
1663
1672
|
route.surface !== 'user' ||
|
|
@@ -1676,7 +1685,7 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1676
1685
|
String(field.code),
|
|
1677
1686
|
String(field.type),
|
|
1678
1687
|
]));
|
|
1679
|
-
const operations = uniqueStrings(policy.operations, `${policyPointer}/operations`,
|
|
1688
|
+
const operations = uniqueStrings(policy.operations, `${policyPointer}/operations`, 8);
|
|
1680
1689
|
if (operations.length < 1 ||
|
|
1681
1690
|
operations.some(operation => !ANONYMOUS_PUBLIC_OPERATIONS.has(operation))) {
|
|
1682
1691
|
fail('NATIVE_PUBLIC_OPERATION_INVALID', `${policyPointer}/operations`);
|
|
@@ -1688,7 +1697,11 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1688
1697
|
if (fields.length < 1 || fields.some(field => !declaredFields.has(field))) {
|
|
1689
1698
|
fail('NATIVE_PUBLIC_FIELD_INVALID', `${policyPointer}/fields`);
|
|
1690
1699
|
}
|
|
1691
|
-
for (const optionalFieldSet of [
|
|
1700
|
+
for (const optionalFieldSet of [
|
|
1701
|
+
'requiredFields',
|
|
1702
|
+
'ownRecordFields',
|
|
1703
|
+
'publicRecordFields',
|
|
1704
|
+
]) {
|
|
1692
1705
|
if (!Object.prototype.hasOwnProperty.call(policy, optionalFieldSet))
|
|
1693
1706
|
continue;
|
|
1694
1707
|
const selected = uniqueStrings(policy[optionalFieldSet], `${policyPointer}/${optionalFieldSet}`, 64);
|
|
@@ -1696,6 +1709,137 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1696
1709
|
fail('NATIVE_PUBLIC_FIELD_SCOPE_INVALID', `${policyPointer}/${optionalFieldSet}`);
|
|
1697
1710
|
}
|
|
1698
1711
|
}
|
|
1712
|
+
const serverGeneratedFields = Object.prototype.hasOwnProperty.call(policy, 'serverGeneratedFields')
|
|
1713
|
+
? boundedArray(policy.serverGeneratedFields, `${policyPointer}/serverGeneratedFields`, 16)
|
|
1714
|
+
: [];
|
|
1715
|
+
const generatedFieldCodes = new Set();
|
|
1716
|
+
serverGeneratedFields.forEach((rawGenerated, generatedIndex) => {
|
|
1717
|
+
const generatedPointer = `${policyPointer}/serverGeneratedFields/${generatedIndex}`;
|
|
1718
|
+
const generated = object(rawGenerated, generatedPointer);
|
|
1719
|
+
exactKeys(generated, ['field', 'kind'], generatedPointer);
|
|
1720
|
+
const field = fieldCodeValue(generated.field, `${generatedPointer}/field`);
|
|
1721
|
+
if (generatedFieldCodes.has(field) ||
|
|
1722
|
+
!declaredFields.has(field) ||
|
|
1723
|
+
fields.includes(field) ||
|
|
1724
|
+
(declaredFields.get(field) !== 'text.short' &&
|
|
1725
|
+
declaredFields.get(field) !== 'text.long')) {
|
|
1726
|
+
fail('NATIVE_PUBLIC_SERVER_GENERATED_FIELD_INVALID', `${generatedPointer}/field`);
|
|
1727
|
+
}
|
|
1728
|
+
equal(generated.kind, 'random-token', `${generatedPointer}/kind`);
|
|
1729
|
+
generatedFieldCodes.add(field);
|
|
1730
|
+
});
|
|
1731
|
+
const schedule = Object.prototype.hasOwnProperty.call(policy, 'schedule')
|
|
1732
|
+
? object(policy.schedule, `${policyPointer}/schedule`)
|
|
1733
|
+
: null;
|
|
1734
|
+
if (schedule) {
|
|
1735
|
+
const scheduleKeys = [
|
|
1736
|
+
'campusPolicyCode',
|
|
1737
|
+
'rulePolicyCode',
|
|
1738
|
+
'campusField',
|
|
1739
|
+
'ruleCampusField',
|
|
1740
|
+
'ruleWeekdaysField',
|
|
1741
|
+
'ruleOpenAtField',
|
|
1742
|
+
'ruleCloseAtField',
|
|
1743
|
+
'ruleSlotMinutesField',
|
|
1744
|
+
'ruleAdvanceHoursField',
|
|
1745
|
+
'ruleAdvanceDaysField',
|
|
1746
|
+
'campusEnabledField',
|
|
1747
|
+
'ruleEnabledField',
|
|
1748
|
+
'dateField',
|
|
1749
|
+
'timeField',
|
|
1750
|
+
];
|
|
1751
|
+
exactKeys(schedule, scheduleKeys, `${policyPointer}/schedule`);
|
|
1752
|
+
for (const key of ['campusPolicyCode', 'rulePolicyCode']) {
|
|
1753
|
+
stableCode(schedule[key], `${policyPointer}/schedule/${key}`);
|
|
1754
|
+
}
|
|
1755
|
+
for (const key of scheduleKeys.filter(key => !['campusPolicyCode', 'rulePolicyCode'].includes(key))) {
|
|
1756
|
+
fieldCodeValue(schedule[key], `${policyPointer}/schedule/${key}`);
|
|
1757
|
+
}
|
|
1758
|
+
for (const field of [schedule.campusField, schedule.dateField, schedule.timeField]) {
|
|
1759
|
+
if (!fields.includes(String(field))) {
|
|
1760
|
+
fail('NATIVE_PUBLIC_SCHEDULE_FIELD_INVALID', `${policyPointer}/schedule`);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
if (!declaredPolicyCodes.has(String(schedule.campusPolicyCode)) ||
|
|
1764
|
+
!declaredPolicyCodes.has(String(schedule.rulePolicyCode))) {
|
|
1765
|
+
fail('NATIVE_PUBLIC_SCHEDULE_POLICY_INVALID', `${policyPointer}/schedule`);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
const publicFilters = Object.prototype.hasOwnProperty.call(policy, 'publicFilters')
|
|
1769
|
+
? boundedArray(policy.publicFilters, `${policyPointer}/publicFilters`, 16)
|
|
1770
|
+
: [];
|
|
1771
|
+
const filterFields = new Set();
|
|
1772
|
+
publicFilters.forEach((rawFilter, filterIndex) => {
|
|
1773
|
+
const filterPointer = `${policyPointer}/publicFilters/${filterIndex}`;
|
|
1774
|
+
const filter = object(rawFilter, filterPointer);
|
|
1775
|
+
exactKeys(filter, ['field', 'operator', 'value'], filterPointer);
|
|
1776
|
+
const field = fieldCodeValue(filter.field, `${filterPointer}/field`);
|
|
1777
|
+
if (filterFields.has(field)) {
|
|
1778
|
+
fail('NATIVE_PUBLIC_FILTER_DUPLICATE', `${filterPointer}/field`);
|
|
1779
|
+
}
|
|
1780
|
+
if (!fields.includes(field)) {
|
|
1781
|
+
fail('NATIVE_PUBLIC_FILTER_FIELD_INVALID', `${filterPointer}/field`);
|
|
1782
|
+
}
|
|
1783
|
+
equal(filter.operator, 'eq', `${filterPointer}/operator`);
|
|
1784
|
+
if (![
|
|
1785
|
+
'boolean',
|
|
1786
|
+
'text.short',
|
|
1787
|
+
'text.long',
|
|
1788
|
+
'number.integer',
|
|
1789
|
+
'number.decimal',
|
|
1790
|
+
'date',
|
|
1791
|
+
'time',
|
|
1792
|
+
].includes(declaredFields.get(field) || '')) {
|
|
1793
|
+
fail('NATIVE_PUBLIC_FILTER_FIELD_INVALID', `${filterPointer}/field`);
|
|
1794
|
+
}
|
|
1795
|
+
if (filter.value !== null &&
|
|
1796
|
+
typeof filter.value !== 'string' &&
|
|
1797
|
+
typeof filter.value !== 'number' &&
|
|
1798
|
+
typeof filter.value !== 'boolean') {
|
|
1799
|
+
fail('NATIVE_PUBLIC_FILTER_VALUE_INVALID', `${filterPointer}/value`);
|
|
1800
|
+
}
|
|
1801
|
+
filterFields.add(field);
|
|
1802
|
+
});
|
|
1803
|
+
const publicSubtableFields = Object.prototype.hasOwnProperty.call(policy, 'publicSubtableFields')
|
|
1804
|
+
? object(policy.publicSubtableFields, `${policyPointer}/publicSubtableFields`)
|
|
1805
|
+
: null;
|
|
1806
|
+
if (publicSubtableFields) {
|
|
1807
|
+
if (Object.keys(publicSubtableFields).length > 64) {
|
|
1808
|
+
fail('NATIVE_PUBLIC_SUBTABLE_FIELDS_INVALID', `${policyPointer}/publicSubtableFields`);
|
|
1809
|
+
}
|
|
1810
|
+
for (const [parentFieldCode, rawChildFields] of Object.entries(publicSubtableFields)) {
|
|
1811
|
+
const parentField = resource.schema.fields.find((field) => String(field.code) === parentFieldCode);
|
|
1812
|
+
const childResourceCode = String(parentField?.subtable?.resourceCode || '');
|
|
1813
|
+
const childResource = resources.get(childResourceCode);
|
|
1814
|
+
const childFieldTypes = new Map((childResource?.schema?.fields || []).map((field) => [
|
|
1815
|
+
String(field.code),
|
|
1816
|
+
String(field.type),
|
|
1817
|
+
]));
|
|
1818
|
+
const selected = uniqueStrings(rawChildFields, `${policyPointer}/publicSubtableFields/${parentFieldCode}`, 64);
|
|
1819
|
+
if (!fields.includes(parentFieldCode) ||
|
|
1820
|
+
declaredFields.get(parentFieldCode) !== 'subtable' ||
|
|
1821
|
+
!childResource ||
|
|
1822
|
+
selected.length < 1 ||
|
|
1823
|
+
selected.some(field => !childFieldTypes.has(field)) ||
|
|
1824
|
+
selected.some(field => childFieldTypes.get(field) === 'subtable') ||
|
|
1825
|
+
selected.some(field => childFieldTypes.get(field) === 'signature')) {
|
|
1826
|
+
fail('NATIVE_PUBLIC_SUBTABLE_FIELDS_INVALID', `${policyPointer}/publicSubtableFields/${parentFieldCode}`);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
if (operations.some(operation => operation.startsWith('public.'))) {
|
|
1831
|
+
if (!Object.prototype.hasOwnProperty.call(policy, 'publicRecordFields')) {
|
|
1832
|
+
fail('NATIVE_PUBLIC_RECORD_FIELDS_REQUIRED', `${policyPointer}/publicRecordFields`);
|
|
1833
|
+
}
|
|
1834
|
+
const publicRecordFields = uniqueStrings(policy.publicRecordFields, `${policyPointer}/publicRecordFields`, 64);
|
|
1835
|
+
if (publicRecordFields.length < 1 ||
|
|
1836
|
+
publicRecordFields.some(field => !fields.includes(field)) ||
|
|
1837
|
+
publicRecordFields.some(field => declaredFields.get(field) === 'signature' ||
|
|
1838
|
+
(declaredFields.get(field) === 'subtable' &&
|
|
1839
|
+
!publicSubtableFields?.[field]))) {
|
|
1840
|
+
fail('NATIVE_PUBLIC_RECORD_FIELDS_INVALID', `${policyPointer}/publicRecordFields`);
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1699
1843
|
const requiredFields = Object.prototype.hasOwnProperty.call(policy, 'requiredFields')
|
|
1700
1844
|
? uniqueStrings(policy.requiredFields, `${policyPointer}/requiredFields`, 64)
|
|
1701
1845
|
: [];
|
|
@@ -1709,6 +1853,10 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1709
1853
|
if (operations.includes('create') && !nativeCreate) {
|
|
1710
1854
|
fail('NATIVE_PUBLIC_CREATE_FIELDS_INCOMPLETE', `${policyPointer}/fields`);
|
|
1711
1855
|
}
|
|
1856
|
+
if (operations.includes('create') &&
|
|
1857
|
+
!Object.prototype.hasOwnProperty.call(policy, 'draft')) {
|
|
1858
|
+
fail('NATIVE_PUBLIC_DRAFT_REQUIRED', `${policyPointer}/draft`);
|
|
1859
|
+
}
|
|
1712
1860
|
if (operations.includes('create')) {
|
|
1713
1861
|
for (const fieldCode of requiredCreateFields) {
|
|
1714
1862
|
const missingSet = !fields.includes(fieldCode)
|
|
@@ -1752,7 +1900,6 @@ function validateAnonymousPublicAccess(value, config, pointer) {
|
|
|
1752
1900
|
validationCodes.add(validationCode);
|
|
1753
1901
|
});
|
|
1754
1902
|
policyCodes.add(code);
|
|
1755
|
-
routeCodes.add(routeCode);
|
|
1756
1903
|
});
|
|
1757
1904
|
}
|
|
1758
1905
|
function validateAnonymousPublicAccessContract(value, pointer) {
|
|
@@ -1777,6 +1924,62 @@ function compileAnonymousPublicAccess(config) {
|
|
|
1777
1924
|
...(policy.ownRecordFields
|
|
1778
1925
|
? { ownRecordFields: uniqueSorted(policy.ownRecordFields) }
|
|
1779
1926
|
: {}),
|
|
1927
|
+
...(policy.publicRecordFields
|
|
1928
|
+
? { publicRecordFields: uniqueSorted(policy.publicRecordFields) }
|
|
1929
|
+
: {}),
|
|
1930
|
+
...(policy.publicFilters
|
|
1931
|
+
? {
|
|
1932
|
+
publicFilters: policy.publicFilters
|
|
1933
|
+
.map((filter) => ({
|
|
1934
|
+
field: filter.field,
|
|
1935
|
+
operator: filter.operator,
|
|
1936
|
+
value: filter.value,
|
|
1937
|
+
}))
|
|
1938
|
+
.sort((left, right) => compareText(left.field, right.field)),
|
|
1939
|
+
}
|
|
1940
|
+
: {}),
|
|
1941
|
+
...(policy.publicSubtableFields
|
|
1942
|
+
? {
|
|
1943
|
+
publicSubtableFields: Object.fromEntries(Object.entries(policy.publicSubtableFields)
|
|
1944
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
1945
|
+
.map(([field, childFields]) => [
|
|
1946
|
+
field,
|
|
1947
|
+
uniqueSorted(Array.isArray(childFields)
|
|
1948
|
+
? childFields.map(String)
|
|
1949
|
+
: []),
|
|
1950
|
+
])),
|
|
1951
|
+
}
|
|
1952
|
+
: {}),
|
|
1953
|
+
...(policy.serverGeneratedFields
|
|
1954
|
+
? {
|
|
1955
|
+
serverGeneratedFields: policy.serverGeneratedFields
|
|
1956
|
+
.map((generated) => ({
|
|
1957
|
+
field: generated.field,
|
|
1958
|
+
kind: generated.kind,
|
|
1959
|
+
}))
|
|
1960
|
+
.sort((left, right) => compareText(left.field, right.field)),
|
|
1961
|
+
}
|
|
1962
|
+
: {}),
|
|
1963
|
+
...(policy.schedule
|
|
1964
|
+
? {
|
|
1965
|
+
schedule: {
|
|
1966
|
+
campusPolicyCode: policy.schedule.campusPolicyCode,
|
|
1967
|
+
rulePolicyCode: policy.schedule.rulePolicyCode,
|
|
1968
|
+
campusField: policy.schedule.campusField,
|
|
1969
|
+
ruleCampusField: policy.schedule.ruleCampusField,
|
|
1970
|
+
ruleWeekdaysField: policy.schedule.ruleWeekdaysField,
|
|
1971
|
+
ruleOpenAtField: policy.schedule.ruleOpenAtField,
|
|
1972
|
+
ruleCloseAtField: policy.schedule.ruleCloseAtField,
|
|
1973
|
+
ruleSlotMinutesField: policy.schedule.ruleSlotMinutesField,
|
|
1974
|
+
ruleAdvanceHoursField: policy.schedule.ruleAdvanceHoursField,
|
|
1975
|
+
ruleAdvanceDaysField: policy.schedule.ruleAdvanceDaysField,
|
|
1976
|
+
campusEnabledField: policy.schedule.campusEnabledField,
|
|
1977
|
+
ruleEnabledField: policy.schedule.ruleEnabledField,
|
|
1978
|
+
dateField: policy.schedule.dateField,
|
|
1979
|
+
timeField: policy.schedule.timeField,
|
|
1980
|
+
},
|
|
1981
|
+
}
|
|
1982
|
+
: {}),
|
|
1780
1983
|
...(policy.draft ? { draft: { ...policy.draft } } : {}),
|
|
1781
1984
|
...(policy.validations
|
|
1782
1985
|
? {
|