@stndrds/schema 0.1.0-alpha.46 → 0.1.0-alpha.48

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.
@@ -369,6 +369,12 @@ var cacheKeys = {
369
369
  // -------------------------------------------------------------------------
370
370
  /** Relation options for an attribute */
371
371
  relationOptions: (tenantId, attrId, hash) => `rel:${tenantId}:${attrId}:${hash}`,
372
+ /**
373
+ * Resolved relation by composite ID.
374
+ * Composite ID format: `${attributeId}:${recordId}`
375
+ * Used by cachedByMany in RelationService.resolveIds()
376
+ */
377
+ resolvedRelation: (tenantId, compositeId) => `relres:${tenantId}:${compositeId}`,
372
378
  // -------------------------------------------------------------------------
373
379
  // Rollups - TTL: 2 minutes (high volatility)
374
380
  // -------------------------------------------------------------------------
@@ -408,6 +414,19 @@ var cacheKeys = {
408
414
  allPermissions: (tenantId) => `perms:${tenantId}:*`,
409
415
  /** All relation cache for a tenant */
410
416
  allRelations: (tenantId) => `rel:${tenantId}:*`,
417
+ /** All resolved relations cache for a tenant */
418
+ allResolvedRelations: (tenantId) => `relres:${tenantId}:*`,
419
+ /**
420
+ * Resolved relations for a specific record (all attributeId variants).
421
+ * Pattern matches `relres:${tenantId}:*:${recordId}` to invalidate
422
+ * all cached labels for a record regardless of which attribute resolved it.
423
+ */
424
+ resolvedRelationsByRecord: (tenantId, recordId) => `relres:${tenantId}:*:${recordId}`,
425
+ /**
426
+ * Resolved relations for a specific attribute.
427
+ * Invalidates when a relation's displayTemplate changes.
428
+ */
429
+ resolvedRelationsByAttr: (tenantId, attributeId) => `relres:${tenantId}:${attributeId}:*`,
411
430
  /** All rollup cache for a tenant */
412
431
  allRollups: (tenantId) => `rollup:${tenantId}:*`,
413
432
  /** All rollups for a specific record */
@@ -460,6 +479,8 @@ var cacheTtl = {
460
479
  permissions: 15 * 60 * 1e3,
461
480
  /** Relation options - medium volatility (5 minutes) */
462
481
  relations: 5 * 60 * 1e3,
482
+ /** Resolved relations - medium volatility (5 minutes) */
483
+ resolvedRelations: 5 * 60 * 1e3,
463
484
  /** Rollup values - high volatility (2 minutes) */
464
485
  rollup: 2 * 60 * 1e3,
465
486
  /** Individual records - high volatility (1 minute) */
@@ -492,6 +513,7 @@ var defaultTtl = {
492
513
  workflowById: cacheTtl.workflows,
493
514
  workflowList: cacheTtl.workflows,
494
515
  relationOptions: cacheTtl.relations,
516
+ resolvedRelation: cacheTtl.resolvedRelations,
495
517
  rollupValue: cacheTtl.rollup,
496
518
  userPermissions: cacheTtl.permissions,
497
519
  recordList: cacheTtl.recordList,
@@ -4408,6 +4430,72 @@ var BaseService = class {
4408
4430
  const pattern = patternFn(this.tenantId, id);
4409
4431
  await this.cache.deletePattern(pattern);
4410
4432
  }
4433
+ /**
4434
+ * Cache multiple resources by ID, fetching only missing ones.
4435
+ * Useful for batch operations with individual caching (e.g., resolveIds).
4436
+ *
4437
+ * Unlike `cachedBy` which caches a single resource, this method:
4438
+ * 1. Checks the cache for each ID in parallel
4439
+ * 2. Collects cache misses
4440
+ * 3. Fetches only missing items via the fetcher
4441
+ * 4. Caches new results individually
4442
+ * 5. Returns all results (cached + freshly fetched)
4443
+ *
4444
+ * @param keyType - Type of cache key (e.g., "resolvedRelation")
4445
+ * @param ids - Resource identifiers to fetch
4446
+ * @param fetcher - Function to fetch missing items (receives only cache-miss IDs)
4447
+ * @param getId - Function to extract ID from a fetched item
4448
+ * @param ttlMs - Optional TTL override
4449
+ *
4450
+ * @example
4451
+ * ```typescript
4452
+ * // Cache relations by composite ID (attributeId:recordId)
4453
+ * return this.cachedByMany(
4454
+ * "resolvedRelation",
4455
+ * ids.map(id => `${attributeId}:${id}`),
4456
+ * async (missingCompositeIds) => {
4457
+ * const missingRecordIds = missingCompositeIds.map(c => c.split(":")[1]);
4458
+ * return this.fetchRelations(missingRecordIds, attributeId);
4459
+ * },
4460
+ * (item) => `${attributeId}:${item.id}`
4461
+ * );
4462
+ * ```
4463
+ */
4464
+ async cachedByMany(keyType, ids, fetcher, getId, ttlMs) {
4465
+ const cache = this.cache;
4466
+ if (!cache || ids.length === 0) {
4467
+ return fetcher(ids);
4468
+ }
4469
+ const keyFn = cacheKeys[keyType];
4470
+ const ttl = _nullishCoalesce(_nullishCoalesce(ttlMs, () => ( defaultTtl[keyType])), () => ( 6e4));
4471
+ const cacheChecks = await Promise.all(
4472
+ ids.map(async (id) => {
4473
+ const key = keyFn(this.tenantId, id);
4474
+ const cached = await cache.get(key);
4475
+ return { id, cached };
4476
+ })
4477
+ );
4478
+ const results = [];
4479
+ const missingIds = [];
4480
+ for (const { id, cached } of cacheChecks) {
4481
+ if (cached !== null) {
4482
+ results.push(cached);
4483
+ } else {
4484
+ missingIds.push(id);
4485
+ }
4486
+ }
4487
+ if (missingIds.length > 0) {
4488
+ const fetched = await fetcher(missingIds);
4489
+ await Promise.all(
4490
+ fetched.map(async (item) => {
4491
+ const key = keyFn(this.tenantId, getId(item));
4492
+ await cache.set(key, item, ttl);
4493
+ })
4494
+ );
4495
+ results.push(...fetched);
4496
+ }
4497
+ return results;
4498
+ }
4411
4499
  };
4412
4500
  var BaseRepository = class {
4413
4501
  /**
@@ -7717,6 +7805,7 @@ var ObjectSchemaService = class extends BaseService {
7717
7805
  return new Map(records.map((r) => [r.id, r.label]));
7718
7806
  });
7719
7807
  });
7808
+ await this.invalidateCachePattern(cacheKeys.allResolvedRelations(this.tenantId));
7720
7809
  }
7721
7810
  return this.convertDBObjectToDefinition(updatedDbObject, dbAttributes);
7722
7811
  }
@@ -9445,8 +9534,8 @@ var RelationService = class extends BaseService {
9445
9534
  * Resolve record IDs to their display labels.
9446
9535
  * Useful for displaying current values in the UI.
9447
9536
  *
9448
- * Uses batch fetching for performance - fetches all records in one query,
9449
- * then groups by objectId to minimize schema lookups.
9537
+ * Uses caching per individual record ID for optimal performance.
9538
+ * Cache key format: `${attributeId}:${recordId}` to handle different displayTemplates.
9450
9539
  *
9451
9540
  * @param ids - Record IDs to resolve
9452
9541
  * @param attributeId - Relation attribute ID to use its displayTemplate for label rendering
@@ -9461,6 +9550,153 @@ var RelationService = class extends BaseService {
9461
9550
  if (!ids || ids.length === 0) {
9462
9551
  return [];
9463
9552
  }
9553
+ const compositeIds = ids.map((id) => `${attributeId}:${id}`);
9554
+ return this.cachedByMany(
9555
+ "resolvedRelation",
9556
+ compositeIds,
9557
+ async (missingCompositeIds) => {
9558
+ const missingRecordIds = missingCompositeIds.map((c) => c.split(":")[1]);
9559
+ return this.fetchResolveIds(missingRecordIds, attributeId);
9560
+ },
9561
+ (item) => `${attributeId}:${item.id}`,
9562
+ cacheTtl.resolvedRelations
9563
+ );
9564
+ }
9565
+ /**
9566
+ * Resolve multiple attribute/IDs batches in a single operation.
9567
+ * Optimized for DataGrid scenarios with multiple relation columns.
9568
+ *
9569
+ * Benefits over multiple resolveIds() calls:
9570
+ * - Single DB query for all records across all attributes
9571
+ * - Deduplication of records referenced by multiple attributes
9572
+ * - Single schema lookup per objectId
9573
+ *
9574
+ * Uses caching per individual record ID for optimal performance.
9575
+ *
9576
+ * @param requests - Array of { attributeId, ids } to resolve
9577
+ * @returns Map of attributeId to resolved options
9578
+ *
9579
+ * @example
9580
+ * ```typescript
9581
+ * const results = await relationService.resolveIdsBatch([
9582
+ * { attributeId: "attr-company", ids: ["rec-1", "rec-2"] },
9583
+ * { attributeId: "attr-contact", ids: ["rec-3", "rec-4"] },
9584
+ * ]);
9585
+ * // { "attr-company": [...], "attr-contact": [...] }
9586
+ * ```
9587
+ */
9588
+ async resolveIdsBatch(requests) {
9589
+ if (!requests || requests.length === 0) {
9590
+ return {};
9591
+ }
9592
+ const validRequests = requests.filter((r) => r.ids && r.ids.length > 0);
9593
+ if (validRequests.length === 0) {
9594
+ return {};
9595
+ }
9596
+ const allCompositeIds = [];
9597
+ const compositeIdsByAttr = /* @__PURE__ */ new Map();
9598
+ for (const req of validRequests) {
9599
+ const composites = req.ids.map((id) => `${req.attributeId}:${id}`);
9600
+ allCompositeIds.push(...composites);
9601
+ compositeIdsByAttr.set(req.attributeId, composites);
9602
+ }
9603
+ const allResolved = await this.cachedByMany(
9604
+ "resolvedRelation",
9605
+ allCompositeIds,
9606
+ (missingCompositeIds) => this.fetchResolveIdsBatch(missingCompositeIds),
9607
+ (item) => item._compositeId,
9608
+ cacheTtl.resolvedRelations
9609
+ );
9610
+ const response = {};
9611
+ const resolvedMap = new Map(allResolved.map((item) => [item._compositeId, item]));
9612
+ for (const req of validRequests) {
9613
+ const composites = _nullishCoalesce(compositeIdsByAttr.get(req.attributeId), () => ( []));
9614
+ const options = [];
9615
+ for (const compositeId of composites) {
9616
+ const resolved = resolvedMap.get(compositeId);
9617
+ if (resolved) {
9618
+ const { _compositeId, ...option } = resolved;
9619
+ options.push(option);
9620
+ }
9621
+ }
9622
+ response[req.attributeId] = options;
9623
+ }
9624
+ return response;
9625
+ }
9626
+ /**
9627
+ * Internal method to fetch and resolve multiple composite IDs at once.
9628
+ * Optimized for batch operations - single DB query for all records.
9629
+ */
9630
+ async fetchResolveIdsBatch(compositeIds) {
9631
+ if (compositeIds.length === 0) {
9632
+ return [];
9633
+ }
9634
+ const parsed = compositeIds.map((c) => {
9635
+ const [attributeId, recordId] = c.split(":");
9636
+ return { compositeId: c, attributeId, recordId };
9637
+ });
9638
+ const uniqueRecordIds = [...new Set(parsed.map((p) => p.recordId))];
9639
+ const uniqueAttributeIds = [...new Set(parsed.map((p) => p.attributeId))];
9640
+ const records = await this.adapter.objectRecords.findByIds(uniqueRecordIds);
9641
+ if (records.length === 0) {
9642
+ return [];
9643
+ }
9644
+ const recordMap = new Map(records.map((r) => [r.id, r]));
9645
+ const attributePromises = uniqueAttributeIds.map((id) => this.findAttributeById(id));
9646
+ const attributes = await Promise.all(attributePromises);
9647
+ const attributeMap = new Map(uniqueAttributeIds.map((id, i) => [id, attributes[i]]));
9648
+ const uniqueObjectIds = [...new Set(records.map((r) => r.objectId))];
9649
+ const schemaPromises = uniqueObjectIds.map((id) => this.schemaService.getObjectSchema(id));
9650
+ const schemas = await Promise.all(schemaPromises);
9651
+ const schemaMap = new Map(uniqueObjectIds.map((id, i) => [id, schemas[i]]));
9652
+ const resolved = [];
9653
+ for (const { compositeId, attributeId, recordId } of parsed) {
9654
+ const record = recordMap.get(recordId);
9655
+ if (!record) {
9656
+ continue;
9657
+ }
9658
+ const objectSchema = schemaMap.get(record.objectId);
9659
+ if (!objectSchema) {
9660
+ continue;
9661
+ }
9662
+ const attribute = attributeMap.get(attributeId);
9663
+ const targetConfig = _optionalChain([attribute, 'optionalAccess', _201 => _201.targets, 'optionalAccess', _202 => _202.find, 'call', _203 => _203((t) => t.object === objectSchema.name)]);
9664
+ const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _204 => _204.displayTemplate]);
9665
+ let label;
9666
+ if (customTemplate) {
9667
+ label = await computeLabelWithRelations(
9668
+ customTemplate,
9669
+ record.values,
9670
+ objectSchema.attributes,
9671
+ async (nestedIds) => {
9672
+ const linkedRecords = await this.adapter.objectRecords.findByIds(nestedIds);
9673
+ return new Map(linkedRecords.map((r) => [r.id, r.label]));
9674
+ }
9675
+ );
9676
+ } else {
9677
+ label = record.label;
9678
+ }
9679
+ resolved.push({
9680
+ _compositeId: compositeId,
9681
+ id: record.id,
9682
+ objectId: record.objectId,
9683
+ objectName: objectSchema.name,
9684
+ objectLabel: objectSchema.label,
9685
+ objectIcon: objectSchema.icon,
9686
+ label
9687
+ });
9688
+ }
9689
+ return resolved;
9690
+ }
9691
+ /**
9692
+ * Internal method to fetch and resolve relation IDs (no caching).
9693
+ * Uses batch fetching for performance - fetches all records in one query,
9694
+ * then groups by objectId to minimize schema lookups.
9695
+ */
9696
+ async fetchResolveIds(ids, attributeId) {
9697
+ if (ids.length === 0) {
9698
+ return [];
9699
+ }
9464
9700
  const attribute = await this.findAttributeById(attributeId);
9465
9701
  const records = await this.adapter.objectRecords.findByIds(ids);
9466
9702
  if (records.length === 0) {
@@ -9478,8 +9714,8 @@ var RelationService = class extends BaseService {
9478
9714
  if (!objectSchema) {
9479
9715
  continue;
9480
9716
  }
9481
- const targetConfig = _optionalChain([attribute, 'optionalAccess', _201 => _201.targets, 'optionalAccess', _202 => _202.find, 'call', _203 => _203((t) => t.object === objectSchema.name)]);
9482
- const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _204 => _204.displayTemplate]);
9717
+ const targetConfig = _optionalChain([attribute, 'optionalAccess', _205 => _205.targets, 'optionalAccess', _206 => _206.find, 'call', _207 => _207((t) => t.object === objectSchema.name)]);
9718
+ const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _208 => _208.displayTemplate]);
9483
9719
  for (const record of objectRecords) {
9484
9720
  let label;
9485
9721
  if (customTemplate) {
@@ -9487,8 +9723,8 @@ var RelationService = class extends BaseService {
9487
9723
  customTemplate,
9488
9724
  record.values,
9489
9725
  objectSchema.attributes,
9490
- async (ids2) => {
9491
- const linkedRecords = await this.adapter.objectRecords.findByIds(ids2);
9726
+ async (nestedIds) => {
9727
+ const linkedRecords = await this.adapter.objectRecords.findByIds(nestedIds);
9492
9728
  return new Map(linkedRecords.map((r) => [r.id, r.label]));
9493
9729
  }
9494
9730
  );
@@ -9624,14 +9860,14 @@ var RollupService = class extends BaseService {
9624
9860
  const sourceSchema = getSchemaByNameFromContext(sourceObjectName);
9625
9861
  let sourceObjectId;
9626
9862
  let reverseRelationAttrName;
9627
- if (_optionalChain([sourceSchema, 'optionalAccess', _205 => _205.id])) {
9863
+ if (_optionalChain([sourceSchema, 'optionalAccess', _209 => _209.id])) {
9628
9864
  sourceObjectId = sourceSchema.id;
9629
9865
  const reverseRelationAttr = sourceSchema.attributes.find((attr) => {
9630
9866
  if (attr.type !== "relation") return false;
9631
9867
  const relationConfig = attr;
9632
- return _optionalChain([relationConfig, 'optionalAccess', _206 => _206.targets, 'optionalAccess', _207 => _207.some, 'call', _208 => _208((t) => t.object === schema.name)]);
9868
+ return _optionalChain([relationConfig, 'optionalAccess', _210 => _210.targets, 'optionalAccess', _211 => _211.some, 'call', _212 => _212((t) => t.object === schema.name)]);
9633
9869
  });
9634
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _209 => _209.name]);
9870
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _213 => _213.name]);
9635
9871
  } else {
9636
9872
  const sourceObject = await this.adapter.objects.findByName(sourceObjectName);
9637
9873
  if (!sourceObject) {
@@ -9642,9 +9878,9 @@ var RollupService = class extends BaseService {
9642
9878
  const reverseRelationAttr = sourceAttributes.find((attr) => {
9643
9879
  if (attr.type !== "relation") return false;
9644
9880
  const relationConfig = attr.config;
9645
- return _optionalChain([relationConfig, 'optionalAccess', _210 => _210.targets, 'optionalAccess', _211 => _211.some, 'call', _212 => _212((t) => t.object === schema.name)]);
9881
+ return _optionalChain([relationConfig, 'optionalAccess', _214 => _214.targets, 'optionalAccess', _215 => _215.some, 'call', _216 => _216((t) => t.object === schema.name)]);
9646
9882
  });
9647
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _213 => _213.name]);
9883
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _217 => _217.name]);
9648
9884
  }
