@stndrds/schema 0.1.0-alpha.36 → 0.1.0-alpha.38
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/{chunk-JHLPK3RO.js → chunk-5NXIMZNY.js} +279 -129
- package/dist/{chunk-QZZ4SSHD.mjs → chunk-6NQPARLS.mjs} +212 -62
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -6
- package/dist/index.mjs +7 -1
- package/dist/{runtime-BWBRGKY1.d.mts → runtime-Hwgvv9Bn.d.mts} +243 -32
- package/dist/{runtime-BWBRGKY1.d.ts → runtime-Hwgvv9Bn.d.ts} +243 -32
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +8 -2
- package/dist/runtime.mjs +7 -1
- package/package.json +4 -3
|
@@ -2,6 +2,93 @@
|
|
|
2
2
|
|
|
3
3
|
var _chunk3RG5ZIWIjs = require('./chunk-3RG5ZIWI.js');
|
|
4
4
|
|
|
5
|
+
// src/runtime/cache.ts
|
|
6
|
+
var cacheKeys = {
|
|
7
|
+
// -------------------------------------------------------------------------
|
|
8
|
+
// Schemas - TTL: 1 hour (rarely change)
|
|
9
|
+
// -------------------------------------------------------------------------
|
|
10
|
+
/** Object schema by ID */
|
|
11
|
+
objectSchema: (tenantId, objectId) => `schema:${tenantId}:obj:${objectId}`,
|
|
12
|
+
/** Object schema by name */
|
|
13
|
+
objectSchemaByName: (tenantId, name) => `schema:${tenantId}:name:${name}`,
|
|
14
|
+
/** List of all object schemas */
|
|
15
|
+
objectSchemaList: (tenantId) => `schema:${tenantId}:list`,
|
|
16
|
+
// -------------------------------------------------------------------------
|
|
17
|
+
// Attributes - TTL: 1 hour (rarely change)
|
|
18
|
+
// -------------------------------------------------------------------------
|
|
19
|
+
/** Attributes for an object */
|
|
20
|
+
objectAttributes: (tenantId, objectId) => `attrs:${tenantId}:${objectId}`,
|
|
21
|
+
// -------------------------------------------------------------------------
|
|
22
|
+
// Permissions - TTL: 15 minutes (medium volatility)
|
|
23
|
+
// -------------------------------------------------------------------------
|
|
24
|
+
/** Effective permissions for a user */
|
|
25
|
+
userPermissions: (tenantId, userId) => `perms:${tenantId}:user:${userId}`,
|
|
26
|
+
// -------------------------------------------------------------------------
|
|
27
|
+
// Relations - TTL: 5 minutes (medium volatility)
|
|
28
|
+
// -------------------------------------------------------------------------
|
|
29
|
+
/** Relation options for an attribute */
|
|
30
|
+
relationOptions: (tenantId, attrId, hash) => `rel:${tenantId}:${attrId}:${hash}`,
|
|
31
|
+
// -------------------------------------------------------------------------
|
|
32
|
+
// Rollups - TTL: 2 minutes (high volatility)
|
|
33
|
+
// -------------------------------------------------------------------------
|
|
34
|
+
/** Computed rollup value for a record */
|
|
35
|
+
rollupValue: (tenantId, recordId, attrName) => `rollup:${tenantId}:${recordId}:${attrName}`,
|
|
36
|
+
// -------------------------------------------------------------------------
|
|
37
|
+
// Invalidation Patterns
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
39
|
+
/** All schema cache for a tenant */
|
|
40
|
+
allSchemas: (tenantId) => `schema:${tenantId}:*`,
|
|
41
|
+
/** All attribute cache for a tenant */
|
|
42
|
+
allAttributes: (tenantId) => `attrs:${tenantId}:*`,
|
|
43
|
+
/** All permission cache for a tenant */
|
|
44
|
+
allPermissions: (tenantId) => `perms:${tenantId}:*`,
|
|
45
|
+
/** All relation cache for a tenant */
|
|
46
|
+
allRelations: (tenantId) => `rel:${tenantId}:*`,
|
|
47
|
+
/** All rollup cache for a tenant */
|
|
48
|
+
allRollups: (tenantId) => `rollup:${tenantId}:*`,
|
|
49
|
+
/** All rollups for a specific record */
|
|
50
|
+
rollupsByRecord: (tenantId, recordId) => `rollup:${tenantId}:${recordId}:*`,
|
|
51
|
+
/** All cache for a tenant (nuclear option) */
|
|
52
|
+
allForTenant: (tenantId) => `*:${tenantId}:*`
|
|
53
|
+
};
|
|
54
|
+
var cacheTtl = {
|
|
55
|
+
/** Object schemas - rarely change (1 hour) */
|
|
56
|
+
schema: 60 * 60 * 1e3,
|
|
57
|
+
/** Schema list - new objects more frequent (5 minutes) */
|
|
58
|
+
schemaList: 5 * 60 * 1e3,
|
|
59
|
+
/** Object attributes - rarely change (1 hour) */
|
|
60
|
+
attributes: 60 * 60 * 1e3,
|
|
61
|
+
/** User permissions - medium volatility (15 minutes) */
|
|
62
|
+
permissions: 15 * 60 * 1e3,
|
|
63
|
+
/** Relation options - medium volatility (5 minutes) */
|
|
64
|
+
relations: 5 * 60 * 1e3,
|
|
65
|
+
/** Rollup values - high volatility (2 minutes) */
|
|
66
|
+
rollup: 2 * 60 * 1e3
|
|
67
|
+
};
|
|
68
|
+
var NoopCacheAdapter = class {
|
|
69
|
+
get() {
|
|
70
|
+
return Promise.resolve(null);
|
|
71
|
+
}
|
|
72
|
+
set() {
|
|
73
|
+
return Promise.resolve();
|
|
74
|
+
}
|
|
75
|
+
delete() {
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
78
|
+
deletePattern() {
|
|
79
|
+
return Promise.resolve();
|
|
80
|
+
}
|
|
81
|
+
has() {
|
|
82
|
+
return Promise.resolve(false);
|
|
83
|
+
}
|
|
84
|
+
clear() {
|
|
85
|
+
return Promise.resolve();
|
|
86
|
+
}
|
|
87
|
+
getOrSet(_key, fetcher) {
|
|
88
|
+
return fetcher();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
5
92
|
// src/runtime/client/types.ts
|
|
6
93
|
function formatRecord(record) {
|
|
7
94
|
return {
|
|
@@ -1720,7 +1807,6 @@ function createMockObjectRecordsRepository(stores) {
|
|
|
1720
1807
|
const records = results.map(({ tenantId: _t, ...r }) => r);
|
|
1721
1808
|
return Promise.resolve({ records, total });
|
|
1722
1809
|
},
|
|
1723
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This is a mock adapter, we don't need to worry about complexity
|
|
1724
1810
|
globalSearch(query, options) {
|
|
1725
1811
|
const tenantId = getTenantId();
|
|
1726
1812
|
const lowerQuery = query.toLowerCase();
|
|
@@ -1793,7 +1879,6 @@ function createMockObjectRecordsRepository(stores) {
|
|
|
1793
1879
|
// -------------------------------------------------------------------------
|
|
1794
1880
|
// Schema Integrity Methods
|
|
1795
1881
|
// -------------------------------------------------------------------------
|
|
1796
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This is a mock adapter, we don't need to worry about complexity
|
|
1797
1882
|
countRecordsReferencingId(targetId) {
|
|
1798
1883
|
const relationAttrs = [];
|
|
1799
1884
|
for (const attr of stores.attributes.values()) {
|
|
@@ -1870,7 +1955,6 @@ function createMockObjectRecordsRepository(stores) {
|
|
|
1870
1955
|
}
|
|
1871
1956
|
return Promise.resolve(updated);
|
|
1872
1957
|
},
|
|
1873
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This is a mock adapter, we don't need to worry about complexity
|
|
1874
1958
|
findByRelation(objectName, relationAttributeName, targetRecordId) {
|
|
1875
1959
|
const obj = Array.from(stores.objects.values()).find((o) => o.name === objectName);
|
|
1876
1960
|
if (!obj) return Promise.resolve([]);
|
|
@@ -2119,7 +2203,6 @@ function createMockPermissionsRepository(stores) {
|
|
|
2119
2203
|
}
|
|
2120
2204
|
return Promise.resolve();
|
|
2121
2205
|
},
|
|
2122
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This is a mock adapter, we don't need to worry about complexity
|
|
2123
2206
|
getEffectivePermissions(userProfileId) {
|
|
2124
2207
|
const tenantId = getTenantId();
|
|
2125
2208
|
const userRoleIds = Array.from(stores.userRoles.values()).filter((ur) => ur.userProfileId === userProfileId && ur.tenantId === tenantId).map((ur) => ur.roleId);
|
|
@@ -6284,6 +6367,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6284
6367
|
this.adapter = adapter;
|
|
6285
6368
|
this.nativeRegistry = nativeRegistry;
|
|
6286
6369
|
this.auditService = _optionalChain([options, 'optionalAccess', _147 => _147.auditService]);
|
|
6370
|
+
this.cache = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _148 => _148.cache]), () => ( adapter.cache));
|
|
6287
6371
|
}
|
|
6288
6372
|
/**
|
|
6289
6373
|
* Create a new custom object.
|
|
@@ -6359,6 +6443,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6359
6443
|
attributes: createdAttributes,
|
|
6360
6444
|
system: false
|
|
6361
6445
|
};
|
|
6446
|
+
await this.invalidateSchemaCache();
|
|
6362
6447
|
if (this.auditService && this.userId) {
|
|
6363
6448
|
await this.auditService.logSchemaAction({
|
|
6364
6449
|
action: "object.created",
|
|
@@ -6406,6 +6491,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6406
6491
|
// Always false for attributes added via API
|
|
6407
6492
|
config
|
|
6408
6493
|
});
|
|
6494
|
+
await this.invalidateSchemaCache();
|
|
6409
6495
|
if (this.auditService && this.userId) {
|
|
6410
6496
|
await this.auditService.logSchemaAction({
|
|
6411
6497
|
action: "attribute.created",
|
|
@@ -6479,12 +6565,13 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6479
6565
|
resourceType: "attribute",
|
|
6480
6566
|
resourceId: attributeId,
|
|
6481
6567
|
resourceLabel: updatedDbAttr.label,
|
|
6482
|
-
objectName: _optionalChain([dbObject, 'optionalAccess',
|
|
6568
|
+
objectName: _optionalChain([dbObject, 'optionalAccess', _149 => _149.name]),
|
|
6483
6569
|
objectId: dbAttr.objectId,
|
|
6484
6570
|
changes
|
|
6485
6571
|
});
|
|
6486
6572
|
}
|
|
6487
6573
|
}
|
|
6574
|
+
await this.invalidateSchemaCache();
|
|
6488
6575
|
if (updates.required !== void 0 && updates.required !== oldValues.required) {
|
|
6489
6576
|
const schema = await this.getObjectSchema(dbAttr.objectId);
|
|
6490
6577
|
await this.adapter.objectRecords.batchRefreshStatus(
|
|
@@ -6511,7 +6598,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6511
6598
|
);
|
|
6512
6599
|
}
|
|
6513
6600
|
const dbObject = await this.adapter.objects.findById(dbAttr.objectId);
|
|
6514
|
-
if (_optionalChain([dbObject, 'optionalAccess',
|
|
6601
|
+
if (_optionalChain([dbObject, 'optionalAccess', _150 => _150.labelExpression])) {
|
|
6515
6602
|
const usedAttributes = extractAttributeNames(dbObject.labelExpression);
|
|
6516
6603
|
if (usedAttributes.includes(dbAttr.name)) {
|
|
6517
6604
|
throw new AttributeInUseError(dbAttr.name, "labelExpression");
|
|
@@ -6519,6 +6606,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6519
6606
|
}
|
|
6520
6607
|
await this.adapter.attributes.delete(attributeId);
|
|
6521
6608
|
await this.adapter.objectRecords.removeAttributeData(dbAttr.objectId, dbAttr.name);
|
|
6609
|
+
await this.invalidateSchemaCache();
|
|
6522
6610
|
if (this.auditService && this.userId) {
|
|
6523
6611
|
await this.auditService.logSchemaAction({
|
|
6524
6612
|
action: "attribute.deleted",
|
|
@@ -6526,7 +6614,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6526
6614
|
resourceType: "attribute",
|
|
6527
6615
|
resourceId: attributeId,
|
|
6528
6616
|
resourceLabel: dbAttr.label,
|
|
6529
|
-
objectName: _optionalChain([dbObject, 'optionalAccess',
|
|
6617
|
+
objectName: _optionalChain([dbObject, 'optionalAccess', _151 => _151.name]),
|
|
6530
6618
|
objectId: dbAttr.objectId
|
|
6531
6619
|
});
|
|
6532
6620
|
}
|
|
@@ -6541,9 +6629,9 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6541
6629
|
async listAttributes(objectId, options) {
|
|
6542
6630
|
const dbAttributes = await this.adapter.attributes.findByObjectId(objectId);
|
|
6543
6631
|
let filtered = dbAttributes;
|
|
6544
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
6632
|
+
if (_optionalChain([options, 'optionalAccess', _152 => _152.systemOnly])) {
|
|
6545
6633
|
filtered = dbAttributes.filter((attr) => attr.system);
|
|
6546
|
-
} else if (_optionalChain([options, 'optionalAccess',
|
|
6634
|
+
} else if (_optionalChain([options, 'optionalAccess', _153 => _153.customOnly])) {
|
|
6547
6635
|
filtered = dbAttributes.filter((attr) => !attr.system);
|
|
6548
6636
|
}
|
|
6549
6637
|
return filtered.map((attr) => this.convertDBAttributeToAttribute(attr));
|
|
@@ -6579,14 +6667,14 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6579
6667
|
pluralLabel: dbObject.pluralLabel,
|
|
6580
6668
|
description: dbObject.description,
|
|
6581
6669
|
labelExpression: dbObject.labelExpression,
|
|
6582
|
-
icon: _optionalChain([dbObject, 'access',
|
|
6670
|
+
icon: _optionalChain([dbObject, 'access', _154 => _154.metadata, 'optionalAccess', _155 => _155.icon])
|
|
6583
6671
|
};
|
|
6584
6672
|
let metadata = dbObject.metadata;
|
|
6585
6673
|
if (updates.icon !== void 0 || updates.metadata !== void 0) {
|
|
6586
6674
|
metadata = {
|
|
6587
6675
|
...dbObject.metadata,
|
|
6588
6676
|
...updates.metadata,
|
|
6589
|
-
icon: _nullishCoalesce(updates.icon, () => ( _optionalChain([dbObject, 'access',
|
|
6677
|
+
icon: _nullishCoalesce(updates.icon, () => ( _optionalChain([dbObject, 'access', _156 => _156.metadata, 'optionalAccess', _157 => _157.icon])))
|
|
6590
6678
|
};
|
|
6591
6679
|
}
|
|
6592
6680
|
const updatedDbObject = await this.adapter.objects.update(objectId, {
|
|
@@ -6619,6 +6707,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6619
6707
|
}
|
|
6620
6708
|
const dbAttributes = await this.adapter.attributes.findByObjectId(objectId);
|
|
6621
6709
|
const attributes = dbAttributes.map((attr) => this.convertDBAttributeToAttribute(attr));
|
|
6710
|
+
await this.invalidateSchemaCache();
|
|
6622
6711
|
if (updates.labelExpression !== void 0 && updates.labelExpression !== oldValues.labelExpression) {
|
|
6623
6712
|
const newExpression = updates.labelExpression;
|
|
6624
6713
|
await this.adapter.objectRecords.batchRefreshLabels(objectId, (values) => {
|
|
@@ -6656,6 +6745,7 @@ var ObjectSchemaService = class extends TenantAwareService {
|
|
|
6656
6745
|
throw new ObjectReferencedError(dbObject.name, referencingObjects);
|
|
6657
6746
|
}
|
|
6658
6747
|
await this.adapter.objects.delete(objectId);
|
|
6748
|
+
await this.invalidateSchemaCache();
|
|
6659
6749
|
if (this.auditService && this.userId) {
|
|
6660
6750
|
await this.auditService.logSchemaAction({
|
|
6661
6751
|
action: "object.deleted",
|
|
@@ -6699,10 +6789,26 @@ Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
|
6699
6789
|
* Get complete object schema (object attributes + system attributes)
|
|
6700
6790
|
* Includes system attributes (createdAt, updatedAt, createdBy, lastUpdatedBy)
|
|
6701
6791
|
*
|
|
6792
|
+
* Results are cached if a CacheAdapter is configured.
|
|
6793
|
+
*
|
|
6702
6794
|
* @param objectId - Object UUID from database
|
|
6703
6795
|
* @returns Complete ObjectDefinition with all attributes including system attributes
|
|
6704
6796
|
*/
|
|
6705
6797
|
async getObjectSchema(objectId) {
|
|
6798
|
+
if (this.cache) {
|
|
6799
|
+
const cacheKey = cacheKeys.objectSchema(this.tenantId, objectId);
|
|
6800
|
+
return this.cache.getOrSet(
|
|
6801
|
+
cacheKey,
|
|
6802
|
+
() => this.fetchObjectSchemaById(objectId),
|
|
6803
|
+
cacheTtl.schema
|
|
6804
|
+
);
|
|
6805
|
+
}
|
|
6806
|
+
return this.fetchObjectSchemaById(objectId);
|
|
6807
|
+
}
|
|
6808
|
+
/**
|
|
6809
|
+
* Internal method to fetch object schema by ID (no caching)
|
|
6810
|
+
*/
|
|
6811
|
+
async fetchObjectSchemaById(objectId) {
|
|
6706
6812
|
const dbObject = await this.adapter.objects.findById(objectId);
|
|
6707
6813
|
if (!dbObject) {
|
|
6708
6814
|
throw new Error(`Object with id "${objectId}" not found`);
|
|
@@ -6723,8 +6829,24 @@ Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
|
6723
6829
|
/**
|
|
6724
6830
|
* Get object schema by name (supports both native and custom objects).
|
|
6725
6831
|
* Automatically uses tenant context from AsyncLocalStorage.
|
|
6832
|
+
*
|
|
6833
|
+
* Results are cached if a CacheAdapter is configured.
|
|
6726
6834
|
*/
|
|
6727
6835
|
async getObjectSchemaByNameForTenant(name) {
|
|
6836
|
+
if (this.cache) {
|
|
6837
|
+
const cacheKey = cacheKeys.objectSchemaByName(this.tenantId, name);
|
|
6838
|
+
return this.cache.getOrSet(
|
|
6839
|
+
cacheKey,
|
|
6840
|
+
() => this.fetchObjectSchemaByName(name),
|
|
6841
|
+
cacheTtl.schema
|
|
6842
|
+
);
|
|
6843
|
+
}
|
|
6844
|
+
return this.fetchObjectSchemaByName(name);
|
|
6845
|
+
}
|
|
6846
|
+
/**
|
|
6847
|
+
* Internal method to fetch object schema by name (no caching)
|
|
6848
|
+
*/
|
|
6849
|
+
async fetchObjectSchemaByName(name) {
|
|
6728
6850
|
let dbObject = await this.adapter.objects.findByName(name);
|
|
6729
6851
|
if (!dbObject) {
|
|
6730
6852
|
dbObject = await this.adapter.objects.findSystemByName(name);
|
|
@@ -6737,11 +6859,32 @@ Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
|
6737
6859
|
/**
|
|
6738
6860
|
* List all object schemas.
|
|
6739
6861
|
* Automatically uses tenant context from AsyncLocalStorage.
|
|
6862
|
+
*
|
|
6863
|
+
* Results are cached if a CacheAdapter is configured.
|
|
6740
6864
|
*/
|
|
6741
6865
|
async listObjectSchemas() {
|
|
6866
|
+
if (this.cache) {
|
|
6867
|
+
const cacheKey = cacheKeys.objectSchemaList(this.tenantId);
|
|
6868
|
+
return this.cache.getOrSet(cacheKey, () => this.fetchObjectSchemaList(), cacheTtl.schemaList);
|
|
6869
|
+
}
|
|
6870
|
+
return this.fetchObjectSchemaList();
|
|
6871
|
+
}
|
|
6872
|
+
/**
|
|
6873
|
+
* Internal method to fetch all object schemas (no caching)
|
|
6874
|
+
*/
|
|
6875
|
+
async fetchObjectSchemaList() {
|
|
6742
6876
|
const dbObjects = await this.adapter.objects.list();
|
|
6743
6877
|
return Promise.all(dbObjects.map((dbObject) => this.buildObjectDefinition(dbObject)));
|
|
6744
6878
|
}
|
|
6879
|
+
/**
|
|
6880
|
+
* Invalidate all schema-related cache for the current tenant.
|
|
6881
|
+
* Called automatically after schema mutations.
|
|
6882
|
+
*/
|
|
6883
|
+
async invalidateSchemaCache() {
|
|
6884
|
+
if (!this.cache) return;
|
|
6885
|
+
await this.cache.deletePattern(cacheKeys.allSchemas(this.tenantId));
|
|
6886
|
+
await this.cache.deletePattern(cacheKeys.allAttributes(this.tenantId));
|
|
6887
|
+
}
|
|
6745
6888
|
// ============================================================================
|
|
6746
6889
|
// PRIVATE HELPERS - SCHEMA BUILDING
|
|
6747
6890
|
// ============================================================================
|
|
@@ -6819,7 +6962,7 @@ Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
|
6819
6962
|
label: dbObject.label,
|
|
6820
6963
|
pluralLabel: dbObject.pluralLabel,
|
|
6821
6964
|
description: dbObject.description,
|
|
6822
|
-
icon: _optionalChain([dbObject, 'access',
|
|
6965
|
+
icon: _optionalChain([dbObject, 'access', _158 => _158.metadata, 'optionalAccess', _159 => _159.icon]),
|
|
6823
6966
|
labelExpression: dbObject.labelExpression,
|
|
6824
6967
|
attributes,
|
|
6825
6968
|
system: dbObject.system,
|
|
@@ -6919,7 +7062,7 @@ Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
|
6919
7062
|
const hasRelationToTarget = attrs.some((attr) => {
|
|
6920
7063
|
if (attr.type !== "relation") return false;
|
|
6921
7064
|
const config = attr.config;
|
|
6922
|
-
return _nullishCoalesce(_optionalChain([config, 'optionalAccess',
|
|
7065
|
+
return _nullishCoalesce(_optionalChain([config, 'optionalAccess', _160 => _160.targets, 'optionalAccess', _161 => _161.some, 'call', _162 => _162((t) => t.object === targetObjectName)]), () => ( false));
|
|
6923
7066
|
});
|
|
6924
7067
|
if (hasRelationToTarget) {
|
|
6925
7068
|
referencing.push(obj.name);
|
|
@@ -6951,17 +7094,13 @@ var PermissionService = class extends TenantAwareService {
|
|
|
6951
7094
|
constructor(adapter, options) {
|
|
6952
7095
|
super();
|
|
6953
7096
|
this.adapter = adapter;
|
|
6954
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
6955
|
-
/** Track pending permission fetches to prevent duplicate concurrent requests */
|
|
6956
|
-
this.pendingFetches = /* @__PURE__ */ new Map();
|
|
6957
7097
|
if (!adapter.permissions) {
|
|
6958
7098
|
throw new Error(
|
|
6959
7099
|
"PermissionService requires a DatabaseAdapter with permissions repository. Make sure your adapter implements the permissions property."
|
|
6960
7100
|
);
|
|
6961
7101
|
}
|
|
6962
7102
|
this.permissionsRepo = adapter.permissions;
|
|
6963
|
-
this.
|
|
6964
|
-
this.maxCacheSize = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _163 => _163.maxCacheSize]), () => ( 1e4));
|
|
7103
|
+
this.cache = _nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _163 => _163.cache]), () => ( adapter.cache)), () => ( new NoopCacheAdapter()));
|
|
6965
7104
|
this.auditService = _optionalChain([options, 'optionalAccess', _164 => _164.auditService]);
|
|
6966
7105
|
}
|
|
6967
7106
|
// ============================================================================
|
|
@@ -7089,46 +7228,18 @@ var PermissionService = class extends TenantAwareService {
|
|
|
7089
7228
|
// ============================================================================
|
|
7090
7229
|
/**
|
|
7091
7230
|
* Get effective permissions for a user.
|
|
7092
|
-
* Results are cached with TTL
|
|
7231
|
+
* Results are cached using CacheAdapter with TTL.
|
|
7093
7232
|
*
|
|
7094
7233
|
* @param userProfileId - User profile ID
|
|
7095
7234
|
* @returns Merged permissions from all user's roles
|
|
7096
7235
|
*/
|
|
7097
7236
|
async getEffectivePermissions(userProfileId) {
|
|
7098
|
-
const cacheKey = this.
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
if (pendingFetch) {
|
|
7105
|
-
return pendingFetch;
|
|
7106
|
-
}
|
|
7107
|
-
const fetchPromise = this.fetchAndCachePermissions(userProfileId, cacheKey);
|
|
7108
|
-
this.pendingFetches.set(cacheKey, fetchPromise);
|
|
7109
|
-
try {
|
|
7110
|
-
return await fetchPromise;
|
|
7111
|
-
} finally {
|
|
7112
|
-
this.pendingFetches.delete(cacheKey);
|
|
7113
|
-
}
|
|
7114
|
-
}
|
|
7115
|
-
/**
|
|
7116
|
-
* Fetch permissions from database and cache the result
|
|
7117
|
-
* @internal
|
|
7118
|
-
*/
|
|
7119
|
-
async fetchAndCachePermissions(userProfileId, cacheKey) {
|
|
7120
|
-
const permissions = await this.permissionsRepo.getEffectivePermissions(userProfileId);
|
|
7121
|
-
if (this.cache.size >= this.maxCacheSize) {
|
|
7122
|
-
const firstKey = this.cache.keys().next().value;
|
|
7123
|
-
if (firstKey) {
|
|
7124
|
-
this.cache.delete(firstKey);
|
|
7125
|
-
}
|
|
7126
|
-
}
|
|
7127
|
-
this.cache.set(cacheKey, {
|
|
7128
|
-
permissions,
|
|
7129
|
-
expiresAt: Date.now() + this.cacheTtlMs
|
|
7130
|
-
});
|
|
7131
|
-
return permissions;
|
|
7237
|
+
const cacheKey = cacheKeys.userPermissions(this.tenantId, userProfileId);
|
|
7238
|
+
return this.cache.getOrSet(
|
|
7239
|
+
cacheKey,
|
|
7240
|
+
() => this.permissionsRepo.getEffectivePermissions(userProfileId),
|
|
7241
|
+
cacheTtl.permissions
|
|
7242
|
+
);
|
|
7132
7243
|
}
|
|
7133
7244
|
// ============================================================================
|
|
7134
7245
|
// CACHE MANAGEMENT
|
|
@@ -7137,24 +7248,15 @@ var PermissionService = class extends TenantAwareService {
|
|
|
7137
7248
|
* Invalidate cached permissions for a specific user.
|
|
7138
7249
|
* Call this after role/permission changes.
|
|
7139
7250
|
*/
|
|
7140
|
-
invalidateCache(userProfileId) {
|
|
7141
|
-
this.cache.delete(this.
|
|
7251
|
+
async invalidateCache(userProfileId) {
|
|
7252
|
+
await this.cache.delete(cacheKeys.userPermissions(this.tenantId, userProfileId));
|
|
7142
7253
|
}
|
|
7143
7254
|
/**
|
|
7144
|
-
* Invalidate all cached permissions.
|
|
7255
|
+
* Invalidate all cached permissions for the current tenant.
|
|
7145
7256
|
* Call this after bulk role/permission changes.
|
|
7146
7257
|
*/
|
|
7147
|
-
invalidateAllCache() {
|
|
7148
|
-
this.cache.
|
|
7149
|
-
}
|
|
7150
|
-
/**
|
|
7151
|
-
* Get current cache size (for monitoring).
|
|
7152
|
-
*/
|
|
7153
|
-
getCacheSize() {
|
|
7154
|
-
return this.cache.size;
|
|
7155
|
-
}
|
|
7156
|
-
getCacheKey(userProfileId) {
|
|
7157
|
-
return `${this.tenantId}:${userProfileId}`;
|
|
7258
|
+
async invalidateAllCache() {
|
|
7259
|
+
await this.cache.deletePattern(cacheKeys.allPermissions(this.tenantId));
|
|
7158
7260
|
}
|
|
7159
7261
|
// ============================================================================
|
|
7160
7262
|
// ROLE MANAGEMENT
|
|
@@ -7516,10 +7618,11 @@ var registry = new NativeObjectRegistryClass();
|
|
|
7516
7618
|
|
|
7517
7619
|
// src/runtime/services/relation.service.ts
|
|
7518
7620
|
var RelationService = class extends TenantAwareService {
|
|
7519
|
-
constructor(adapter, nativeRegistry) {
|
|
7621
|
+
constructor(adapter, nativeRegistry, options) {
|
|
7520
7622
|
super();
|
|
7521
7623
|
this.adapter = adapter;
|
|
7522
|
-
this.
|
|
7624
|
+
this.cache = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _186 => _186.cache]), () => ( adapter.cache));
|
|
7625
|
+
this.schemaService = new ObjectSchemaService(adapter, nativeRegistry, { cache: this.cache });
|
|
7523
7626
|
}
|
|
7524
7627
|
/**
|
|
7525
7628
|
* Validate all relation attributes in the data
|
|
@@ -7570,7 +7673,7 @@ var RelationService = class extends TenantAwareService {
|
|
|
7570
7673
|
}
|
|
7571
7674
|
const isUniversal = attr.targets.length === 1 && attr.targets[0].object === RELATION_TARGET_ANY;
|
|
7572
7675
|
const validObjectIds = isUniversal ? null : await this.getValidObjectIds(attr.targets);
|
|
7573
|
-
if (!isUniversal && _optionalChain([validObjectIds, 'optionalAccess',
|
|
7676
|
+
if (!isUniversal && _optionalChain([validObjectIds, 'optionalAccess', _187 => _187.size]) === 0) {
|
|
7574
7677
|
errors.push({
|
|
7575
7678
|
attribute: attr.name,
|
|
7576
7679
|
message: `No valid target objects found for ${attr.label}`
|
|
@@ -7621,7 +7724,7 @@ var RelationService = class extends TenantAwareService {
|
|
|
7621
7724
|
for (const target of targets) {
|
|
7622
7725
|
try {
|
|
7623
7726
|
const objectSchema = await this.schemaService.getObjectSchemaByName(target.object);
|
|
7624
|
-
if (_optionalChain([objectSchema, 'optionalAccess',
|
|
7727
|
+
if (_optionalChain([objectSchema, 'optionalAccess', _188 => _188.id])) {
|
|
7625
7728
|
objectIds.add(objectSchema.id);
|
|
7626
7729
|
}
|
|
7627
7730
|
} catch (e7) {
|
|
@@ -7674,7 +7777,7 @@ var RelationService = class extends TenantAwareService {
|
|
|
7674
7777
|
const recordService = new RecordService(this.adapter);
|
|
7675
7778
|
for (const target of filteredTargets) {
|
|
7676
7779
|
const objectSchema = await this.schemaService.getObjectSchemaByName(target.object);
|
|
7677
|
-
if (!_optionalChain([objectSchema, 'optionalAccess',
|
|
7780
|
+
if (!_optionalChain([objectSchema, 'optionalAccess', _189 => _189.id])) {
|
|
7678
7781
|
continue;
|
|
7679
7782
|
}
|
|
7680
7783
|
const result = query ? await recordService.searchRecords(objectSchema.id, query, {
|
|
@@ -7744,9 +7847,9 @@ var RelationService = class extends TenantAwareService {
|
|
|
7744
7847
|
continue;
|
|
7745
7848
|
}
|
|
7746
7849
|
let template = objectSchema.labelExpression;
|
|
7747
|
-
if (_optionalChain([attribute, 'optionalAccess',
|
|
7850
|
+
if (_optionalChain([attribute, 'optionalAccess', _190 => _190.targets])) {
|
|
7748
7851
|
const targetConfig = attribute.targets.find((t) => t.object === objectSchema.name);
|
|
7749
|
-
if (_optionalChain([targetConfig, 'optionalAccess',
|
|
7852
|
+
if (_optionalChain([targetConfig, 'optionalAccess', _191 => _191.displayTemplate])) {
|
|
7750
7853
|
template = targetConfig.displayTemplate;
|
|
7751
7854
|
}
|
|
7752
7855
|
}
|
|
@@ -7786,12 +7889,15 @@ var RelationService = class extends TenantAwareService {
|
|
|
7786
7889
|
|
|
7787
7890
|
// src/runtime/services/rollup.service.ts
|
|
7788
7891
|
var RollupService = class {
|
|
7789
|
-
constructor(adapter) {
|
|
7892
|
+
constructor(adapter, options) {
|
|
7790
7893
|
this.adapter = adapter;
|
|
7894
|
+
this.cache = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _192 => _192.cache]), () => ( adapter.cache));
|
|
7791
7895
|
}
|
|
7792
7896
|
/**
|
|
7793
7897
|
* Calculate a rollup value for a record
|
|
7794
7898
|
*
|
|
7899
|
+
* Results are cached if a CacheAdapter is configured.
|
|
7900
|
+
*
|
|
7795
7901
|
* @param recordId - ID of the parent record
|
|
7796
7902
|
* @param rollupAttr - Rollup attribute definition
|
|
7797
7903
|
* @param schema - Schema of the parent object
|
|
@@ -7815,6 +7921,21 @@ var RollupService = class {
|
|
|
7815
7921
|
* ```
|
|
7816
7922
|
*/
|
|
7817
7923
|
async calculate(recordId, rollupAttr, schema) {
|
|
7924
|
+
if (this.cache) {
|
|
7925
|
+
const tenantId = getTenantId();
|
|
7926
|
+
const cacheKey = cacheKeys.rollupValue(tenantId, recordId, rollupAttr.name);
|
|
7927
|
+
return this.cache.getOrSet(
|
|
7928
|
+
cacheKey,
|
|
7929
|
+
() => this.computeRollup(recordId, rollupAttr, schema),
|
|
7930
|
+
cacheTtl.rollup
|
|
7931
|
+
);
|
|
7932
|
+
}
|
|
7933
|
+
return this.computeRollup(recordId, rollupAttr, schema);
|
|
7934
|
+
}
|
|
7935
|
+
/**
|
|
7936
|
+
* Internal method to compute rollup value (no caching)
|
|
7937
|
+
*/
|
|
7938
|
+
async computeRollup(recordId, rollupAttr, schema) {
|
|
7818
7939
|
const relationAttr = schema.attributes.find(
|
|
7819
7940
|
(a) => a.type === "relation" && a.name === rollupAttr.relationAttribute
|
|
7820
7941
|
);
|
|
@@ -7866,7 +7987,7 @@ var RollupService = class {
|
|
|
7866
7987
|
const reverseRelationAttr = sourceAttributes.find((attr) => {
|
|
7867
7988
|
if (attr.type !== "relation") return false;
|
|
7868
7989
|
const relationConfig = attr.config;
|
|
7869
|
-
return _optionalChain([relationConfig, 'optionalAccess',
|
|
7990
|
+
return _optionalChain([relationConfig, 'optionalAccess', _193 => _193.targets, 'optionalAccess', _194 => _194.some, 'call', _195 => _195((t) => t.object === schema.name)]);
|
|
7870
7991
|
});
|
|
7871
7992
|
if (!reverseRelationAttr) {
|
|
7872
7993
|
return { value: null, recordCount: 0 };
|
|
@@ -8053,6 +8174,31 @@ var RollupService = class {
|
|
|
8053
8174
|
}
|
|
8054
8175
|
return [...new Set(affectedIds)];
|
|
8055
8176
|
}
|
|
8177
|
+
/**
|
|
8178
|
+
* Invalidate cached rollups for affected parent records.
|
|
8179
|
+
* Call this after a child record is created, updated, or deleted.
|
|
8180
|
+
*
|
|
8181
|
+
* @param affectedParentIds - Array of parent record IDs whose rollups need invalidation
|
|
8182
|
+
*/
|
|
8183
|
+
async invalidateAffectedRollups(affectedParentIds) {
|
|
8184
|
+
if (!this.cache || affectedParentIds.length === 0) return;
|
|
8185
|
+
const tenantId = getTenantId();
|
|
8186
|
+
const cache = this.cache;
|
|
8187
|
+
await Promise.all(
|
|
8188
|
+
affectedParentIds.map(
|
|
8189
|
+
(parentId) => cache.deletePattern(cacheKeys.rollupsByRecord(tenantId, parentId))
|
|
8190
|
+
)
|
|
8191
|
+
);
|
|
8192
|
+
}
|
|
8193
|
+
/**
|
|
8194
|
+
* Invalidate all cached rollups for the current tenant.
|
|
8195
|
+
* Use sparingly - prefer targeted invalidation.
|
|
8196
|
+
*/
|
|
8197
|
+
async invalidateAllRollups() {
|
|
8198
|
+
if (!this.cache) return;
|
|
8199
|
+
const tenantId = getTenantId();
|
|
8200
|
+
await this.cache.deletePattern(cacheKeys.allRollups(tenantId));
|
|
8201
|
+
}
|
|
8056
8202
|
/**
|
|
8057
8203
|
* Find records that have forward rollups pointing to the modified record.
|
|
8058
8204
|
*
|
|
@@ -8082,7 +8228,7 @@ var RollupService = class {
|
|
|
8082
8228
|
}
|
|
8083
8229
|
for (const rollupDbAttr of rollupAttrs) {
|
|
8084
8230
|
const rollupConfig = rollupDbAttr.config;
|
|
8085
|
-
if (!_optionalChain([rollupConfig, 'optionalAccess',
|
|
8231
|
+
if (!_optionalChain([rollupConfig, 'optionalAccess', _196 => _196.relationAttribute])) {
|
|
8086
8232
|
continue;
|
|
8087
8233
|
}
|
|
8088
8234
|
const relationAttr = attributes.find(
|
|
@@ -8092,7 +8238,7 @@ var RollupService = class {
|
|
|
8092
8238
|
continue;
|
|
8093
8239
|
}
|
|
8094
8240
|
const relationConfig = relationAttr.config;
|
|
8095
|
-
const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess',
|
|
8241
|
+
const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _197 => _197.targets, 'optionalAccess', _198 => _198.some, 'call', _199 => _199(
|
|
8096
8242
|
(t) => t.object === changedSchema.name
|
|
8097
8243
|
)]);
|
|
8098
8244
|
if (!targetsChangedObject) {
|
|
@@ -8195,7 +8341,7 @@ var UserService = class extends TenantAwareService {
|
|
|
8195
8341
|
if (roleErrors.length > 0) {
|
|
8196
8342
|
errors.push({
|
|
8197
8343
|
attribute: attr.name,
|
|
8198
|
-
message: `Users do not have required role for ${attr.label}. Allowed roles: ${_optionalChain([attr, 'access',
|
|
8344
|
+
message: `Users do not have required role for ${attr.label}. Allowed roles: ${_optionalChain([attr, 'access', _200 => _200.allowedRoles, 'optionalAccess', _201 => _201.join, 'call', _202 => _202(", ")])}`,
|
|
8199
8345
|
invalidIds: roleErrors
|
|
8200
8346
|
});
|
|
8201
8347
|
}
|
|
@@ -8249,15 +8395,15 @@ var RecordService = class extends TenantAwareService {
|
|
|
8249
8395
|
super();
|
|
8250
8396
|
this.adapter = adapter;
|
|
8251
8397
|
this.schemaService = new ObjectSchemaService(adapter, registry, {
|
|
8252
|
-
auditService: _optionalChain([options, 'optionalAccess',
|
|
8398
|
+
auditService: _optionalChain([options, 'optionalAccess', _203 => _203.auditService])
|
|
8253
8399
|
});
|
|
8254
8400
|
this.relationService = new RelationService(adapter, registry);
|
|
8255
8401
|
this.userService = new UserService(adapter);
|
|
8256
8402
|
this.rollupService = new RollupService(adapter);
|
|
8257
|
-
this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
8258
|
-
this.permissionService = _optionalChain([options, 'optionalAccess',
|
|
8259
|
-
this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
8260
|
-
this.policyRegistry = _optionalChain([options, 'optionalAccess',
|
|
8403
|
+
this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _204 => _204.hookRegistry]), () => ( new NoopHookRegistry()));
|
|
8404
|
+
this.permissionService = _optionalChain([options, 'optionalAccess', _205 => _205.permissionService]);
|
|
8405
|
+
this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _206 => _206.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
|
|
8406
|
+
this.policyRegistry = _optionalChain([options, 'optionalAccess', _207 => _207.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _208 => _208.policyRegistry]), () => ( defaultPolicyRegistry));
|
|
8261
8407
|
}
|
|
8262
8408
|
/**
|
|
8263
8409
|
* Check permission for an action on an object.
|
|
@@ -8441,20 +8587,20 @@ var RecordService = class extends TenantAwareService {
|
|
|
8441
8587
|
const schema = await this.schemaService.getObjectSchema(objectId);
|
|
8442
8588
|
const dataWithDefaults = applyDefaultValues(schema, data);
|
|
8443
8589
|
await this.checkPermission(schema.name, "create");
|
|
8444
|
-
const hookCtx = this.buildCreateHookContext(schema, dataWithDefaults, _optionalChain([options, 'optionalAccess',
|
|
8445
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8590
|
+
const hookCtx = this.buildCreateHookContext(schema, dataWithDefaults, _optionalChain([options, 'optionalAccess', _209 => _209.hookMetadata]));
|
|
8591
|
+
if (!_optionalChain([options, 'optionalAccess', _210 => _210.skipHooks])) {
|
|
8446
8592
|
await this.hookRegistry.execute("beforeCreate", schema.name, hookCtx);
|
|
8447
8593
|
}
|
|
8448
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8449
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8594
|
+
if (_optionalChain([options, 'optionalAccess', _211 => _211.validate]) !== false) {
|
|
8595
|
+
if (_optionalChain([options, 'optionalAccess', _212 => _212.allowDraft])) {
|
|
8450
8596
|
validateDraftOrThrow(schema, dataWithDefaults);
|
|
8451
8597
|
} else {
|
|
8452
8598
|
validateObjectOrThrow(schema, dataWithDefaults);
|
|
8453
8599
|
}
|
|
8454
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8600
|
+
if (!_optionalChain([options, 'optionalAccess', _213 => _213.skipRelationValidation])) {
|
|
8455
8601
|
await this.relationService.validateRelationsOrThrow(schema, dataWithDefaults);
|
|
8456
8602
|
}
|
|
8457
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8603
|
+
if (!_optionalChain([options, 'optionalAccess', _214 => _214.skipUserValidation])) {
|
|
8458
8604
|
await this.userService.validateUsersOrThrow(schema, dataWithDefaults);
|
|
8459
8605
|
}
|
|
8460
8606
|
}
|
|
@@ -8465,10 +8611,10 @@ var RecordService = class extends TenantAwareService {
|
|
|
8465
8611
|
data: dataWithDefaults,
|
|
8466
8612
|
label,
|
|
8467
8613
|
completionStatus,
|
|
8468
|
-
metadata: _optionalChain([options, 'optionalAccess',
|
|
8614
|
+
metadata: _optionalChain([options, 'optionalAccess', _215 => _215.metadata]),
|
|
8469
8615
|
createdBy: this.userId
|
|
8470
8616
|
});
|
|
8471
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8617
|
+
if (!_optionalChain([options, 'optionalAccess', _216 => _216.skipHooks])) {
|
|
8472
8618
|
const afterCtx = {
|
|
8473
8619
|
...hookCtx,
|
|
8474
8620
|
recordId: record.id,
|
|
@@ -8485,7 +8631,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8485
8631
|
objectId: schema.id,
|
|
8486
8632
|
recordId: record.id,
|
|
8487
8633
|
recordLabel: record.label,
|
|
8488
|
-
metadata: _optionalChain([options, 'optionalAccess',
|
|
8634
|
+
metadata: _optionalChain([options, 'optionalAccess', _217 => _217.hookMetadata])
|
|
8489
8635
|
});
|
|
8490
8636
|
}
|
|
8491
8637
|
return record;
|
|
@@ -8503,17 +8649,17 @@ var RecordService = class extends TenantAwareService {
|
|
|
8503
8649
|
return null;
|
|
8504
8650
|
}
|
|
8505
8651
|
const schema = await this.schemaService.getObjectSchema(record.objectId);
|
|
8506
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8652
|
+
if (!_optionalChain([options, 'optionalAccess', _218 => _218.skipPolicyCheck])) {
|
|
8507
8653
|
const policy = this.getPolicy(schema.name);
|
|
8508
8654
|
if (policy && !this.checkRecordAccess(policy, record)) {
|
|
8509
8655
|
return null;
|
|
8510
8656
|
}
|
|
8511
8657
|
}
|
|
8512
8658
|
let enrichedRecord = record;
|
|
8513
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8659
|
+
if (!_optionalChain([options, 'optionalAccess', _219 => _219.skipFormulas])) {
|
|
8514
8660
|
enrichedRecord = this.enrichWithFormulas(record, schema);
|
|
8515
8661
|
}
|
|
8516
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8662
|
+
if (_optionalChain([options, 'optionalAccess', _220 => _220.includeSchema])) {
|
|
8517
8663
|
const recordWithSchema = enrichedRecord;
|
|
8518
8664
|
recordWithSchema.schema = schema;
|
|
8519
8665
|
return recordWithSchema;
|
|
@@ -8572,9 +8718,9 @@ var RecordService = class extends TenantAwareService {
|
|
|
8572
8718
|
data,
|
|
8573
8719
|
mergedData,
|
|
8574
8720
|
changedAttributes,
|
|
8575
|
-
_optionalChain([options, 'optionalAccess',
|
|
8721
|
+
_optionalChain([options, 'optionalAccess', _221 => _221.hookMetadata])
|
|
8576
8722
|
);
|
|
8577
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8723
|
+
if (!_optionalChain([options, 'optionalAccess', _222 => _222.skipHooks])) {
|
|
8578
8724
|
await this.hookRegistry.execute("beforeUpdate", schema.name, hookCtx);
|
|
8579
8725
|
}
|
|
8580
8726
|
const hookModifiedValues = {};
|
|
@@ -8583,19 +8729,19 @@ var RecordService = class extends TenantAwareService {
|
|
|
8583
8729
|
hookModifiedValues[key] = hookCtx.newValues[key];
|
|
8584
8730
|
}
|
|
8585
8731
|
}
|
|
8586
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8587
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8732
|
+
if (_optionalChain([options, 'optionalAccess', _223 => _223.validate]) !== false) {
|
|
8733
|
+
if (_optionalChain([options, 'optionalAccess', _224 => _224.partial])) {
|
|
8588
8734
|
validateDraftOrThrow(schema, mergedData);
|
|
8589
8735
|
} else {
|
|
8590
8736
|
validateObjectOrThrow(schema, mergedData);
|
|
8591
8737
|
}
|
|
8592
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8738
|
+
if (!_optionalChain([options, 'optionalAccess', _225 => _225.skipRelationValidation])) {
|
|
8593
8739
|
await this.relationService.validateRelationsOrThrow(schema, {
|
|
8594
8740
|
...data,
|
|
8595
8741
|
...hookModifiedValues
|
|
8596
8742
|
});
|
|
8597
8743
|
}
|
|
8598
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8744
|
+
if (!_optionalChain([options, 'optionalAccess', _226 => _226.skipUserValidation])) {
|
|
8599
8745
|
await this.userService.validateUsersOrThrow(schema, {
|
|
8600
8746
|
...data,
|
|
8601
8747
|
...hookModifiedValues
|
|
@@ -8611,7 +8757,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8611
8757
|
__label: label,
|
|
8612
8758
|
__lastUpdatedBy: this.userId
|
|
8613
8759
|
};
|
|
8614
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8760
|
+
if (_optionalChain([options, 'optionalAccess', _227 => _227.metadata]) !== void 0) {
|
|
8615
8761
|
const existingMetadata = _nullishCoalesce(existing.metadata, () => ( {}));
|
|
8616
8762
|
const mergedMetadata = { ...existingMetadata, ...options.metadata };
|
|
8617
8763
|
const cleanedMetadata = Object.fromEntries(
|
|
@@ -8620,7 +8766,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8620
8766
|
updatePayload.__metadata = cleanedMetadata;
|
|
8621
8767
|
}
|
|
8622
8768
|
const updated = await this.adapter.objectRecords.update(recordId, updatePayload);
|
|
8623
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8769
|
+
if (!_optionalChain([options, 'optionalAccess', _228 => _228.skipHooks])) {
|
|
8624
8770
|
const afterCtx = {
|
|
8625
8771
|
...hookCtx,
|
|
8626
8772
|
record: updated
|
|
@@ -8635,7 +8781,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8635
8781
|
if (this.auditService && this.userId && allChangedAttributes.length > 0) {
|
|
8636
8782
|
const changes = allChangedAttributes.map((attr) => ({
|
|
8637
8783
|
field: attr,
|
|
8638
|
-
oldValue: _optionalChain([hookCtx, 'access',
|
|
8784
|
+
oldValue: _optionalChain([hookCtx, 'access', _229 => _229.oldValues, 'optionalAccess', _230 => _230[attr]]),
|
|
8639
8785
|
newValue: hookCtx.newValues[attr]
|
|
8640
8786
|
}));
|
|
8641
8787
|
await this.auditService.logRecordAction({
|
|
@@ -8646,7 +8792,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8646
8792
|
recordId: updated.id,
|
|
8647
8793
|
recordLabel: updated.label,
|
|
8648
8794
|
changes,
|
|
8649
|
-
metadata: _optionalChain([options, 'optionalAccess',
|
|
8795
|
+
metadata: _optionalChain([options, 'optionalAccess', _231 => _231.hookMetadata])
|
|
8650
8796
|
});
|
|
8651
8797
|
}
|
|
8652
8798
|
return updated;
|
|
@@ -8746,23 +8892,23 @@ var RecordService = class extends TenantAwareService {
|
|
|
8746
8892
|
if (policy) {
|
|
8747
8893
|
this.checkRecordDelete(policy, record);
|
|
8748
8894
|
}
|
|
8749
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
8895
|
+
if (_optionalChain([options, 'optionalAccess', _232 => _232.checkSystem])) {
|
|
8750
8896
|
if (schema.system) {
|
|
8751
8897
|
throw new ProtectedResourceError("object", schema.name, "delete");
|
|
8752
8898
|
}
|
|
8753
8899
|
}
|
|
8754
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8900
|
+
if (!_optionalChain([options, 'optionalAccess', _233 => _233.skipReferenceCheck])) {
|
|
8755
8901
|
const references = await this.adapter.objectRecords.countRecordsReferencingId(recordId);
|
|
8756
8902
|
if (references.length > 0) {
|
|
8757
8903
|
throw new RecordReferencedError(recordId, references);
|
|
8758
8904
|
}
|
|
8759
8905
|
}
|
|
8760
|
-
const hookCtx = this.buildDeleteHookContext(schema, record, _optionalChain([options, 'optionalAccess',
|
|
8761
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8906
|
+
const hookCtx = this.buildDeleteHookContext(schema, record, _optionalChain([options, 'optionalAccess', _234 => _234.hookMetadata]));
|
|
8907
|
+
if (!_optionalChain([options, 'optionalAccess', _235 => _235.skipHooks])) {
|
|
8762
8908
|
await this.hookRegistry.execute("beforeDelete", schema.name, hookCtx);
|
|
8763
8909
|
}
|
|
8764
8910
|
await this.adapter.objectRecords.delete(recordId);
|
|
8765
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8911
|
+
if (!_optionalChain([options, 'optionalAccess', _236 => _236.skipHooks])) {
|
|
8766
8912
|
await this.hookRegistry.execute("afterDelete", schema.name, hookCtx);
|
|
8767
8913
|
}
|
|
8768
8914
|
await this.recalculateParentRollups(record, schema);
|
|
@@ -8774,7 +8920,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8774
8920
|
objectId: schema.id,
|
|
8775
8921
|
recordId: record.id,
|
|
8776
8922
|
recordLabel: record.label,
|
|
8777
|
-
metadata: _optionalChain([options, 'optionalAccess',
|
|
8923
|
+
metadata: _optionalChain([options, 'optionalAccess', _237 => _237.hookMetadata])
|
|
8778
8924
|
});
|
|
8779
8925
|
}
|
|
8780
8926
|
}
|
|
@@ -8805,12 +8951,12 @@ var RecordService = class extends TenantAwareService {
|
|
|
8805
8951
|
}
|
|
8806
8952
|
const schema = await this.schemaService.getObjectSchema(record.objectId);
|
|
8807
8953
|
await this.checkPermission(schema.name, "update");
|
|
8808
|
-
const hookCtx = this.buildRestoreHookContext(schema, record, _optionalChain([options, 'optionalAccess',
|
|
8809
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8954
|
+
const hookCtx = this.buildRestoreHookContext(schema, record, _optionalChain([options, 'optionalAccess', _238 => _238.hookMetadata]));
|
|
8955
|
+
if (!_optionalChain([options, 'optionalAccess', _239 => _239.skipHooks])) {
|
|
8810
8956
|
await this.hookRegistry.execute("beforeRestore", schema.name, hookCtx);
|
|
8811
8957
|
}
|
|
8812
8958
|
const restored = await this.adapter.objectRecords.restore(recordId);
|
|
8813
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
8959
|
+
if (!_optionalChain([options, 'optionalAccess', _240 => _240.skipHooks])) {
|
|
8814
8960
|
const afterCtx = {
|
|
8815
8961
|
...hookCtx,
|
|
8816
8962
|
record: restored
|
|
@@ -8825,7 +8971,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
8825
8971
|
objectId: schema.id,
|
|
8826
8972
|
recordId: restored.id,
|
|
8827
8973
|
recordLabel: restored.label,
|
|
8828
|
-
metadata: _optionalChain([options, 'optionalAccess',
|
|
8974
|
+
metadata: _optionalChain([options, 'optionalAccess', _241 => _241.hookMetadata])
|
|
8829
8975
|
});
|
|
8830
8976
|
}
|
|
8831
8977
|
return restored;
|
|
@@ -8970,20 +9116,20 @@ var RecordService = class extends TenantAwareService {
|
|
|
8970
9116
|
if (this.permissionService && this.userId) {
|
|
8971
9117
|
await this.checkPermission(schema.name, "read");
|
|
8972
9118
|
}
|
|
8973
|
-
const policy = _optionalChain([options, 'optionalAccess',
|
|
9119
|
+
const policy = _optionalChain([options, 'optionalAccess', _242 => _242.skipPolicyFilter]) ? void 0 : this.getPolicy(schema.name);
|
|
8974
9120
|
let effectiveOptions = options;
|
|
8975
|
-
if (_optionalChain([policy, 'optionalAccess',
|
|
9121
|
+
if (_optionalChain([policy, 'optionalAccess', _243 => _243.applyListFilter])) {
|
|
8976
9122
|
effectiveOptions = policy.applyListFilter(this.buildPolicyContext(schema.name), options);
|
|
8977
9123
|
}
|
|
8978
9124
|
const result = await this.adapter.objectRecords.list(objectId, effectiveOptions);
|
|
8979
9125
|
let filteredRecords = result.records;
|
|
8980
9126
|
let effectiveTotal = result.total;
|
|
8981
|
-
if (_optionalChain([policy, 'optionalAccess',
|
|
9127
|
+
if (_optionalChain([policy, 'optionalAccess', _244 => _244.canAccessRecord])) {
|
|
8982
9128
|
const ctx = this.buildPolicyContext(schema.name);
|
|
8983
|
-
filteredRecords = result.records.filter((record) => _optionalChain([policy, 'access',
|
|
9129
|
+
filteredRecords = result.records.filter((record) => _optionalChain([policy, 'access', _245 => _245.canAccessRecord, 'optionalCall', _246 => _246(ctx, record)]));
|
|
8984
9130
|
effectiveTotal = filteredRecords.length;
|
|
8985
9131
|
}
|
|
8986
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
9132
|
+
if (!_optionalChain([options, 'optionalAccess', _247 => _247.skipFormulas])) {
|
|
8987
9133
|
return {
|
|
8988
9134
|
records: this.enrichRecordsWithFormulas(filteredRecords, schema),
|
|
8989
9135
|
total: effectiveTotal
|
|
@@ -9008,7 +9154,7 @@ var RecordService = class extends TenantAwareService {
|
|
|
9008
9154
|
await this.checkPermission(schema.name, "read");
|
|
9009
9155
|
}
|
|
9010
9156
|
const result = await this.adapter.objectRecords.search(objectId, query, options);
|
|
9011
|
-
if (!_optionalChain([options, 'optionalAccess',
|
|
9157
|
+
if (!_optionalChain([options, 'optionalAccess', _248 => _248.skipFormulas])) {
|
|
9012
9158
|
return {
|
|
9013
9159
|
records: this.enrichRecordsWithFormulas(result.records, schema),
|
|
9014
9160
|
total: result.total
|
|
@@ -9156,6 +9302,7 @@ var RelationResolverService = class {
|
|
|
9156
9302
|
for (const record of records) {
|
|
9157
9303
|
const result = resultMap.get(record.id);
|
|
9158
9304
|
const idToAttr = recordRelationMap.get(record.id);
|
|
9305
|
+
if (!(result && idToAttr)) continue;
|
|
9159
9306
|
for (const [relatedId, attrName] of idToAttr) {
|
|
9160
9307
|
const relatedRecord = relatedRecordMap.get(relatedId);
|
|
9161
9308
|
if (relatedRecord) {
|
|
@@ -9206,8 +9353,8 @@ var RollupScheduler = class {
|
|
|
9206
9353
|
this.getSchemaById = getSchemaById;
|
|
9207
9354
|
this.pending = /* @__PURE__ */ new Map();
|
|
9208
9355
|
this.rollupService = new RollupService(adapter);
|
|
9209
|
-
this.debounceMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
9210
|
-
this.maxPending = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
9356
|
+
this.debounceMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _249 => _249.debounceMs]), () => ( 100));
|
|
9357
|
+
this.maxPending = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _250 => _250.maxPending]), () => ( 100));
|
|
9211
9358
|
}
|
|
9212
9359
|
/**
|
|
9213
9360
|
* Schedule a rollup recalculation for a parent record.
|
|
@@ -9283,7 +9430,7 @@ var UserProfileService = class extends TenantAwareService {
|
|
|
9283
9430
|
constructor(adapter, options) {
|
|
9284
9431
|
super();
|
|
9285
9432
|
this.adapter = adapter;
|
|
9286
|
-
this.auditService = _optionalChain([options, 'optionalAccess',
|
|
9433
|
+
this.auditService = _optionalChain([options, 'optionalAccess', _251 => _251.auditService]);
|
|
9287
9434
|
}
|
|
9288
9435
|
/**
|
|
9289
9436
|
* Create a new user profile (typically after first auth).
|
|
@@ -9416,7 +9563,7 @@ var UserProfileService = class extends TenantAwareService {
|
|
|
9416
9563
|
*/
|
|
9417
9564
|
async deleteProfile(profileId, options) {
|
|
9418
9565
|
const profile = await this.getProfileOrThrow(profileId);
|
|
9419
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
9566
|
+
if (_optionalChain([options, 'optionalAccess', _252 => _252.checkAdmin])) {
|
|
9420
9567
|
if (profile.role === "admin") {
|
|
9421
9568
|
const adminCount = await this.adapter.userProfiles.countByRole("admin");
|
|
9422
9569
|
if (adminCount <= 1) {
|
|
@@ -9485,7 +9632,7 @@ var UserProfileService = class extends TenantAwareService {
|
|
|
9485
9632
|
*/
|
|
9486
9633
|
async hasRole(profileId, role) {
|
|
9487
9634
|
const profile = await this.getProfile(profileId);
|
|
9488
|
-
return _optionalChain([profile, 'optionalAccess',
|
|
9635
|
+
return _optionalChain([profile, 'optionalAccess', _253 => _253.role]) === role;
|
|
9489
9636
|
}
|
|
9490
9637
|
/**
|
|
9491
9638
|
* Check if user is admin
|
|
@@ -9750,7 +9897,7 @@ var ViewService = class extends TenantAwareService {
|
|
|
9750
9897
|
}
|
|
9751
9898
|
if (tabs[0].type !== "form") {
|
|
9752
9899
|
throw new ValidationError("Modal views must have a form tab", [
|
|
9753
|
-
{ path: ["tabs"], message:
|
|
9900
|
+
{ path: ["tabs"], message: `Modal views must have a form tab, not a ${tabs[0].type}` }
|
|
9754
9901
|
]);
|
|
9755
9902
|
}
|
|
9756
9903
|
}
|
|
@@ -10319,4 +10466,7 @@ var NoopGeocodingAdapter = class {
|
|
|
10319
10466
|
|
|
10320
10467
|
|
|
10321
10468
|
|
|
10322
|
-
|
|
10469
|
+
|
|
10470
|
+
|
|
10471
|
+
|
|
10472
|
+
exports.RELATION_TARGET_ANY = RELATION_TARGET_ANY; exports.isUniversalRelation = isUniversalRelation; exports.RecordReferencedError = RecordReferencedError; exports.AttributeInUseError = AttributeInUseError; exports.ObjectReferencedError = ObjectReferencedError; exports.NoopGeocodingAdapter = NoopGeocodingAdapter; exports.SYSTEM_FIELD_NAMES = SYSTEM_FIELD_NAMES; exports.RESERVED_ATTRIBUTE_NAMES = RESERVED_ATTRIBUTE_NAMES; exports.PolicyViolationError = PolicyViolationError; exports.SYSTEM_ATTRIBUTES = SYSTEM_ATTRIBUTES; exports.getSystemAttributeList = getSystemAttributeList; exports.isSystemAttribute = isSystemAttribute; exports.isSystemAttributeObject = isSystemAttributeObject; exports.asTenantId = asTenantId; exports.asUserId = asUserId; exports.generateId = generateId; exports.generatePrefixedId = generatePrefixedId; exports.EMPTY_VALUE_PLACEHOLDER = EMPTY_VALUE_PLACEHOLDER; exports.formatAttributeValue = formatAttributeValue; exports.SchemaErrorCode = SchemaErrorCode; exports.SchemaError = SchemaError; exports.NotFoundError = NotFoundError; exports.ObjectNotFoundError = ObjectNotFoundError; exports.AttributeNotFoundError = AttributeNotFoundError; exports.RecordNotFoundError = RecordNotFoundError; exports.UserProfileNotFoundError = UserProfileNotFoundError; exports.FileNotFoundError = FileNotFoundError; exports.ValidationError = ValidationError; exports.ProtectedResourceError = ProtectedResourceError; exports.SyncError = SyncError; exports.NotSystemObjectError = NotSystemObjectError; exports.DuplicateError = DuplicateError; exports.isSchemaError = isSchemaError; exports.isNotFoundError = isNotFoundError; exports.isValidationError = isValidationError; exports.isProtectedResourceError = isProtectedResourceError; exports.ForbiddenError = ForbiddenError; exports.ProtectedRoleError = ProtectedRoleError; exports.RoleNotFoundError = RoleNotFoundError; exports.isForbiddenError = isForbiddenError; exports.text = text; exports.textarea = textarea; exports.richtext = richtext; exports.number = number; exports.checkbox = checkbox; exports.date = date; exports.phone = phone; exports.currency = currency; exports.status = status; exports.select = select; exports.multiselect = multiselect; exports.location = location; exports.file = file; exports.user = user; exports.relation = relation; exports.rating = rating; exports.formula = formula; exports.rollup = rollup; exports.FlowRowBuilder = FlowRowBuilder; exports.FlowPageBuilder = FlowPageBuilder; exports.FlowBuilder = FlowBuilder; exports.flow = flow; exports.ObjectBuilder = ObjectBuilder; exports.object = object; exports.GroupBuilder = GroupBuilder; exports.DirectTableTabConfig = DirectTableTabConfig; exports.InverseTableTabConfig = InverseTableTabConfig; exports.CustomTabConfig = CustomTabConfig; exports.NotesTabConfig = NotesTabConfig; exports.ActivityTabConfig = ActivityTabConfig; exports.TabBuilder = TabBuilder; exports.ViewBuilder = ViewBuilder; exports.view = view; exports.group = group; exports.registry = registry; exports.DEFAULT_VALIDATION_MESSAGES = DEFAULT_VALIDATION_MESSAGES; exports.textConfigSchema = textConfigSchema; exports.textareaConfigSchema = textareaConfigSchema; exports.richtextConfigSchema = richtextConfigSchema; exports.numberConfigSchema = numberConfigSchema; exports.checkboxConfigSchema = checkboxConfigSchema; exports.dateConfigSchema = dateConfigSchema; exports.phoneConfigSchema = phoneConfigSchema; exports.currencyConfigSchema = currencyConfigSchema; exports.statusConfigSchema = statusConfigSchema; exports.locationConfigSchema = locationConfigSchema; exports.selectConfigSchema = selectConfigSchema; exports.multiselectConfigSchema = multiselectConfigSchema; exports.fileConfigSchema = fileConfigSchema; exports.userConfigSchema = userConfigSchema; exports.relationConfigSchema = relationConfigSchema; exports.ratingConfigSchema = ratingConfigSchema; exports.formulaConfigSchema = formulaConfigSchema; exports.rollupConfigSchema = rollupConfigSchema; exports.attributeConfigSchemas = attributeConfigSchemas; exports.getAttributeConfigSchema = getAttributeConfigSchema; exports.validateAttributeConfig = validateAttributeConfig; exports.parseAttributeConfig = parseAttributeConfig; exports.safeParseAttributeConfig = safeParseAttributeConfig; exports.createTextValidator = createTextValidator; exports.createNumberValidator = createNumberValidator; exports.createCheckboxValidator = createCheckboxValidator; exports.createDateValidator = createDateValidator; exports.createPhoneValidator = createPhoneValidator; exports.createCurrencyValidator = createCurrencyValidator; exports.createStatusValidator = createStatusValidator; exports.createSelectValidator = createSelectValidator; exports.createMultiselectValidator = createMultiselectValidator; exports.createLocationValidator = createLocationValidator; exports.createFileValidator = createFileValidator; exports.createUserValidator = createUserValidator; exports.createSingleRelationValidator = createSingleRelationValidator; exports.createMultiRelationValidator = createMultiRelationValidator; exports.createRelationValidator = createRelationValidator; exports.createRatingValidator = createRatingValidator; exports.createFormulaValidator = createFormulaValidator; exports.createRollupValidator = createRollupValidator; exports.createTextAreaValidator = createTextAreaValidator; exports.createRichtextValidator = createRichtextValidator; exports.createAttributeValidator = createAttributeValidator; exports.createFormAttributeValidator = createFormAttributeValidator; exports.createObjectValidator = createObjectValidator; exports.validateAttribute = validateAttribute; exports.validateObject = validateObject; exports.validateObjectOrThrow = validateObjectOrThrow; exports.createDraftValidator = createDraftValidator; exports.validateDraft = validateDraft; exports.validateDraftOrThrow = validateDraftOrThrow; exports.getMissingRequiredAttributes = getMissingRequiredAttributes; exports.isRecordComplete = isRecordComplete; exports.computeRecordStatus = computeRecordStatus; exports.cacheKeys = cacheKeys; exports.cacheTtl = cacheTtl; exports.NoopCacheAdapter = NoopCacheAdapter; exports.formatRecord = formatRecord; exports.formatRecords = formatRecords; exports.createDefaultState = createDefaultState; exports.SHORTCUT_TO_FILTER_OPERATOR = SHORTCUT_TO_FILTER_OPERATOR; exports.QueryNoResultError = QueryNoResultError; exports.QueryMultipleResultsError = QueryMultipleResultsError; exports.TenantContextError = TenantContextError; exports.getContext = getContext; exports.getTenantId = getTenantId; exports.getUserId = getUserId; exports.hasContext = hasContext; exports.runWithContext = runWithContext; exports.withTenantContext = withTenantContext; exports.QueryBuilder = QueryBuilder; exports.createQueryBuilder = createQueryBuilder; exports.evaluateFormula = evaluateFormula; exports.evaluateFormulaWithResult = evaluateFormulaWithResult; exports.formatFormulaResult = formatFormulaResult; exports.evaluateFormulaAttribute = evaluateFormulaAttribute; exports.validateFormulaExpression = validateFormulaExpression; exports.extractFormulaVariables = extractFormulaVariables; exports.extractRelationReferences = extractRelationReferences; exports.extractRelationNames = extractRelationNames; exports.hasRelationReferences = hasRelationReferences; exports.flattenRelationsForEval = flattenRelationsForEval; exports.evaluateFormulaWithRelations = evaluateFormulaWithRelations; exports.evaluateFormulaAttributeWithRelations = evaluateFormulaAttributeWithRelations; exports.InvalidPathError = InvalidPathError; exports.MaxDepthExceededError = MaxDepthExceededError; exports.parsePath = parsePath; exports.validatePath = validatePath; exports.pathHasManyCardinality = pathHasManyCardinality; exports.getPathDepth = getPathDepth; exports.getTargetAttributeName = getTargetAttributeName; exports.getRelationPath = getRelationPath; exports.traversePath = traversePath; exports.resolveSingleValue = resolveSingleValue; exports.resolveMultiplePaths = resolveMultiplePaths; exports.NoopHookRegistry = NoopHookRegistry; exports.DEFAULT_LABEL_FALLBACK = DEFAULT_LABEL_FALLBACK; exports.renderLabelExpression = renderLabelExpression; exports.isLabelExpression = isLabelExpression; exports.extractAttributeNames = extractAttributeNames; exports.enrichValuesWithSelectLabels = enrichValuesWithSelectLabels; exports.createMockAdapter = createMockAdapter; exports.PolicyRegistry = PolicyRegistry; exports.defaultPolicyRegistry = defaultPolicyRegistry; exports.notesPolicy = notesPolicy; exports.buildAuditChanges = buildAuditChanges; exports.TenantAwareService = TenantAwareService; exports.TenantAwareRepository = TenantAwareRepository; exports.AuditService = AuditService; exports.FileService = FileService; exports.FlowService = FlowService; exports.GeocodingService = GeocodingService; exports.GlobalSearchService = GlobalSearchService; exports.ObjectSchemaService = ObjectSchemaService; exports.PermissionService = PermissionService; exports.RelationService = RelationService; exports.RollupService = RollupService; exports.UserService = UserService; exports.RecordService = RecordService; exports.RelationResolverService = RelationResolverService; exports.RollupScheduler = RollupScheduler; exports.UserProfileService = UserProfileService; exports.ViewService = ViewService; exports.syncNativeViews = syncNativeViews; exports.verifyNativeViewsSync = verifyNativeViewsSync; exports.getViewSyncPreview = getViewSyncPreview; exports.syncNativeObjects = syncNativeObjects; exports.verifyNativeObjectsSync = verifyNativeObjectsSync; exports.getSyncPreview = getSyncPreview; exports.syncAll = syncAll;
|