@stndrds/schema 0.1.0-alpha.47 → 0.1.0-alpha.49

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.
@@ -323,7 +323,14 @@ function initializePinCodeService(salt) {
323
323
  }
324
324
 
325
325
  // src/runtime/cache.ts
326
- var _crypto = require('crypto');
326
+ function fnv1aHash(str) {
327
+ let hash = 2166136261;
328
+ for (let i = 0; i < str.length; i++) {
329
+ hash ^= str.charCodeAt(i);
330
+ hash = hash * 16777619 >>> 0;
331
+ }
332
+ return hash.toString(16).padStart(8, "0");
333
+ }
327
334
  function hashOptions(options) {
328
335
  if (options === null || options === void 0 || typeof options === "object" && Object.keys(options).length === 0) {
329
336
  return "default";
@@ -340,7 +347,7 @@ function hashOptions(options) {
340
347
  }
341
348
  return value;
342
349
  });
343
- return _crypto.createHash.call(void 0, "md5").update(sortedJson).digest("hex").slice(0, 8);
350
+ return fnv1aHash(sortedJson);
344
351
  }
345
352
  var cacheKeys = {
346
353
  // -------------------------------------------------------------------------
@@ -369,6 +376,12 @@ var cacheKeys = {
369
376
  // -------------------------------------------------------------------------
370
377
  /** Relation options for an attribute */
371
378
  relationOptions: (tenantId, attrId, hash) => `rel:${tenantId}:${attrId}:${hash}`,
379
+ /**
380
+ * Resolved relation by composite ID.
381
+ * Composite ID format: `${attributeId}:${recordId}`
382
+ * Used by cachedByMany in RelationService.resolveIds()
383
+ */
384
+ resolvedRelation: (tenantId, compositeId) => `relres:${tenantId}:${compositeId}`,
372
385
  // -------------------------------------------------------------------------
373
386
  // Rollups - TTL: 2 minutes (high volatility)
374
387
  // -------------------------------------------------------------------------
@@ -408,6 +421,19 @@ var cacheKeys = {
408
421
  allPermissions: (tenantId) => `perms:${tenantId}:*`,
409
422
  /** All relation cache for a tenant */
410
423
  allRelations: (tenantId) => `rel:${tenantId}:*`,
424
+ /** All resolved relations cache for a tenant */
425
+ allResolvedRelations: (tenantId) => `relres:${tenantId}:*`,
426
+ /**
427
+ * Resolved relations for a specific record (all attributeId variants).
428
+ * Pattern matches `relres:${tenantId}:*:${recordId}` to invalidate
429
+ * all cached labels for a record regardless of which attribute resolved it.
430
+ */
431
+ resolvedRelationsByRecord: (tenantId, recordId) => `relres:${tenantId}:*:${recordId}`,
432
+ /**
433
+ * Resolved relations for a specific attribute.
434
+ * Invalidates when a relation's displayTemplate changes.
435
+ */
436
+ resolvedRelationsByAttr: (tenantId, attributeId) => `relres:${tenantId}:${attributeId}:*`,
411
437
  /** All rollup cache for a tenant */
412
438
  allRollups: (tenantId) => `rollup:${tenantId}:*`,
413
439
  /** All rollups for a specific record */
@@ -460,6 +486,8 @@ var cacheTtl = {
460
486
  permissions: 15 * 60 * 1e3,
461
487
  /** Relation options - medium volatility (5 minutes) */
462
488
  relations: 5 * 60 * 1e3,
489
+ /** Resolved relations - medium volatility (5 minutes) */
490
+ resolvedRelations: 5 * 60 * 1e3,
463
491
  /** Rollup values - high volatility (2 minutes) */
464
492
  rollup: 2 * 60 * 1e3,
465
493
  /** Individual records - high volatility (1 minute) */
@@ -492,6 +520,7 @@ var defaultTtl = {
492
520
  workflowById: cacheTtl.workflows,
493
521
  workflowList: cacheTtl.workflows,
494
522
  relationOptions: cacheTtl.relations,
523
+ resolvedRelation: cacheTtl.resolvedRelations,
495
524
  rollupValue: cacheTtl.rollup,
496
525
  userPermissions: cacheTtl.permissions,
497
526
  recordList: cacheTtl.recordList,
@@ -4408,6 +4437,72 @@ var BaseService = class {
4408
4437
  const pattern = patternFn(this.tenantId, id);
4409
4438
  await this.cache.deletePattern(pattern);
4410
4439
  }
4440
+ /**
4441
+ * Cache multiple resources by ID, fetching only missing ones.
4442
+ * Useful for batch operations with individual caching (e.g., resolveIds).
4443
+ *
4444
+ * Unlike `cachedBy` which caches a single resource, this method:
4445
+ * 1. Checks the cache for each ID in parallel
4446
+ * 2. Collects cache misses
4447
+ * 3. Fetches only missing items via the fetcher
4448
+ * 4. Caches new results individually
4449
+ * 5. Returns all results (cached + freshly fetched)
4450
+ *
4451
+ * @param keyType - Type of cache key (e.g., "resolvedRelation")
4452
+ * @param ids - Resource identifiers to fetch
4453
+ * @param fetcher - Function to fetch missing items (receives only cache-miss IDs)
4454
+ * @param getId - Function to extract ID from a fetched item
4455
+ * @param ttlMs - Optional TTL override
4456
+ *
4457
+ * @example
4458
+ * ```typescript
4459
+ * // Cache relations by composite ID (attributeId:recordId)
4460
+ * return this.cachedByMany(
4461
+ * "resolvedRelation",
4462
+ * ids.map(id => `${attributeId}:${id}`),
4463
+ * async (missingCompositeIds) => {
4464
+ * const missingRecordIds = missingCompositeIds.map(c => c.split(":")[1]);
4465
+ * return this.fetchRelations(missingRecordIds, attributeId);
4466
+ * },
4467
+ * (item) => `${attributeId}:${item.id}`
4468
+ * );
4469
+ * ```
4470
+ */
4471
+ async cachedByMany(keyType, ids, fetcher, getId, ttlMs) {
4472
+ const cache = this.cache;
4473
+ if (!cache || ids.length === 0) {
4474
+ return fetcher(ids);
4475
+ }
4476
+ const keyFn = cacheKeys[keyType];
4477
+ const ttl = _nullishCoalesce(_nullishCoalesce(ttlMs, () => ( defaultTtl[keyType])), () => ( 6e4));
4478
+ const cacheChecks = await Promise.all(
4479
+ ids.map(async (id) => {
4480
+ const key = keyFn(this.tenantId, id);
4481
+ const cached = await cache.get(key);
4482
+ return { id, cached };
4483
+ })
4484
+ );
4485
+ const results = [];
4486
+ const missingIds = [];
4487
+ for (const { id, cached } of cacheChecks) {
4488
+ if (cached !== null) {
4489
+ results.push(cached);
4490
+ } else {
4491
+ missingIds.push(id);
4492
+ }
4493
+ }
4494
+ if (missingIds.length > 0) {
4495
+ const fetched = await fetcher(missingIds);
4496
+ await Promise.all(
4497
+ fetched.map(async (item) => {
4498
+ const key = keyFn(this.tenantId, getId(item));
4499
+ await cache.set(key, item, ttl);
4500
+ })
4501
+ );
4502
+ results.push(...fetched);
4503
+ }
4504
+ return results;
4505
+ }
4411
4506
  };
4412
4507
  var BaseRepository = class {
4413
4508
  /**
@@ -7717,6 +7812,7 @@ var ObjectSchemaService = class extends BaseService {
7717
7812
  return new Map(records.map((r) => [r.id, r.label]));
7718
7813
  });
7719
7814
  });
7815
+ await this.invalidateCachePattern(cacheKeys.allResolvedRelations(this.tenantId));
7720
7816
  }
7721
7817
  return this.convertDBObjectToDefinition(updatedDbObject, dbAttributes);
7722
7818
  }
@@ -9445,8 +9541,8 @@ var RelationService = class extends BaseService {
9445
9541
  * Resolve record IDs to their display labels.
9446
9542
  * Useful for displaying current values in the UI.
9447
9543
  *
9448
- * Uses batch fetching for performance - fetches all records in one query,
9449
- * then groups by objectId to minimize schema lookups.
9544
+ * Uses caching per individual record ID for optimal performance.
9545
+ * Cache key format: `${attributeId}:${recordId}` to handle different displayTemplates.
9450
9546
  *
9451
9547
  * @param ids - Record IDs to resolve
9452
9548
  * @param attributeId - Relation attribute ID to use its displayTemplate for label rendering
@@ -9461,6 +9557,153 @@ var RelationService = class extends BaseService {
9461
9557
  if (!ids || ids.length === 0) {
9462
9558
  return [];
9463
9559
  }
9560
+ const compositeIds = ids.map((id) => `${attributeId}:${id}`);
9561
+ return this.cachedByMany(
9562
+ "resolvedRelation",
9563
+ compositeIds,
9564
+ async (missingCompositeIds) => {
9565
+ const missingRecordIds = missingCompositeIds.map((c) => c.split(":")[1]);
9566
+ return this.fetchResolveIds(missingRecordIds, attributeId);
9567
+ },
9568
+ (item) => `${attributeId}:${item.id}`,
9569
+ cacheTtl.resolvedRelations
9570
+ );
9571
+ }
9572
+ /**
9573
+ * Resolve multiple attribute/IDs batches in a single operation.
9574
+ * Optimized for DataGrid scenarios with multiple relation columns.
9575
+ *
9576
+ * Benefits over multiple resolveIds() calls:
9577
+ * - Single DB query for all records across all attributes
9578
+ * - Deduplication of records referenced by multiple attributes
9579
+ * - Single schema lookup per objectId
9580
+ *
9581
+ * Uses caching per individual record ID for optimal performance.
9582
+ *
9583
+ * @param requests - Array of { attributeId, ids } to resolve
9584
+ * @returns Map of attributeId to resolved options
9585
+ *
9586
+ * @example
9587
+ * ```typescript
9588
+ * const results = await relationService.resolveIdsBatch([
9589
+ * { attributeId: "attr-company", ids: ["rec-1", "rec-2"] },
9590
+ * { attributeId: "attr-contact", ids: ["rec-3", "rec-4"] },
9591
+ * ]);
9592
+ * // { "attr-company": [...], "attr-contact": [...] }
9593
+ * ```
9594
+ */
9595
+ async resolveIdsBatch(requests) {
9596
+ if (!requests || requests.length === 0) {
9597
+ return {};
9598
+ }
9599
+ const validRequests = requests.filter((r) => r.ids && r.ids.length > 0);
9600
+ if (validRequests.length === 0) {
9601
+ return {};
9602
+ }
9603
+ const allCompositeIds = [];
9604
+ const compositeIdsByAttr = /* @__PURE__ */ new Map();
9605
+ for (const req of validRequests) {
9606
+ const composites = req.ids.map((id) => `${req.attributeId}:${id}`);
9607
+ allCompositeIds.push(...composites);
9608
+ compositeIdsByAttr.set(req.attributeId, composites);
9609
+ }
9610
+ const allResolved = await this.cachedByMany(
9611
+ "resolvedRelation",
9612
+ allCompositeIds,
9613
+ (missingCompositeIds) => this.fetchResolveIdsBatch(missingCompositeIds),
9614
+ (item) => item._compositeId,
9615
+ cacheTtl.resolvedRelations
9616
+ );
9617
+ const response = {};
9618
+ const resolvedMap = new Map(allResolved.map((item) => [item._compositeId, item]));
9619
+ for (const req of validRequests) {
9620
+ const composites = _nullishCoalesce(compositeIdsByAttr.get(req.attributeId), () => ( []));
9621
+ const options = [];
9622
+ for (const compositeId of composites) {
9623
+ const resolved = resolvedMap.get(compositeId);
9624
+ if (resolved) {
9625
+ const { _compositeId, ...option } = resolved;
9626
+ options.push(option);
9627
+ }
9628
+ }
9629
+ response[req.attributeId] = options;
9630
+ }
9631
+ return response;
9632
+ }
9633
+ /**
9634
+ * Internal method to fetch and resolve multiple composite IDs at once.
9635
+ * Optimized for batch operations - single DB query for all records.
9636
+ */
9637
+ async fetchResolveIdsBatch(compositeIds) {
9638
+ if (compositeIds.length === 0) {
9639
+ return [];
9640
+ }
9641
+ const parsed = compositeIds.map((c) => {
9642
+ const [attributeId, recordId] = c.split(":");
9643
+ return { compositeId: c, attributeId, recordId };
9644
+ });
9645
+ const uniqueRecordIds = [...new Set(parsed.map((p) => p.recordId))];
9646
+ const uniqueAttributeIds = [...new Set(parsed.map((p) => p.attributeId))];
9647
+ const records = await this.adapter.objectRecords.findByIds(uniqueRecordIds);
9648
+ if (records.length === 0) {
9649
+ return [];
9650
+ }
9651
+ const recordMap = new Map(records.map((r) => [r.id, r]));
9652
+ const attributePromises = uniqueAttributeIds.map((id) => this.findAttributeById(id));
9653
+ const attributes = await Promise.all(attributePromises);
9654
+ const attributeMap = new Map(uniqueAttributeIds.map((id, i) => [id, attributes[i]]));
9655
+ const uniqueObjectIds = [...new Set(records.map((r) => r.objectId))];
9656
+ const schemaPromises = uniqueObjectIds.map((id) => this.schemaService.getObjectSchema(id));
9657
+ const schemas = await Promise.all(schemaPromises);
9658
+ const schemaMap = new Map(uniqueObjectIds.map((id, i) => [id, schemas[i]]));
9659
+ const resolved = [];
9660
+ for (const { compositeId, attributeId, recordId } of parsed) {
9661
+ const record = recordMap.get(recordId);
9662
+ if (!record) {
9663
+ continue;
9664
+ }
9665
+ const objectSchema = schemaMap.get(record.objectId);
9666
+ if (!objectSchema) {
9667
+ continue;
9668
+ }
9669
+ const attribute = attributeMap.get(attributeId);
9670
+ const targetConfig = _optionalChain([attribute, 'optionalAccess', _201 => _201.targets, 'optionalAccess', _202 => _202.find, 'call', _203 => _203((t) => t.object === objectSchema.name)]);
9671
+ const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _204 => _204.displayTemplate]);
9672
+ let label;
9673
+ if (customTemplate) {
9674
+ label = await computeLabelWithRelations(
9675
+ customTemplate,
9676
+ record.values,
9677
+ objectSchema.attributes,
9678
+ async (nestedIds) => {
9679
+ const linkedRecords = await this.adapter.objectRecords.findByIds(nestedIds);
9680
+ return new Map(linkedRecords.map((r) => [r.id, r.label]));
9681
+ }
9682
+ );
9683
+ } else {
9684
+ label = record.label;
9685
+ }
9686
+ resolved.push({
9687
+ _compositeId: compositeId,
9688
+ id: record.id,
9689
+ objectId: record.objectId,
9690
+ objectName: objectSchema.name,
9691
+ objectLabel: objectSchema.label,
9692
+ objectIcon: objectSchema.icon,
9693
+ label
9694
+ });
9695
+ }
9696
+ return resolved;
9697
+ }
9698
+ /**
9699
+ * Internal method to fetch and resolve relation IDs (no caching).
9700
+ * Uses batch fetching for performance - fetches all records in one query,
9701
+ * then groups by objectId to minimize schema lookups.
9702
+ */
9703
+ async fetchResolveIds(ids, attributeId) {
9704
+ if (ids.length === 0) {
9705
+ return [];
9706
+ }
9464
9707
  const attribute = await this.findAttributeById(attributeId);
9465
9708
  const records = await this.adapter.objectRecords.findByIds(ids);
9466
9709
  if (records.length === 0) {
@@ -9478,8 +9721,8 @@ var RelationService = class extends BaseService {
9478
9721
  if (!objectSchema) {
9479
9722
  continue;
9480
9723
  }
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]);
9724
+ const targetConfig = _optionalChain([attribute, 'optionalAccess', _205 => _205.targets, 'optionalAccess', _206 => _206.find, 'call', _207 => _207((t) => t.object === objectSchema.name)]);
9725
+ const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _208 => _208.displayTemplate]);
9483
9726
  for (const record of objectRecords) {
9484
9727
  let label;
9485
9728
  if (customTemplate) {
@@ -9487,8 +9730,8 @@ var RelationService = class extends BaseService {
9487
9730
  customTemplate,
9488
9731
  record.values,
9489
9732
  objectSchema.attributes,
9490
- async (ids2) => {
9491
- const linkedRecords = await this.adapter.objectRecords.findByIds(ids2);
9733
+ async (nestedIds) => {
9734
+ const linkedRecords = await this.adapter.objectRecords.findByIds(nestedIds);
9492
9735
  return new Map(linkedRecords.map((r) => [r.id, r.label]));
9493
9736
  }
9494
9737
  );
@@ -9624,14 +9867,14 @@ var RollupService = class extends BaseService {
9624
9867
  const sourceSchema = getSchemaByNameFromContext(sourceObjectName);
9625
9868
  let sourceObjectId;
9626
9869
  let reverseRelationAttrName;
9627
- if (_optionalChain([sourceSchema, 'optionalAccess', _205 => _205.id])) {
9870
+ if (_optionalChain([sourceSchema, 'optionalAccess', _209 => _209.id])) {
9628
9871
  sourceObjectId = sourceSchema.id;
9629
9872
  const reverseRelationAttr = sourceSchema.attributes.find((attr) => {
9630
9873
  if (attr.type !== "relation") return false;
9631
9874
  const relationConfig = attr;
9632
- return _optionalChain([relationConfig, 'optionalAccess', _206 => _206.targets, 'optionalAccess', _207 => _207.some, 'call', _208 => _208((t) => t.object === schema.name)]);
9875
+ return _optionalChain([relationConfig, 'optionalAccess', _210 => _210.targets, 'optionalAccess', _211 => _211.some, 'call', _212 => _212((t) => t.object === schema.name)]);
9633
9876
  });
9634
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _209 => _209.name]);
9877
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _213 => _213.name]);
9635
9878
  } else {
9636
9879
  const sourceObject = await this.adapter.objects.findByName(sourceObjectName);
9637
9880
  if (!sourceObject) {
@@ -9642,9 +9885,9 @@ var RollupService = class extends BaseService {
9642
9885
  const reverseRelationAttr = sourceAttributes.find((attr) => {
9643
9886
  if (attr.type !== "relation") return false;
9644
9887
  const relationConfig = attr.config;
9645
- return _optionalChain([relationConfig, 'optionalAccess', _210 => _210.targets, 'optionalAccess', _211 => _211.some, 'call', _212 => _212((t) => t.object === schema.name)]);
9888
+ return _optionalChain([relationConfig, 'optionalAccess', _214 => _214.targets, 'optionalAccess', _215 => _215.some, 'call', _216 => _216((t) => t.object === schema.name)]);
9646
9889
  });
9647
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _213 => _213.name]);
9890
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _217 => _217.name]);
9648
9891
  }
9649
9892
  if (!reverseRelationAttrName) {
9650
9893
  return { value: null, recordCount: 0 };
@@ -9881,7 +10124,7 @@ var RollupService = class extends BaseService {
9881
10124
  }
9882
10125
  for (const rollupDbAttr of rollupAttrs) {
9883
10126
  const rollupConfig = rollupDbAttr.config;
9884
- if (!_optionalChain([rollupConfig, 'optionalAccess', _214 => _214.relationAttribute])) {
10127
+ if (!_optionalChain([rollupConfig, 'optionalAccess', _218 => _218.relationAttribute])) {
9885
10128
  continue;
9886
10129
  }
9887
10130
  const relationAttr = attributes.find(
@@ -9891,7 +10134,7 @@ var RollupService = class extends BaseService {
9891
10134
  continue;
9892
10135
  }
9893
10136
  const relationConfig = relationAttr.config;
9894
- const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _215 => _215.targets, 'optionalAccess', _216 => _216.some, 'call', _217 => _217(
10137
+ const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _219 => _219.targets, 'optionalAccess', _220 => _220.some, 'call', _221 => _221(
9895
10138
  (t) => t.object === changedSchema.name
9896
10139
  )]);
9897
10140
  if (!targetsChangedObject) {
@@ -9918,11 +10161,11 @@ var RecordService = class extends BaseService {
9918
10161
  constructor(adapter, options) {
9919
10162
  super(adapter);
9920
10163
  this.schemaService = new ObjectSchemaService(adapter, registry, {
9921
- auditService: _optionalChain([options, 'optionalAccess', _218 => _218.auditService])
10164
+ auditService: _optionalChain([options, 'optionalAccess', _222 => _222.auditService])
9922
10165
  });
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));
10166
+ this.permissionService = _optionalChain([options, 'optionalAccess', _223 => _223.permissionService]);
10167
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _224 => _224.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
10168
+ this.policyRegistry = _optionalChain([options, 'optionalAccess', _225 => _225.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _226 => _226.policyRegistry]), () => ( defaultPolicyRegistry));
9926
10169
  this.queryService = new RecordQueryService(adapter, this.schemaService, {
9927
10170
  permissionService: this.permissionService,
9928
10171
  policyRegistry: this.policyRegistry
@@ -9932,7 +10175,7 @@ var RecordService = class extends BaseService {
9932
10175
  });
9933
10176
  this.userService = new UserService(adapter);
9934
10177
  this.rollupService = new RollupService(adapter);
9935
- this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _223 => _223.hookRegistry]), () => ( new NoopHookRegistry()));
10178
+ this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _227 => _227.hookRegistry]), () => ( new NoopHookRegistry()));
9936
10179
  this.labelResolver = {
9937
10180
  resolveRelationIds: (ids, attrId) => this.relationService.resolveIds(ids, attrId),
9938
10181
  findRecordLabels: (ids) => this.adapter.objectRecords.findByIds(ids)
@@ -9964,21 +10207,21 @@ var RecordService = class extends BaseService {
9964
10207
  schema,
9965
10208
  this.tenantId,
9966
10209
  dataWithDefaults,
9967
- _optionalChain([options, 'optionalAccess', _224 => _224.hookMetadata])
10210
+ _optionalChain([options, 'optionalAccess', _228 => _228.hookMetadata])
9968
10211
  );
9969
- if (!_optionalChain([options, 'optionalAccess', _225 => _225.skipHooks])) {
10212
+ if (!_optionalChain([options, 'optionalAccess', _229 => _229.skipHooks])) {
9970
10213
  await this.hookRegistry.execute("beforeCreate", schema.name, hookCtx);
9971
10214
  }
9972
- if (_optionalChain([options, 'optionalAccess', _226 => _226.validate]) !== false) {
9973
- if (_optionalChain([options, 'optionalAccess', _227 => _227.allowDraft])) {
10215
+ if (_optionalChain([options, 'optionalAccess', _230 => _230.validate]) !== false) {
10216
+ if (_optionalChain([options, 'optionalAccess', _231 => _231.allowDraft])) {
9974
10217
  validateDraftOrThrow(schema, dataWithDefaults);
9975
10218
  } else {
9976
10219
  validateObjectOrThrow(schema, dataWithDefaults);
9977
10220
  }
9978
- if (!_optionalChain([options, 'optionalAccess', _228 => _228.skipRelationValidation])) {
10221
+ if (!_optionalChain([options, 'optionalAccess', _232 => _232.skipRelationValidation])) {
9979
10222
  await this.relationService.validateRelationsOrThrow(schema, dataWithDefaults);
9980
10223
  }
9981
- if (!_optionalChain([options, 'optionalAccess', _229 => _229.skipUserValidation])) {
10224
+ if (!_optionalChain([options, 'optionalAccess', _233 => _233.skipUserValidation])) {
9982
10225
  await this.userService.validateUsersOrThrow(schema, dataWithDefaults);
9983
10226
  }
9984
10227
  }
@@ -9989,10 +10232,10 @@ var RecordService = class extends BaseService {
9989
10232
  data: dataWithDefaults,
9990
10233
  label,
9991
10234
  completionStatus,
9992
- metadata: _optionalChain([options, 'optionalAccess', _230 => _230.metadata]),
10235
+ metadata: _optionalChain([options, 'optionalAccess', _234 => _234.metadata]),
9993
10236
  createdBy: this.userId
9994
10237
  });
9995
- if (!_optionalChain([options, 'optionalAccess', _231 => _231.skipHooks])) {
10238
+ if (!_optionalChain([options, 'optionalAccess', _235 => _235.skipHooks])) {
9996
10239
  const afterCtx = {
9997
10240
  ...hookCtx,
9998
10241
  recordId: record.id,
@@ -10012,7 +10255,7 @@ var RecordService = class extends BaseService {
10012
10255
  objectId: schema.id,
10013
10256
  recordId: record.id,
10014
10257
  recordLabel: record.label,
10015
- metadata: _optionalChain([options, 'optionalAccess', _232 => _232.hookMetadata])
10258
+ metadata: _optionalChain([options, 'optionalAccess', _236 => _236.hookMetadata])
10016
10259
  });
10017
10260
  }
10018
10261
  return record;
@@ -10033,7 +10276,7 @@ var RecordService = class extends BaseService {
10033
10276
  return null;
10034
10277
  }
10035
10278
  const schema = await this.schemaService.getObjectSchema(record.objectId);
10036
- if (!_optionalChain([options, 'optionalAccess', _233 => _233.skipPolicyCheck])) {
10279
+ if (!_optionalChain([options, 'optionalAccess', _237 => _237.skipPolicyCheck])) {
10037
10280
  const policy = getPolicy(this.policyRegistry, this.userId, schema.name);
10038
10281
  if (policy) {
10039
10282
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
@@ -10043,10 +10286,10 @@ var RecordService = class extends BaseService {
10043
10286
  }
10044
10287
  }
10045
10288
  let enrichedRecord = record;
10046
- if (!_optionalChain([options, 'optionalAccess', _234 => _234.skipFormulas])) {
10289
+ if (!_optionalChain([options, 'optionalAccess', _238 => _238.skipFormulas])) {
10047
10290
  enrichedRecord = enrichWithFormulas(record, schema);
10048
10291
  }
10049
- if (_optionalChain([options, 'optionalAccess', _235 => _235.includeSchema])) {
10292
+ if (_optionalChain([options, 'optionalAccess', _239 => _239.includeSchema])) {
10050
10293
  const recordWithSchema = enrichedRecord;
10051
10294
  recordWithSchema.schema = schema;
10052
10295
  return recordWithSchema;
@@ -10089,9 +10332,9 @@ var RecordService = class extends BaseService {
10089
10332
  existing,
10090
10333
  mergedData,
10091
10334
  changedAttributes,
10092
- _optionalChain([options, 'optionalAccess', _236 => _236.hookMetadata])
10335
+ _optionalChain([options, 'optionalAccess', _240 => _240.hookMetadata])
10093
10336
  );
10094
- if (!_optionalChain([options, 'optionalAccess', _237 => _237.skipHooks])) {
10337
+ if (!_optionalChain([options, 'optionalAccess', _241 => _241.skipHooks])) {
10095
10338
  await this.hookRegistry.execute("beforeUpdate", schema.name, hookCtx);
10096
10339
  }
10097
10340
  const hookModifiedValues = {};
@@ -10100,19 +10343,19 @@ var RecordService = class extends BaseService {
10100
10343
  hookModifiedValues[key] = hookCtx.newValues[key];
10101
10344
  }
10102
10345
  }
10103
- if (_optionalChain([options, 'optionalAccess', _238 => _238.validate]) !== false) {
10104
- if (_optionalChain([options, 'optionalAccess', _239 => _239.partial])) {
10346
+ if (_optionalChain([options, 'optionalAccess', _242 => _242.validate]) !== false) {
10347
+ if (_optionalChain([options, 'optionalAccess', _243 => _243.partial])) {
10105
10348
  validateDraftOrThrow(schema, mergedData);
10106
10349
  } else {
10107
10350
  validateObjectOrThrow(schema, mergedData);
10108
10351
  }
10109
- if (!_optionalChain([options, 'optionalAccess', _240 => _240.skipRelationValidation])) {
10352
+ if (!_optionalChain([options, 'optionalAccess', _244 => _244.skipRelationValidation])) {
10110
10353
  await this.relationService.validateRelationsOrThrow(schema, {
10111
10354
  ...data,
10112
10355
  ...hookModifiedValues
10113
10356
  });
10114
10357
  }
10115
- if (!_optionalChain([options, 'optionalAccess', _241 => _241.skipUserValidation])) {
10358
+ if (!_optionalChain([options, 'optionalAccess', _245 => _245.skipUserValidation])) {
10116
10359
  await this.userService.validateUsersOrThrow(schema, {
10117
10360
  ...data,
10118
10361
  ...hookModifiedValues
@@ -10128,7 +10371,7 @@ var RecordService = class extends BaseService {
10128
10371
  __label: label,
10129
10372
  __lastUpdatedBy: this.userId
10130
10373
  };
10131
- if (_optionalChain([options, 'optionalAccess', _242 => _242.metadata]) !== void 0) {
10374
+ if (_optionalChain([options, 'optionalAccess', _246 => _246.metadata]) !== void 0) {
10132
10375
  const existingMetadata = _nullishCoalesce(existing.metadata, () => ( {}));
10133
10376
  const mergedMetadata = { ...existingMetadata, ...options.metadata };
10134
10377
  const cleanedMetadata = Object.fromEntries(
@@ -10140,7 +10383,8 @@ var RecordService = class extends BaseService {
10140
10383
  await this.invalidateCache(cacheKeys.record(this.tenantId, recordId));
10141
10384
  await this.invalidateLists("allRecordLists", existing.objectId);
10142
10385
  await this.invalidateLists("allSearchResults", existing.objectId);
10143
- if (!_optionalChain([options, 'optionalAccess', _243 => _243.skipHooks])) {
10386
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10387
+ if (!_optionalChain([options, 'optionalAccess', _247 => _247.skipHooks])) {
10144
10388
  const afterCtx = {
10145
10389
  ...hookCtx,
10146
10390
  record: updated
@@ -10155,7 +10399,7 @@ var RecordService = class extends BaseService {
10155
10399
  if (this.auditService && this.userId && allChangedAttributes.length > 0) {
10156
10400
  const changes = allChangedAttributes.map((attr) => ({
10157
10401
  field: attr,
10158
- oldValue: _optionalChain([hookCtx, 'access', _244 => _244.oldValues, 'optionalAccess', _245 => _245[attr]]),
10402
+ oldValue: _optionalChain([hookCtx, 'access', _248 => _248.oldValues, 'optionalAccess', _249 => _249[attr]]),
10159
10403
  newValue: hookCtx.newValues[attr]
10160
10404
  }));
10161
10405
  await this.auditService.logRecordAction({
@@ -10166,7 +10410,7 @@ var RecordService = class extends BaseService {
10166
10410
  recordId: updated.id,
10167
10411
  recordLabel: updated.label,
10168
10412
  changes,
10169
- metadata: _optionalChain([options, 'optionalAccess', _246 => _246.hookMetadata])
10413
+ metadata: _optionalChain([options, 'optionalAccess', _250 => _250.hookMetadata])
10170
10414
  });
10171
10415
  }
10172
10416
  return updated;
@@ -10189,17 +10433,17 @@ var RecordService = class extends BaseService {
10189
10433
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
10190
10434
  checkRecordDeleteOrThrow(policy, record, ctx);
10191
10435
  }
10192
- if (_optionalChain([options, 'optionalAccess', _247 => _247.checkSystem]) && schema.system) {
10436
+ if (_optionalChain([options, 'optionalAccess', _251 => _251.checkSystem]) && schema.system) {
10193
10437
  throw new ProtectedResourceError("object", schema.name, "delete");
10194
10438
  }
10195
- if (!_optionalChain([options, 'optionalAccess', _248 => _248.skipReferenceCheck])) {
10439
+ if (!_optionalChain([options, 'optionalAccess', _252 => _252.skipReferenceCheck])) {
10196
10440
  const references = await this.adapter.objectRecords.countRecordsReferencingId(recordId);
10197
10441
  if (references.length > 0) {
10198
10442
  throw new RecordReferencedError(recordId, references);
10199
10443
  }
10200
10444
  }
10201
- const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _249 => _249.hookMetadata]));
10202
- if (!_optionalChain([options, 'optionalAccess', _250 => _250.skipHooks])) {
10445
+ const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _253 => _253.hookMetadata]));
10446
+ if (!_optionalChain([options, 'optionalAccess', _254 => _254.skipHooks])) {
10203
10447
  await this.hookRegistry.execute("beforeDelete", schema.name, hookCtx);
10204
10448
  }
10205
10449
  await this.adapter.objectRecords.delete(recordId);
@@ -10207,7 +10451,8 @@ var RecordService = class extends BaseService {
10207
10451
  await this.invalidateLists("allRecordLists", record.objectId);
10208
10452
  await this.invalidateLists("allSearchResults", record.objectId);
10209
10453
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10210
- if (!_optionalChain([options, 'optionalAccess', _251 => _251.skipHooks])) {
10454
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10455
+ if (!_optionalChain([options, 'optionalAccess', _255 => _255.skipHooks])) {
10211
10456
  await this.hookRegistry.execute("afterDelete", schema.name, hookCtx);
10212
10457
  }
10213
10458
  await recalculateParentRollups(record, schema, this.rollupContext);
@@ -10219,7 +10464,7 @@ var RecordService = class extends BaseService {
10219
10464
  objectId: schema.id,
10220
10465
  recordId: record.id,
10221
10466
  recordLabel: record.label,
10222
- metadata: _optionalChain([options, 'optionalAccess', _252 => _252.hookMetadata])
10467
+ metadata: _optionalChain([options, 'optionalAccess', _256 => _256.hookMetadata])
10223
10468
  });
10224
10469
  }
10225
10470
  }
@@ -10235,6 +10480,7 @@ var RecordService = class extends BaseService {
10235
10480
  await this.invalidateLists("allRecordLists", record.objectId);
10236
10481
  await this.invalidateLists("allSearchResults", record.objectId);
10237
10482
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10483
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10238
10484
  }
10239
10485
  // ============================================================================
10240
10486
  // RESTORE
@@ -10253,8 +10499,8 @@ var RecordService = class extends BaseService {
10253
10499
  }
10254
10500
  const schema = await this.schemaService.getObjectSchema(record.objectId);
10255
10501
  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])) {
10502
+ const hookCtx = createContextForRestore(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _257 => _257.hookMetadata]));
10503
+ if (!_optionalChain([options, 'optionalAccess', _258 => _258.skipHooks])) {
10258
10504
  await this.hookRegistry.execute("beforeRestore", schema.name, hookCtx);
10259
10505
  }
10260
10506
  const restored = await this.adapter.objectRecords.restore(recordId);
@@ -10262,7 +10508,8 @@ var RecordService = class extends BaseService {
10262
10508
  await this.invalidateLists("allRecordLists", record.objectId);
10263
10509
  await this.invalidateLists("allSearchResults", record.objectId);
10264
10510
  await this.invalidateCachePattern(cacheKeys.allGlobalSearch(this.tenantId));
10265
- if (!_optionalChain([options, 'optionalAccess', _255 => _255.skipHooks])) {
10511
+ await this.invalidateCachePattern(cacheKeys.resolvedRelationsByRecord(this.tenantId, recordId));
10512
+ if (!_optionalChain([options, 'optionalAccess', _259 => _259.skipHooks])) {
10266
10513
  const afterCtx = {
10267
10514
  ...hookCtx,
10268
10515
  record: restored
@@ -10277,7 +10524,7 @@ var RecordService = class extends BaseService {
10277
10524
  objectId: schema.id,
10278
10525
  recordId: restored.id,
10279
10526
  recordLabel: restored.label,
10280
- metadata: _optionalChain([options, 'optionalAccess', _256 => _256.hookMetadata])
10527
+ metadata: _optionalChain([options, 'optionalAccess', _260 => _260.hookMetadata])
10281
10528
  });
10282
10529
  }
10283
10530
  return restored;
@@ -10480,8 +10727,8 @@ var RollupScheduler = class {
10480
10727
  this.getSchemaById = getSchemaById;
10481
10728
  this.pending = /* @__PURE__ */ new Map();
10482
10729
  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));
10730
+ this.debounceMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _261 => _261.debounceMs]), () => ( 100));
10731
+ this.maxPending = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _262 => _262.maxPending]), () => ( 100));
10485
10732
  }
10486
10733
  /**
10487
10734
  * Schedule a rollup recalculation for a parent record.
@@ -10559,7 +10806,7 @@ var WorkflowService = class extends BaseService {
10559
10806
  if (Array.isArray(options)) {
10560
10807
  this.systemWorkflows = new Map(options.map((w) => [w.name, w]));
10561
10808
  } else {
10562
- this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _259 => _259.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
10809
+ this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _263 => _263.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
10563
10810
  }
10564
10811
  }
10565
10812
  // ============================================================================
@@ -10862,9 +11109,9 @@ var WorkflowInstanceService = class extends BaseService {
10862
11109
  constructor(adapter, workflowService, options) {
10863
11110
  super(adapter);
10864
11111
  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]);
11112
+ this.executorRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _264 => _264.executorRegistry]), () => ( getDefaultExecutorRegistry()));
11113
+ this.schemaService = _optionalChain([options, 'optionalAccess', _265 => _265.schemaService]);
11114
+ this.recordService = _optionalChain([options, 'optionalAccess', _266 => _266.recordService]);
10868
11115
  }
10869
11116
  /**
10870
11117
  * Start a new workflow instance
@@ -10990,7 +11237,7 @@ var WorkflowInstanceService = class extends BaseService {
10990
11237
  if (!this.adapter.workflowInstances) {
10991
11238
  return { instances: [], total: 0 };
10992
11239
  }
10993
- if (_optionalChain([options, 'optionalAccess', _263 => _263.workflowName])) {
11240
+ if (_optionalChain([options, 'optionalAccess', _267 => _267.workflowName])) {
10994
11241
  const instances2 = await this.getInstancesByWorkflow(options.workflowName);
10995
11242
  let filtered = instances2;
10996
11243
  if (options.status) {
@@ -11004,11 +11251,11 @@ var WorkflowInstanceService = class extends BaseService {
11004
11251
  return { instances: paginated, total: total2 };
11005
11252
  }
11006
11253
  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])
11254
+ limit: _optionalChain([options, 'optionalAccess', _268 => _268.limit]),
11255
+ offset: _optionalChain([options, 'optionalAccess', _269 => _269.offset])
11009
11256
  });
11010
11257
  let instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
11011
- if (_optionalChain([options, 'optionalAccess', _266 => _266.status])) {
11258
+ if (_optionalChain([options, 'optionalAccess', _270 => _270.status])) {
11012
11259
  instances = instances.filter((i) => i.status === options.status);
11013
11260
  }
11014
11261
  return { instances, total };
@@ -11028,9 +11275,9 @@ var WorkflowInstanceService = class extends BaseService {
11028
11275
  return { instances: [], total: 0 };
11029
11276
  }
11030
11277
  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])
11278
+ status: _optionalChain([options, 'optionalAccess', _271 => _271.status]),
11279
+ limit: _optionalChain([options, 'optionalAccess', _272 => _272.limit]),
11280
+ offset: _optionalChain([options, 'optionalAccess', _273 => _273.offset])
11034
11281
  });
11035
11282
  const instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
11036
11283
  return { instances, total };
@@ -11406,7 +11653,7 @@ var WorkflowParticipationService = class extends BaseService {
11406
11653
  SchemaErrorCode.RECORD_NOT_FOUND
11407
11654
  );
11408
11655
  }
11409
- const template = _optionalChain([instance, 'access', _270 => _270.workflowSnapshot, 'access', _271 => _271.participants, 'optionalAccess', _272 => _272.find, 'call', _273 => _273(
11656
+ const template = _optionalChain([instance, 'access', _274 => _274.workflowSnapshot, 'access', _275 => _275.participants, 'optionalAccess', _276 => _276.find, 'call', _277 => _277(
11410
11657
  (p) => p.id === input.participantTemplateId
11411
11658
  )]);
11412
11659
  if (!template) {
@@ -11708,7 +11955,7 @@ var WorkflowRelationService = class extends BaseService {
11708
11955
  if (attr.type !== "relation") continue;
11709
11956
  for (const slot of slots) {
11710
11957
  const slotData = context.slots[slot.id];
11711
- const slotRecordId = _optionalChain([slotData, 'optionalAccess', _274 => _274.id]);
11958
+ const slotRecordId = _optionalChain([slotData, 'optionalAccess', _278 => _278.id]);
11712
11959
  if (!slotRecordId) continue;
11713
11960
  const targetsSlotObject = attr.targets.some(
11714
11961
  (t) => t.object === slot.objectName
@@ -11773,7 +12020,7 @@ var WorkflowRelationService = class extends BaseService {
11773
12020
  var UserProfileService = class extends BaseService {
11774
12021
  constructor(adapter, options) {
11775
12022
  super(adapter);
11776
- this.auditService = _optionalChain([options, 'optionalAccess', _275 => _275.auditService]);
12023
+ this.auditService = _optionalChain([options, 'optionalAccess', _279 => _279.auditService]);
11777
12024
  }
11778
12025
  // ============================================================================
11779
12026
  // CACHE MANAGEMENT
@@ -11936,7 +12183,7 @@ var UserProfileService = class extends BaseService {
11936
12183
  */
11937
12184
  async deleteProfile(profileId, options) {
11938
12185
  const profile = await this.getProfileOrThrow(profileId);
11939
- if (_optionalChain([options, 'optionalAccess', _276 => _276.checkAdmin])) {
12186
+ if (_optionalChain([options, 'optionalAccess', _280 => _280.checkAdmin])) {
11940
12187
  if (profile.role === "admin") {
11941
12188
  const adminCount = await this.adapter.userProfiles.countByRole("admin");
11942
12189
  if (adminCount <= 1) {
@@ -12011,7 +12258,7 @@ var UserProfileService = class extends BaseService {
12011
12258
  */
12012
12259
  async hasRole(profileId, role) {
12013
12260
  const profile = await this.getProfile(profileId);
12014
- return _optionalChain([profile, 'optionalAccess', _277 => _277.role]) === role;
12261
+ return _optionalChain([profile, 'optionalAccess', _281 => _281.role]) === role;
12015
12262
  }
12016
12263
  /**
12017
12264
  * Check if user is admin
@@ -12068,7 +12315,7 @@ var UserProfileService = class extends BaseService {
12068
12315
  var FileService = class extends BaseService {
12069
12316
  constructor(adapter, options) {
12070
12317
  super(adapter);
12071
- this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _278 => _278.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
12318
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _282 => _282.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
12072
12319
  }
12073
12320
  // ============================================================================
12074
12321
  // UPLOAD (requires StorageAdapter)
@@ -12200,7 +12447,7 @@ var FileService = class extends BaseService {
12200
12447
  */
12201
12448
  async getFile(fileId) {
12202
12449
  const file2 = await this.adapter.files.findById(fileId);
12203
- if (_optionalChain([file2, 'optionalAccess', _279 => _279.deletedAt])) {
12450
+ if (_optionalChain([file2, 'optionalAccess', _283 => _283.deletedAt])) {
12204
12451
  return null;
12205
12452
  }
12206
12453
  return file2;
@@ -12262,12 +12509,12 @@ var FileService = class extends BaseService {
12262
12509
  */
12263
12510
  async deleteFile(fileId, options) {
12264
12511
  const file2 = await this.getFileOrThrow(fileId);
12265
- if (_optionalChain([options, 'optionalAccess', _280 => _280.checkOwnership]) && options.userId) {
12512
+ if (_optionalChain([options, 'optionalAccess', _284 => _284.checkOwnership]) && options.userId) {
12266
12513
  if (file2.uploadedBy !== options.userId) {
12267
12514
  throw new Error("You can only delete files you uploaded");
12268
12515
  }
12269
12516
  }
12270
- if (_optionalChain([options, 'optionalAccess', _281 => _281.hard])) {
12517
+ if (_optionalChain([options, 'optionalAccess', _285 => _285.hard])) {
12271
12518
  await this.adapter.files.hardDelete(fileId);
12272
12519
  } else {
12273
12520
  await this.adapter.files.delete(fileId);
@@ -12298,7 +12545,7 @@ var FileService = class extends BaseService {
12298
12545
  }
12299
12546
  const file2 = await this.getFileOrThrow(fileId);
12300
12547
  await this.adapter.storage.delete(file2.storagePath);
12301
- if (_optionalChain([options, 'optionalAccess', _282 => _282.hard])) {
12548
+ if (_optionalChain([options, 'optionalAccess', _286 => _286.hard])) {
12302
12549
  await this.adapter.files.hardDelete(fileId);
12303
12550
  } else {
12304
12551
  await this.adapter.files.delete(fileId);
@@ -12325,10 +12572,10 @@ var FileService = class extends BaseService {
12325
12572
  if (!file2) {
12326
12573
  continue;
12327
12574
  }
12328
- if (_optionalChain([options, 'optionalAccess', _283 => _283.deleteFromStorage]) && this.adapter.storage) {
12575
+ if (_optionalChain([options, 'optionalAccess', _287 => _287.deleteFromStorage]) && this.adapter.storage) {
12329
12576
  await this.adapter.storage.delete(file2.storagePath);
12330
12577
  }
12331
- if (_optionalChain([options, 'optionalAccess', _284 => _284.hard])) {
12578
+ if (_optionalChain([options, 'optionalAccess', _288 => _288.hard])) {
12332
12579
  await this.adapter.files.hardDelete(fileId);
12333
12580
  } else {
12334
12581
  await this.adapter.files.delete(fileId);
@@ -12339,7 +12586,7 @@ var FileService = class extends BaseService {
12339
12586
  actorId: this.userId,
12340
12587
  fileId,
12341
12588
  fileName: file2.name,
12342
- metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _285 => _285.deleteFromStorage]), () => ( false)) }
12589
+ metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _289 => _289.deleteFromStorage]), () => ( false)) }
12343
12590
  });
12344
12591
  }
12345
12592
  }
@@ -12423,7 +12670,7 @@ var FileService = class extends BaseService {
12423
12670
  return true;
12424
12671
  }
12425
12672
  if (file2.visibility === "restricted") {
12426
- return _nullishCoalesce(_optionalChain([file2, 'access', _286 => _286.allowedUsers, 'optionalAccess', _287 => _287.includes, 'call', _288 => _288(userId)]), () => ( false));
12673
+ return _nullishCoalesce(_optionalChain([file2, 'access', _290 => _290.allowedUsers, 'optionalAccess', _291 => _291.includes, 'call', _292 => _292(userId)]), () => ( false));
12427
12674
  }
12428
12675
  return false;
12429
12676
  }
@@ -12588,10 +12835,10 @@ var GlobalSearchService = class extends BaseService {
12588
12835
  */
12589
12836
  async executeSearch(query, options) {
12590
12837
  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))
12838
+ limit: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _293 => _293.limit]), () => ( 20)),
12839
+ offset: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _294 => _294.offset]), () => ( 0)),
12840
+ objectNames: _optionalChain([options, 'optionalAccess', _295 => _295.objectNames]),
12841
+ includeObjectInfo: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _296 => _296.includeObjectInfo]), () => ( true))
12595
12842
  });
12596
12843
  }
12597
12844
  /**
@@ -12641,7 +12888,7 @@ var PermissionService = class extends BaseService {
12641
12888
  }
12642
12889
  this.permissionsRepo = adapter.permissions;
12643
12890
  this.permissionCache = _nullishCoalesce(adapter.cache, () => ( new NoopCacheAdapter()));
12644
- this.auditService = _optionalChain([options, 'optionalAccess', _293 => _293.auditService]);
12891
+ this.auditService = _optionalChain([options, 'optionalAccess', _297 => _297.auditService]);
12645
12892
  }
12646
12893
  // ============================================================================
12647
12894
  // PERMISSION CHECKS
@@ -12660,11 +12907,11 @@ var PermissionService = class extends BaseService {
12660
12907
  return true;
12661
12908
  }
12662
12909
  const wildcardPerms = permissions.objectPermissions["*"];
12663
- if (_optionalChain([wildcardPerms, 'optionalAccess', _294 => _294.includes, 'call', _295 => _295(action)])) {
12910
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _298 => _298.includes, 'call', _299 => _299(action)])) {
12664
12911
  return true;
12665
12912
  }
12666
12913
  const objectPerms = permissions.objectPermissions[objectName];
12667
- return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _296 => _296.includes, 'call', _297 => _297(action)]), () => ( false));
12914
+ return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _300 => _300.includes, 'call', _301 => _301(action)]), () => ( false));
12668
12915
  }
12669
12916
  /**
12670
12917
  * Check if user can access an object, throw ForbiddenError if not.
@@ -12719,12 +12966,12 @@ var PermissionService = class extends BaseService {
12719
12966
  if (permissions.isAdmin) {
12720
12967
  return true;
12721
12968
  }
12722
- const wildcardPerms = _optionalChain([permissions, 'access', _298 => _298.systemPermissions, 'optionalAccess', _299 => _299["*"]]);
12723
- if (_optionalChain([wildcardPerms, 'optionalAccess', _300 => _300.includes, 'call', _301 => _301(action)])) {
12969
+ const wildcardPerms = _optionalChain([permissions, 'access', _302 => _302.systemPermissions, 'optionalAccess', _303 => _303["*"]]);
12970
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _304 => _304.includes, 'call', _305 => _305(action)])) {
12724
12971
  return true;
12725
12972
  }
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));
12973
+ const resourcePerms = _optionalChain([permissions, 'access', _306 => _306.systemPermissions, 'optionalAccess', _307 => _307[resource]]);
12974
+ return _nullishCoalesce(_optionalChain([resourcePerms, 'optionalAccess', _308 => _308.includes, 'call', _309 => _309(action)]), () => ( false));
12728
12975
  }
12729
12976
  /**
12730
12977
  * Check if user can access a system resource, throw ForbiddenError if not.
@@ -12753,8 +13000,8 @@ var PermissionService = class extends BaseService {
12753
13000
  if (permissions.isAdmin) {
12754
13001
  return { canRead: true, canCreate: true, canUpdate: true, canDelete: true };
12755
13002
  }
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]]), () => ( []));
13003
+ const wildcardPerms = _nullishCoalesce(_optionalChain([permissions, 'access', _310 => _310.systemPermissions, 'optionalAccess', _311 => _311["*"]]), () => ( []));
13004
+ const resourcePerms = _nullishCoalesce(_optionalChain([permissions, 'access', _312 => _312.systemPermissions, 'optionalAccess', _313 => _313[resource]]), () => ( []));
12758
13005
  const allPerms = /* @__PURE__ */ new Set([...wildcardPerms, ...resourcePerms]);
12759
13006
  return {
12760
13007
  canRead: allPerms.has("read"),
@@ -12896,7 +13143,7 @@ var PermissionService = class extends BaseService {
12896
13143
  action: "role.updated",
12897
13144
  actorId: this.userId,
12898
13145
  roleId,
12899
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _310 => _310.label]), () => ( roleId)),
13146
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _314 => _314.label]), () => ( roleId)),
12900
13147
  metadata: { permissionsUpdated: true, permissionCount: permissions.length }
12901
13148
  });
12902
13149
  }
@@ -12926,7 +13173,7 @@ var PermissionService = class extends BaseService {
12926
13173
  action: "role.assigned",
12927
13174
  actorId: this.userId,
12928
13175
  roleId,
12929
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _311 => _311.label]), () => ( roleId)),
13176
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _315 => _315.label]), () => ( roleId)),
12930
13177
  targetUserId: userProfileId
12931
13178
  });
12932
13179
  }
@@ -12944,7 +13191,7 @@ var PermissionService = class extends BaseService {
12944
13191
  action: "role.revoked",
12945
13192
  actorId: this.userId,
12946
13193
  roleId,
12947
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _312 => _312.label]), () => ( roleId)),
13194
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _316 => _316.label]), () => ( roleId)),
12948
13195
  targetUserId: userProfileId
12949
13196
  });
12950
13197
  }