9649
9885
  if (!reverseRelationAttrName) {
9650
9886
  return { value: null, recordCount: 0 };
@@ -9881,7 +10117,7 @@ var RollupService = class extends BaseService {
9881
10117
  }
9882
10118
  for (const rollupDbAttr of rollupAttrs) {
9883
10119
  const rollupConfig = rollupDbAttr.config;
9884
- if (!_optionalChain([rollupConfig, 'optionalAccess', _214 => _214.relationAttribute])) {
10120
+ if (!_optionalChain([rollupConfig, 'optionalAccess', _218 => _218.relationAttribute])) {
9885
10121
  continue;
9886
10122
  }
9887
10123
  const relationAttr = attributes.find(
@@ -9891,7 +10127,7 @@ var RollupService = class extends BaseService {
9891
10127
  continue;
9892
10128
  }
9893
10129
  const relationConfig = relationAttr.config;
9894
- const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _215 => _215.targets, 'optionalAccess', _216 => _216.some, 'call', _217 => _217(
10130
+ const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _219 => _219.targets, 'optionalAccess', _220 => _220.some, 'call', _221 => _221(
9895
10131
  (t) => t.object === changedSchema.name
9896
10132
  )]);
9897
10133
  if (!targetsChangedObject) {
@@ -9918,11 +10154,11 @@ var RecordService = class extends BaseService {
9918
10154
  constructor(adapter, options) {
9919
10155
  super(adapter);
9920
10156
  this.schemaService = new ObjectSchemaService(adapter, registry, {
9921
- auditService: _optionalChain([options, 'optionalAccess', _218 => _218.auditService])
10157
+ auditService: _optionalChain([options, 'optionalAccess', _222 => _222.auditService])
9922
10158
  });
9923
- this.permissionService = _optionalChain([options, 'optionalAccess', _219 => _219.permissionService]);
9924
- this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _220 => _220.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
9925
- this.policyRegistry = _optionalChain([options, 'optionalAccess', _221 => _221.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _222 => _222.policyRegistry]), () => ( defaultPolicyRegistry));
10159
+ this.permissionService = _optionalChain([options, 'optionalAccess', _223 => _223.permissionService]);
10160
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _224 => _224.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
10161
+ this.policyRegistry = _optionalChain([options, 'optionalAccess', _225 => _225.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _226 => _226.policyRegistry]), () => ( defaultPolicyRegistry));
9926
10162
  this.queryService = new RecordQueryService(adapter, this.schemaService, {
9927
10163
  permissionService: this.permissionService,
9928
10164
  policyRegistry: this.policyRegistry
@@ -9932,7 +10168,7 @@ var RecordService = class extends BaseService {
9932
10168
  });
9933
10169
  this.userService = new UserService(adapter);
9934
10170
  this.rollupService = new RollupService(adapter);
9935
- this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _223 => _223.hookRegistry]), () => ( new NoopHookRegistry()));
10171
+ this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _227 => _227.hookRegistry]), () => ( new NoopHookRegistry()));
9936
10172
  this.labelResolver = {
9937
10173
  resolveRelationIds: (ids, attrId) => this.relationService.resolveIds(ids, attrId),
9938
10174
  findRecordLabels: (ids) => this.adapter.objectRecords.findByIds(ids)
@@ -9964,21 +10200,21 @@ var RecordService = class extends BaseService {
9964
10200
  schema,
9965
10201
  this.tenantId,
9966
10202
  dataWithDefaults,
9967
- _optionalChain([options, 'optionalAccess', _224 => _224.hookMetadata])
10203
+ _optionalChain([options, 'optionalAccess', _228 => _228.hookMetadata])
9968
10204
  );
9969
- if (!_optionalChain([options, 'optionalAccess', _225 => _225.skipHooks])) {
10205
+ if (!_optionalChain([options, 'optionalAccess', _229 => _229.skipHooks])) {
9970
10206
  await this.hookRegistry.execute("beforeCreate", schema.name, hookCtx);
9971
10207
  }
9972
- if (_optionalChain([options, 'optionalAccess', _226 => _226.validate]) !== false) {
9973
- if (_optionalChain([options, 'optionalAccess', _227 => _227.allowDraft])) {
10208
+ if (_optionalChain([options, 'optionalAccess', _230 => _230.validate]) !== false) {
10209
+ if (_optionalChain([options, 'optionalAccess', _231 => _231.allowDraft])) {
9974
10210
  validateDraftOrThrow(schema, dataWithDefaults);
9975
10211
  } else {
9976
10212
  validateObjectOrThrow(schema, dataWithDefaults);
9977
10213
  }
9978
- if (!_optionalChain([options, 'optionalAccess', _228 => _228.skipRelationValidation])) {
10214
+ if (!_optionalChain([options, 'optionalAccess', _232 => _232.skipRelationValidation])) {
9979
10215
  await this.relationService.validateRelationsOrThrow(schema, dataWithDefaults);
9980
10216
  }
9981
- if (!_optionalChain([options, 'optionalAccess', _229 => _229.skipUserValidation])) {
10217
+ if (!_optionalChain([options, 'optionalAccess', _233 => _233.skipUserValidation])) {
9982
10218
  await this.userService.validateUsersOrThrow(schema, dataWithDefaults);
9983
10219
  }
9984
10220
  }
@@ -9989,10 +10225,10 @@ var RecordService = class extends BaseService {
9989
10225
  data: dataWithDefaults,
9990
10226
  label,
9991
10227
  completionStatus,
9992
- metadata: _optionalChain([options, 'optionalAccess', _230 => _230.metadata]),
10228
+ metadata: _optionalChain([options, 'optionalAccess', _234 => _234.metadata]),
9993
10229
  createdBy: this.userId
9994
10230
  });
9995
- if (!_optionalChain([options, 'optionalAccess', _231 => _231.skipHooks])) {
10231
+ if (!_optionalChain([options, 'optionalAccess', _235 => _235.skipHooks])) {
9996
10232
  const afterCtx = {
9997
10233
  ...hookCtx,
9998
10234
  recordId: record.id,
@@ -10012,7 +10248,7 @@ var RecordService = class extends BaseService {
10012
10248
  objectId: schema.id,
10013
10249
  recordId: record.id,
10014
10250
  recordLabel: record.label,
10015
- metadata: _optionalChain([options, 'optionalAccess', _232 => _232.hookMetadata])
10251
+ metadata: _optionalChain([options, 'optionalAccess', _236 => _236.hookMetadata])
10016
10252
  });
10017
10253
  }
10018
10254
  return record;
@@ -10033,7 +10269,7 @@ var RecordService = class extends BaseService {
10033
10269
  return null;
10034
10270
  }
10035
10271
  const schema = await this.schemaService.getObjectSchema(record.objectId);
10036
- if (!_optionalChain([options, 'optionalAccess', _233 => _233.skipPolicyCheck])) {
10272
+ if (!_optionalChain([options, 'optionalAccess', _237 => _237.skipPolicyCheck])) {
10037
10273
  const policy = getPolicy(this.policyRegistry, this.userId, schema.name);
10038
10274
  if (policy) {
10039
10275
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
@@ -10043,10 +10279,10 @@ var RecordService = class extends BaseService {
10043
10279
  }
10044
10280
  }
10045
10281
  let enrichedRecord = record;
10046
- if (!_optionalChain([options, 'optionalAccess', _234 => _234.skipFormulas])) {
10282
+ if (!_optionalChain([options, 'optionalAccess', _238 => _238.skipFormulas])) {
10047
10283
  enrichedRecord = enrichWithFormulas(record, schema);
10048
10284
  }
10049
- if (_optionalChain([options, 'optionalAccess', _235 => _235.includeSchema])) {
10285
+ if (_optionalChain([options, 'optionalAccess', _239 => _239.includeSchema])) {
10050
10286
  const recordWithSchema = enrichedRecord;
10051
10287
  recordWithSchema.schema = schema;
10052
10288
  return recordWithSchema;
@@ -10089,9 +10325,9 @@ var RecordService = class extends BaseService {
10089
10325
  existing,
10090
10326
  mergedData,
10091
10327
  changedAttributes,
10092
- _optionalChain([options, 'optionalAccess', _236 => _236.hookMetadata])
10328
+ _optionalChain([options, 'optionalAccess', _240 => _240.hookMetadata])
10093
10329
  );
10094
- if (!_optionalChain([options, 'optionalAccess', _237 => _237.skipHooks])) {
10330
+ if (!_optionalChain([options, 'optionalAccess', _241 => _241.skipHooks])) {
10095
10331
  await this.hookRegistry.execute("beforeUpdate", schema.name, hookCtx);
10096
10332
  }
10097
10333
  const hookModifiedValues = {};
@@ -10100,19 +10336,19 @@ var RecordService = class extends BaseService {
10100
10336
  hookModifiedValues[key] = hookCtx.newValues[key];
10101
10337
  }
10102
10338
  }
10103
- if (_optionalChain([options, 'optionalAccess', _238 => _238.validate]) !== false) {
10104
- if (_optionalChain([options, 'optionalAccess', _239 => _239.partial])) {
10339
+ if (_optionalChain([options, 'optionalAccess', _242 => _242.validate]) !== false) {
10340
+ if (_optionalChain([options, 'optionalAccess', _243 => _243.partial])) {
10105
10341
  validateDraftOrThrow(schema, mergedData);
10106
10342
  } else {
10107
10343
  validateObjectOrThrow(schema, mergedData);
10108
10344
  }
10109
- if (!_optionalChain([options, 'optionalAccess', _240 => _240.skipRelationValidation])) {
10345
+ if (!_optionalChain([options, 'optionalAccess', _244 => _244.skipRelationValidation])) {
10110
10346
  await this.relationService.validateRelationsOrThrow(schema, {
10111
10347
  ...data,
10112
10348
  ...hookModifiedValues
10113
10349
  });
10114
10350
  }
10115
- if (!_optionalChain([options, 'optionalAccess', _241 => _241.skipUserValidation])) {
10351
+ if (!_optionalChain([options, 'optionalAccess', _245 => _245.skipUserValidation])) {
10116
10352
  await this.userService.validateUsersOrThrow(schema, {
10117
10353
  ...data,
10118
10354
  ...hookModifiedValues
@@ -10128,7 +10364,7 @@ var RecordService = class extends BaseService {
10128
10364
  __label: label,
10129
10365
  __lastUpdatedBy: this.userId
10130
10366
  };
10131
- if (_optionalChain([options, 'optionalAccess', _242 => _242.metadata]) !== void 0) {
10367
+ if (_optionalChain([options, 'optionalAccess', _246 => _246.metadata]) !== void 0) {
10132
10368
  const existingMetadata = _nullishCoalesce(existing.metadata, () => ( {}));
10133
10369
  const mergedMetadata = { ...existingMetadata, ...options.metadata };
10134
10370
  const cleanedMetadata = Object.fromEntries(
@@ -10140,7 +10376,8 @@ var RecordService = class extends BaseService {
10140
10376
  await this.invalidateCache(cacheKeys.record(this.tenantId, recordId));
10141
10377
  await this.invalidateLists("allRecordLists", existing.objectId);
10142
10378
  await this.invalidateLists("allSearchResults", existing.objectId);
10143
- if (!_optionalChain([options, 'optionalAccess', _243 => _243.skipHooks])) {
10379
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10380
+ if (!_optionalChain([options, 'optionalAccess', _247 => _247.skipHooks])) {
10144
10381
  const afterCtx = {
10145
10382
  ...hookCtx,
10146
10383
  record: updated
@@ -10155,7 +10392,7 @@ var RecordService = class extends BaseService {
10155
10392
  if (this.auditService && this.userId && allChangedAttributes.length > 0) {
10156
10393
  const changes = allChangedAttributes.map((attr) => ({
10157
10394
  field: attr,
10158
- oldValue: _optionalChain([hookCtx, 'access', _244 => _244.oldValues, 'optionalAccess', _245 => _245[attr]]),
10395
+ oldValue: _optionalChain([hookCtx, 'access', _248 => _248.oldValues, 'optionalAccess', _249 => _249[attr]]),
10159
10396
  newValue: hookCtx.newValues[attr]
10160
10397
  }));
10161
10398
  await this.auditService.logRecordAction({
@@ -10166,7 +10403,7 @@ var RecordService = class extends BaseService {
10166
10403
  recordId: updated.id,
10167
10404
  recordLabel: updated.label,
10168
10405
  changes,
10169
- metadata: _optionalChain([options, 'optionalAccess', _246 => _246.hookMetadata])
10406
+ metadata: _optionalChain([options, 'optionalAccess', _250 => _250.hookMetadata])
10170
10407
  });
10171
10408
  }
10172
10409
  return updated;
@@ -10189,17 +10426,17 @@ var RecordService = class extends BaseService {
10189
10426
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
10190
10427
  checkRecordDeleteOrThrow(policy, record, ctx);
10191
10428
  }
10192
- if (_optionalChain([options, 'optionalAccess', _247 => _247.checkSystem]) && schema.system) {
10429
+ if (_optionalChain([options, 'optionalAccess', _251 => _251.checkSystem]) && schema.system) {
10193
10430
  throw new ProtectedResourceError("object", schema.name, "delete");
10194
10431
  }
10195
- if (!_optionalChain([options, 'optionalAccess', _248 => _248.skipReferenceCheck])) {
10432
+ if (!_optionalChain([options, 'optionalAccess', _252 => _252.skipReferenceCheck])) {
10196
10433
  const references = await this.adapter.objectRecords.countRecordsReferencingId(recordId);
10197
10434
  if (references.length > 0) {
10198
10435
  throw new RecordReferencedError(recordId, references);
10199
10436
  }
10200
10437
  }
10201
- const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _249 => _249.hookMetadata]));
10202
- if (!_optionalChain([options, 'optionalAccess', _250 => _250.skipHooks])) {
10438
+ const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _253 => _253.hookMetadata]));
10439
+ if (!_optionalChain([options, 'optionalAccess', _254 => _254.skipHooks])) {
10203
10440
  await this.hookRegistry.execute("beforeDelete", schema.name, hookCtx);
10204
10441
  }
10205
10442
  await this.adapter.objectRecords.delete(recordId);
@@ -10207,7 +10444,8 @@ var RecordService = class extends BaseService {
10207
10444
  await this.invalidateLists("allRecordLists", record.objectId);
10208
10445
  await this.invalidateLists("allSearchResults", record.objectId);
10209
10446
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10210
- if (!_optionalChain([options, 'optionalAccess', _251 => _251.skipHooks])) {
10447
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10448
+ if (!_optionalChain([options, 'optionalAccess', _255 => _255.skipHooks])) {
10211
10449
  await this.hookRegistry.execute("afterDelete", schema.name, hookCtx);
10212
10450
  }
10213
10451
  await recalculateParentRollups(record, schema, this.rollupContext);
@@ -10219,7 +10457,7 @@ var RecordService = class extends BaseService {
10219
10457
  objectId: schema.id,
10220
10458
  recordId: record.id,
10221
10459
  recordLabel: record.label,
10222
- metadata: _optionalChain([options, 'optionalAccess', _252 => _252.hookMetadata])
10460
+ metadata: _optionalChain([options, 'optionalAccess', _256 => _256.hookMetadata])
10223
10461
  });
10224
10462
  }
10225
10463
  }
@@ -10235,6 +10473,7 @@ var RecordService = class extends BaseService {
10235
10473
  await this.invalidateLists("allRecordLists", record.objectId);
10236
10474
  await this.invalidateLists("allSearchResults", record.objectId);
10237
10475
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10476
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10238
10477
  }
10239
10478
  // ============================================================================
10240
10479
  // RESTORE
@@ -10253,8 +10492,8 @@ var RecordService = class extends BaseService {
10253
10492
  }
10254
10493
  const schema = await this.schemaService.getObjectSchema(record.objectId);
10255
10494
  await checkPermission(this.permissionService, this.userId, schema.name, "update");
10256
- const hookCtx = createContextForRestore(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _253 => _253.hookMetadata]));
10257
- if (!_optionalChain([options, 'optionalAccess', _254 => _254.skipHooks])) {
10495
+ const hookCtx = createContextForRestore(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _257 => _257.hookMetadata]));
10496
+ if (!_optionalChain([options, 'optionalAccess', _258 => _258.skipHooks])) {
10258
10497
  await this.hookRegistry.execute("beforeRestore", schema.name, hookCtx);
10259
10498
  }
10260
10499
  const restored = await this.adapter.objectRecords.restore(recordId);
@@ -10262,7 +10501,8 @@ var RecordService = class extends BaseService {
10262
10501
  await this.invalidateLists("allRecordLists", record.objectId);
10263
10502
  await this.invalidateLists("allSearchResults", record.objectId);
10264
10503
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10265
- if (!_optionalChain([options, 'optionalAccess', _255 => _255.skipHooks])) {
10504
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10505
+ if (!_optionalChain([options, 'optionalAccess', _259 => _259.skipHooks])) {
10266
10506
  const afterCtx = {
10267
10507
  ...hookCtx,
10268
10508
  record: restored
@@ -10277,7 +10517,7 @@ var RecordService = class extends BaseService {
10277
10517
  objectId: schema.id,
10278
10518
  recordId: restored.id,
10279
10519
  recordLabel: restored.label,
10280
- metadata: _optionalChain([options, 'optionalAccess', _256 => _256.hookMetadata])
10520
+ metadata: _optionalChain([options, 'optionalAccess', _260 => _260.hookMetadata])
10281
10521
  });
10282
10522
  }
10283
10523
  return restored;
@@ -10480,8 +10720,8 @@ var RollupScheduler = class {
10480
10720
  this.getSchemaById = getSchemaById;
10481
10721
  this.pending = /* @__PURE__ */ new Map();
10482
10722
  this.rollupService = new RollupService(adapter);
10483
- this.debounceMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _257 => _257.debounceMs]), () => ( 100));
10484
- this.maxPending = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _258 => _258.maxPending]), () => ( 100));
10723
+ this.debounceMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _261 => _261.debounceMs]), () => ( 100));
10724
+ this.maxPending = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _262 => _262.maxPending]), () => ( 100));
10485
10725
  }
10486
10726
  /**
10487
10727
  * Schedule a rollup recalculation for a parent record.
@@ -10559,7 +10799,7 @@ var WorkflowService = class extends BaseService {
10559
10799
  if (Array.isArray(options)) {
10560
10800
  this.systemWorkflows = new Map(options.map((w) => [w.name, w]));
10561
10801
  } else {
10562
- this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _259 => _259.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
10802
+ this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _263 => _263.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
10563
10803
  }
10564
10804
  }
10565
10805
  // ============================================================================
@@ -10862,9 +11102,9 @@ var WorkflowInstanceService = class extends BaseService {
10862
11102
  constructor(adapter, workflowService, options) {
10863
11103
  super(adapter);
10864
11104
  this.workflowService = workflowService;
10865
- this.executorRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _260 => _260.executorRegistry]), () => ( getDefaultExecutorRegistry()));
10866
- this.schemaService = _optionalChain([options, 'optionalAccess', _261 => _261.schemaService]);
10867
- this.recordService = _optionalChain([options, 'optionalAccess', _262 => _262.recordService]);
11105
+ this.executorRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _264 => _264.executorRegistry]), () => ( getDefaultExecutorRegistry()));
11106
+ this.schemaService = _optionalChain([options, 'optionalAccess', _265 => _265.schemaService]);
11107
+ this.recordService = _optionalChain([options, 'optionalAccess', _266 => _266.recordService]);
10868
11108
  }
10869
11109
  /**
10870
11110
  * Start a new workflow instance
@@ -10990,7 +11230,7 @@ var WorkflowInstanceService = class extends BaseService {
10990
11230
  if (!this.adapter.workflowInstances) {
10991
11231
  return { instances: [], total: 0 };
10992
11232
  }
10993
- if (_optionalChain([options, 'optionalAccess', _263 => _263.workflowName])) {
11233
+ if (_optionalChain([options, 'optionalAccess', _267 => _267.workflowName])) {
10994
11234
  const instances2 = await this.getInstancesByWorkflow(options.workflowName);
10995
11235
  let filtered = instances2;
10996
11236
  if (options.status) {
@@ -11004,11 +11244,11 @@ var WorkflowInstanceService = class extends BaseService {
11004
11244
  return { instances: paginated, total: total2 };
11005
11245
  }
11006
11246
  const { instances: dbInstances, total } = await this.adapter.workflowInstances.list({
11007
- limit: _optionalChain([options, 'optionalAccess', _264 => _264.limit]),
11008
- offset: _optionalChain([options, 'optionalAccess', _265 => _265.offset])
11247
+ limit: _optionalChain([options, 'optionalAccess', _268 => _268.limit]),
11248
+ offset: _optionalChain([options, 'optionalAccess', _269 => _269.offset])
11009
11249
  });
11010
11250
  let instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
11011
- if (_optionalChain([options, 'optionalAccess', _266 => _266.status])) {
11251
+ if (_optionalChain([options, 'optionalAccess', _270 => _270.status])) {
11012
11252
  instances = instances.filter((i) => i.status === options.status);
11013
11253
  }
11014
11254
  return { instances, total };
@@ -11028,9 +11268,9 @@ var WorkflowInstanceService = class extends BaseService {
11028
11268
  return { instances: [], total: 0 };
11029
11269
  }
11030
11270
  const { instances: dbInstances, total } = await this.adapter.workflowInstances.findByRecordInSlots(objectName, recordId, {
11031
- status: _optionalChain([options, 'optionalAccess', _267 => _267.status]),
11032
- limit: _optionalChain([options, 'optionalAccess', _268 => _268.limit]),
11033
- offset: _optionalChain([options, 'optionalAccess', _269 => _269.offset])
11271
+ status: _optionalChain([options, 'optionalAccess', _271 => _271.status]),
11272
+ limit: _optionalChain([options, 'optionalAccess', _272 => _272.limit]),
11273
+ offset: _optionalChain([options, 'optionalAccess', _273 => _273.offset])
11034
11274
  });
11035
11275
  const instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
11036
11276
  return { instances, total };
@@ -11406,7 +11646,7 @@ var WorkflowParticipationService = class extends BaseService {
11406
11646
  SchemaErrorCode.RECORD_NOT_FOUND
11407
11647
  );
11408
11648
  }
11409
- const template = _optionalChain([instance, 'access', _270 => _270.workflowSnapshot, 'access', _271 => _271.participants, 'optionalAccess', _272 => _272.find, 'call', _273 => _273(
11649
+ const template = _optionalChain([instance, 'access', _274 => _274.workflowSnapshot, 'access', _275 => _275.participants, 'optionalAccess', _276 => _276.find, 'call', _277 => _277(
11410
11650
  (p) => p.id === input.participantTemplateId
11411
11651
  )]);
11412
11652
  if (!template) {
@@ -11708,7 +11948,7 @@ var WorkflowRelationService = class extends BaseService {
11708
11948
  if (attr.type !== "relation") continue;
11709
11949
  for (const slot of slots) {
11710
11950
  const slotData = context.slots[slot.id];
11711
- const slotRecordId = _optionalChain([slotData, 'optionalAccess', _274 => _274.id]);
11951
+ const slotRecordId = _optionalChain([slotData, 'optionalAccess', _278 => _278.id]);
11712
11952
  if (!slotRecordId) continue;
11713
11953
  const targetsSlotObject = attr.targets.some(
11714
11954
  (t) => t.object === slot.objectName
@@ -11773,7 +12013,7 @@ var WorkflowRelationService = class extends BaseService {
11773
12013
  var UserProfileService = class extends BaseService {
11774
12014
  constructor(adapter, options) {
11775
12015
  super(adapter);
11776
- this.auditService = _optionalChain([options, 'optionalAccess', _275 => _275.auditService]);
12016
+ this.auditService = _optionalChain([options, 'optionalAccess', _279 => _279.auditService]);
11777
12017
  }
11778
12018
  // ============================================================================
11779
12019
  // CACHE MANAGEMENT
@@ -11936,7 +12176,7 @@ var UserProfileService = class extends BaseService {
11936
12176
  */
11937
12177
  async deleteProfile(profileId, options) {
11938
12178
  const profile = await this.getProfileOrThrow(profileId);
11939
- if (_optionalChain([options, 'optionalAccess', _276 => _276.checkAdmin])) {
12179
+ if (_optionalChain([options, 'optionalAccess', _280 => _280.checkAdmin])) {
11940
12180
  if (profile.role === "admin") {
11941
12181
  const adminCount = await this.adapter.userProfiles.countByRole("admin");
11942
12182
  if (adminCount <= 1) {
@@ -12011,7 +12251,7 @@ var UserProfileService = class extends BaseService {
12011
12251
  */
12012
12252
  async hasRole(profileId, role) {
12013
12253
  const profile = await this.getProfile(profileId);
12014
- return _optionalChain([profile, 'optionalAccess', _277 => _277.role]) === role;
12254
+ return _optionalChain([profile, 'optionalAccess', _281 => _281.role]) === role;
12015
12255
  }
12016
12256
  /**
12017
12257
  * Check if user is admin
@@ -12068,7 +12308,7 @@ var UserProfileService = class extends BaseService {
12068
12308
  var FileService = class extends BaseService {
12069
12309
  constructor(adapter, options) {
12070
12310
  super(adapter);
12071
- this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _278 => _278.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
12311
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _282 => _282.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
12072
12312
  }
12073
12313
  // ============================================================================
12074
12314
  // UPLOAD (requires StorageAdapter)
@@ -12200,7 +12440,7 @@ var FileService = class extends BaseService {
12200
12440
  */
12201
12441
  async getFile(fileId) {
12202
12442
  const file2 = await this.adapter.files.findById(fileId);
12203
- if (_optionalChain([file2, 'optionalAccess', _279 => _279.deletedAt])) {
12443
+ if (_optionalChain([file2, 'optionalAccess', _283 => _283.deletedAt])) {
12204
12444
  return null;
12205
12445
  }
12206
12446
  return file2;
@@ -12262,12 +12502,12 @@ var FileService = class extends BaseService {
12262
12502
  */
12263
12503
  async deleteFile(fileId, options) {
12264
12504
  const file2 = await this.getFileOrThrow(fileId);
12265
- if (_optionalChain([options, 'optionalAccess', _280 => _280.checkOwnership]) && options.userId) {
12505
+ if (_optionalChain([options, 'optionalAccess', _284 => _284.checkOwnership]) && options.userId) {
12266
12506
  if (file2.uploadedBy !== options.userId) {
12267
12507
  throw new Error("You can only delete files you uploaded");
12268
12508
  }
12269
12509
  }
12270
- if (_optionalChain([options, 'optionalAccess', _281 => _281.hard])) {
12510
+ if (_optionalChain([options, 'optionalAccess', _285 => _285.hard])) {
12271
12511
  await this.adapter.files.hardDelete(fileId);
12272
12512
  } else {
12273
12513
  await this.adapter.files.delete(fileId);
@@ -12298,7 +12538,7 @@ var FileService = class extends BaseService {
12298
12538
  }
12299
12539
  const file2 = await this.getFileOrThrow(fileId);
12300
12540
  await this.adapter.storage.delete(file2.storagePath);
12301
- if (_optionalChain([options, 'optionalAccess', _282 => _282.hard])) {
12541
+ if (_optionalChain([options, 'optionalAccess', _286 => _286.hard])) {
12302
12542
  await this.adapter.files.hardDelete(fileId);
12303
12543
  } else {
12304
12544
  await this.adapter.files.delete(fileId);
@@ -12325,10 +12565,10 @@ var FileService = class extends BaseService {
12325
12565
  if (!file2) {
12326
12566
  continue;
12327
12567
  }
12328
- if (_optionalChain([options, 'optionalAccess', _283 => _283.deleteFromStorage]) && this.adapter.storage) {
12568
+ if (_optionalChain([options, 'optionalAccess', _287 => _287.deleteFromStorage]) && this.adapter.storage) {
12329
12569
  await this.adapter.storage.delete(file2.storagePath);
12330
12570
  }
12331
- if (_optionalChain([options, 'optionalAccess', _284 => _284.hard])) {
12571
+ if (_optionalChain([options, 'optionalAccess', _288 => _288.hard])) {
12332
12572
  await this.adapter.files.hardDelete(fileId);
12333
12573
  } else {
12334
12574
  await this.adapter.files.delete(fileId);
@@ -12339,7 +12579,7 @@ var FileService = class extends BaseService {
12339
12579
  actorId: this.userId,
12340
12580
  fileId,
12341
12581
  fileName: file2.name,
12342
- metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _285 => _285.deleteFromStorage]), () => ( false)) }
12582
+ metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _289 => _289.deleteFromStorage]), () => ( false)) }
12343
12583
  });
12344
12584
  }
12345
12585
  }
@@ -12423,7 +12663,7 @@ var FileService = class extends BaseService {
12423
12663
  return true;
12424
12664
  }
12425
12665
  if (file2.visibility === "restricted") {
12426
- return _nullishCoalesce(_optionalChain([file2, 'access', _286 => _286.allowedUsers, 'optionalAccess', _287 => _287.includes, 'call', _288 => _288(userId)]), () => ( false));
12666
+ return _nullishCoalesce(_optionalChain([file2, 'access', _290 => _290.allowedUsers, 'optionalAccess', _291 => _291.includes, 'call', _292 => _292(userId)]), () => ( false));
12427
12667
  }
12428
12668
  return false;
12429
12669
  }
@@ -12588,10 +12828,10 @@ var GlobalSearchService = class extends BaseService {
12588
12828
  */
12589
12829
  async executeSearch(query, options) {
12590
12830
  return await this.adapter.objectRecords.globalSearch(query, {
12591
- limit: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _289 => _289.limit]), () => ( 20)),
12592
- offset: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _290 => _290.offset]), () => ( 0)),
12593
- objectNames: _optionalChain([options, 'optionalAccess', _291 => _291.objectNames]),
12594
- includeObjectInfo: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _292 => _292.includeObjectInfo]), () => ( true))
12831
+ limit: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _293 => _293.limit]), () => ( 20)),
12832
+ offset: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _294 => _294.offset]), () => ( 0)),
12833
+ objectNames: _optionalChain([options, 'optionalAccess', _295 => _295.objectNames]),
12834
+ includeObjectInfo: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _296 => _296.includeObjectInfo]), () => ( true))
12595
12835
  });
12596
12836
  }
12597
12837
  /**
@@ -12641,7 +12881,7 @@ var PermissionService = class extends BaseService {
12641
12881
  }
12642
12882
  this.permissionsRepo = adapter.permissions;
12643
12883
  this.permissionCache = _nullishCoalesce(adapter.cache, () => ( new NoopCacheAdapter()));
12644
- this.auditService = _optionalChain([options, 'optionalAccess', _293 => _293.auditService]);
12884
+ this.auditService = _optionalChain([options, 'optionalAccess', _297 => _297.auditService]);
12645
12885
  }
12646
12886
  // ============================================================================
12647
12887
  // PERMISSION CHECKS
@@ -12660,11 +12900,11 @@ var PermissionService = class extends BaseService {
12660
12900
  return true;
12661
12901
  }
12662
12902
  const wildcardPerms = permissions.objectPermissions["*"];
12663
- if (_optionalChain([wildcardPerms, 'optionalAccess', _294 => _294.includes, 'call', _295 => _295(action)])) {
12903
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _298 => _298.includes, 'call', _299 => _299(action)])) {
12664
12904
  return true;
12665
12905
  }
12666
12906
  const objectPerms = permissions.objectPermissions[objectName];
12667
- return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _296 => _296.includes, 'call', _297 => _297(action)]), () => ( false));
12907
+ return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _300 => _300.includes, 'call', _301 => _301(action)]), () => ( false));
12668
12908
  }
12669
12909
  /**
12670
12910
  * Check if user can access an object, throw ForbiddenError if not.
@@ -12719,12 +12959,12 @@ var PermissionService = class extends BaseService {
12719
12959
  if (permissions.isAdmin) {
12720
12960
  return true;
12721
12961
  }
12722
- const wildcardPerms = _optionalChain([permissions, 'access', _298 => _298.systemPermissions, 'optionalAccess', _299 => _299["*"]]);
12723
- if (_optionalChain([wildcardPerms, 'optionalAccess', _300 => _300.includes, 'call', _301 => _301(action)])) {
12962
+ const wildcardPerms = _optionalChain([permissions, 'access', _302 => _302.systemPermissions, 'optionalAccess', _303 => _303["*"]]);
12963
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _304 => _304.includes, 'call', _305 => _305(action)])) {
12724
12964
  return true;
12725
12965
  }
12726
- const resourcePerms = _optionalChain([permissions, 'access', _302 => _302.systemPermissions, 'optionalAccess', _303 => _303[resource]]);
12727
- return _nullishCoalesce(_optionalChain([resourcePerms, 'optionalAccess', _304 => _304.includes, 'call', _305 => _305(action)]), () => ( false));
12966
+ const resourcePerms = _optionalChain([permissions, 'access', _306 => _306.systemPermissions, 'optionalAccess', _307 => _307[resource]]);
12967
+ return _nullishCoalesce(_optionalChain([resourcePerms, 'optionalAccess', _308 => _308.includes, 'call', _309 => _309(action)]), () => ( false));
12728
12968
  }
12729
12969
  /**
12730
12970
  * Check if user can access a system resource, throw ForbiddenError if not.
@@ -12753,8 +12993,8 @@ var PermissionService = class extends BaseService {
12753
12993
  if (permissions.isAdmin) {
12754
12994
  return { canRead: true, canCreate: true, canUpdate: true, canDelete: true };
12755
12995
  }
12756
- const wildcardPerms = _nullishCoalesce(_optionalChain([permissions, 'access', _306 => _306.systemPermissions, 'optionalAccess', _307 => _307["*"]]), () => ( []));
12757
- const resourcePerms = _nullishCoalesce(_optionalChain([permissions, 'access', _308 => _308.systemPermissions, 'optionalAccess', _309 => _309[resource]]), () => ( []));
12996
+ const wildcardPerms = _nullishCoalesce(_optionalChain([permissions, 'access', _310 => _310.systemPermissions, 'optionalAccess', _311 => _311["*"]]), () => ( []));
12997
+ const resourcePerms = _nullishCoalesce(_optionalChain([permissions, 'access', _312 => _312.systemPermissions, 'optionalAccess', _313 => _313[resource]]), () => ( []));
12758
12998
  const allPerms = /* @__PURE__ */ new Set([...wildcardPerms, ...resourcePerms]);
12759
12999
  return {
12760
13000
  canRead: allPerms.has("read"),
@@ -12896,7 +13136,7 @@ var PermissionService = class extends BaseService {
12896
13136
  action: "role.updated",
12897
13137
  actorId: this.userId,
12898
13138
  roleId,
12899
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _310 => _310.label]), () => ( roleId)),
13139
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _314 => _314.label]), () => ( roleId)),
12900
13140
  metadata: { permissionsUpdated: true, permissionCount: permissions.length }
12901
13141
  });
12902
13142
  }
@@ -12926,7 +13166,7 @@ var PermissionService = class extends BaseService {
12926
13166
  action: "role.assigned",
12927
13167
  actorId: this.userId,
12928
13168
  roleId,
12929
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _311 => _311.label]), () => ( roleId)),
13169
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _315 => _315.label]), () => ( roleId)),
12930
13170
  targetUserId: userProfileId
12931
13171
  });
12932
13172
  }
@@ -12944,7 +13184,7 @@ var PermissionService = class extends BaseService {
12944
13184
  action: "role.revoked",
12945
13185
  actorId: this.userId,
12946
13186
  roleId,
12947
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _312 => _312.label]), () => ( roleId)),
13187
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _316 => _316.label]), () => ( roleId)),
12948
13188
  targetUserId: userProfileId
12949
13189
  });
12950
13190
  }