@stndrds/schema 0.1.0-alpha.58 → 0.1.0-alpha.59

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.
@@ -4059,6 +4059,91 @@ function createMockObjectRecordsRepository(stores) {
4059
4059
  };
4060
4060
  }
4061
4061
 
4062
+ // src/runtime/mock/mock-relation-attributes.ts
4063
+ var _crypto = require('crypto');
4064
+ function createMockRelationAttributesRepository(stores) {
4065
+ return {
4066
+ async upsertBatch(items) {
4067
+ const context = getContext2();
4068
+ if (!context) {
4069
+ throw new Error("Context required for relationAttributes operations");
4070
+ }
4071
+ const results = [];
4072
+ for (const item of items) {
4073
+ const _key = `${context.tenantId}:${item.fromObject}:${item.fromId}:${item.fromAttribute}:${item.toId}`;
4074
+ const existing = Array.from(stores.relationAttributes.values()).find(
4075
+ (row) => row.tenantId === context.tenantId && row.fromObject === item.fromObject && row.fromId === item.fromId && row.fromAttribute === item.fromAttribute && row.toId === item.toId
4076
+ );
4077
+ if (existing) {
4078
+ existing.properties = _nullishCoalesce(item.properties, () => ( {}));
4079
+ existing.updatedAt = /* @__PURE__ */ new Date();
4080
+ existing.updatedBy = _nullishCoalesce(_nullishCoalesce(item.updatedBy, () => ( context.userId)), () => ( null));
4081
+ results.push(existing);
4082
+ } else {
4083
+ const row = {
4084
+ id: _crypto.randomUUID.call(void 0, ),
4085
+ tenantId: context.tenantId,
4086
+ fromObject: item.fromObject,
4087
+ fromId: item.fromId,
4088
+ fromAttribute: item.fromAttribute,
4089
+ toId: item.toId,
4090
+ properties: _nullishCoalesce(item.properties, () => ( {})),
4091
+ createdAt: /* @__PURE__ */ new Date(),
4092
+ updatedAt: /* @__PURE__ */ new Date(),
4093
+ createdBy: _nullishCoalesce(_nullishCoalesce(item.createdBy, () => ( context.userId)), () => ( null)),
4094
+ updatedBy: _nullishCoalesce(_nullishCoalesce(item.updatedBy, () => ( context.userId)), () => ( null))
4095
+ };
4096
+ stores.relationAttributes.set(row.id, row);
4097
+ results.push(row);
4098
+ }
4099
+ }
4100
+ return results;
4101
+ },
4102
+ async findBySource(fromObject, fromId, fromAttribute) {
4103
+ const context = getContext2();
4104
+ if (!context) {
4105
+ throw new Error("Context required for relationAttributes operations");
4106
+ }
4107
+ return Array.from(stores.relationAttributes.values()).filter(
4108
+ (row) => row.tenantId === context.tenantId && row.fromObject === fromObject && row.fromId === fromId && row.fromAttribute === fromAttribute
4109
+ );
4110
+ },
4111
+ async findByTarget(toId) {
4112
+ const context = getContext2();
4113
+ if (!context) {
4114
+ throw new Error("Context required for relationAttributes operations");
4115
+ }
4116
+ return Array.from(stores.relationAttributes.values()).filter(
4117
+ (row) => row.tenantId === context.tenantId && row.toId === toId
4118
+ );
4119
+ },
4120
+ async deleteBySource(fromObject, fromId, fromAttribute) {
4121
+ const context = getContext2();
4122
+ if (!context) {
4123
+ throw new Error("Context required for relationAttributes operations");
4124
+ }
4125
+ const toDelete = Array.from(stores.relationAttributes.entries()).filter(
4126
+ ([_id, row]) => row.tenantId === context.tenantId && row.fromObject === fromObject && row.fromId === fromId && row.fromAttribute === fromAttribute
4127
+ );
4128
+ for (const [id] of toDelete) {
4129
+ stores.relationAttributes.delete(id);
4130
+ }
4131
+ },
4132
+ async deleteByTarget(toId) {
4133
+ const context = getContext2();
4134
+ if (!context) {
4135
+ throw new Error("Context required for relationAttributes operations");
4136
+ }
4137
+ const toDelete = Array.from(stores.relationAttributes.entries()).filter(
4138
+ ([_id, row]) => row.tenantId === context.tenantId && row.toId === toId
4139
+ );
4140
+ for (const [id] of toDelete) {
4141
+ stores.relationAttributes.delete(id);
4142
+ }
4143
+ }
4144
+ };
4145
+ }
4146
+
4062
4147
  // src/runtime/mock/mock-stores.ts
4063
4148
  function createEmptyStores() {
4064
4149
  return {
@@ -4079,7 +4164,8 @@ function createEmptyStores() {
4079
4164
  aiConversations: /* @__PURE__ */ new Map(),
4080
4165
  aiMessages: /* @__PURE__ */ new Map(),
4081
4166
  aiUserMemory: /* @__PURE__ */ new Map(),
4082
- aiUsageMetrics: /* @__PURE__ */ new Map()
4167
+ aiUsageMetrics: /* @__PURE__ */ new Map(),
4168
+ relationAttributes: /* @__PURE__ */ new Map()
4083
4169
  };
4084
4170
  }
4085
4171
 
@@ -4994,6 +5080,8 @@ function createMockAdapter() {
4994
5080
  aiConversations: createMockAIConversationsRepository(stores),
4995
5081
  aiUserMemory: createMockAIUserMemoryRepository(stores),
4996
5082
  aiUsageMetrics: createMockAIUsageMetricsRepository(stores),
5083
+ // Relation attributes repository
5084
+ relationAttributes: createMockRelationAttributesRepository(stores),
4997
5085
  async transaction(callback) {
4998
5086
  return await callback(adapter);
4999
5087
  },
@@ -5019,6 +5107,7 @@ function createMockAdapter() {
5019
5107
  stores.aiMessages.clear();
5020
5108
  stores.aiUserMemory.clear();
5021
5109
  stores.aiUsageMetrics.clear();
5110
+ stores.relationAttributes.clear();
5022
5111
  }
5023
5112
  };
5024
5113
  return adapter;
@@ -5497,6 +5586,292 @@ function validateOptions(options, attributeName) {
5497
5586
  }
5498
5587
  }
5499
5588
 
5589
+ // src/types/relation-properties.ts
5590
+ var FORBIDDEN_PROPERTY_TYPES = [
5591
+ "formula",
5592
+ "rollup",
5593
+ "relation",
5594
+ "file",
5595
+ "user",
5596
+ "document",
5597
+ "richtext"
5598
+ ];
5599
+
5600
+ // src/builders/property-schema-builder.ts
5601
+ var PropertySchemaBuilder = class {
5602
+ constructor() {
5603
+ this.definitions = [];
5604
+ }
5605
+ /**
5606
+ * Add a property to the schema
5607
+ * The type of property is automatically detected based on the builder methods used
5608
+ */
5609
+ add(name, configure) {
5610
+ const builder = new PropertyTypeBuilder(name);
5611
+ const configured = configure(builder);
5612
+ const definition = configured.build();
5613
+ this.definitions.push(definition);
5614
+ return this;
5615
+ }
5616
+ /**
5617
+ * Build the final PropertySchema
5618
+ */
5619
+ build() {
5620
+ return {
5621
+ definitions: this.definitions
5622
+ };
5623
+ }
5624
+ };
5625
+ var PropertyTypeBuilder = class {
5626
+ constructor(name) {
5627
+ this.name = name;
5628
+ }
5629
+ // Explicit type constructors
5630
+ text() {
5631
+ return new TextPropertyBuilder(this.name);
5632
+ }
5633
+ textarea() {
5634
+ return new TextareaPropertyBuilder(this.name);
5635
+ }
5636
+ number() {
5637
+ return new NumberPropertyBuilder(this.name);
5638
+ }
5639
+ checkbox() {
5640
+ return new CheckboxPropertyBuilder(this.name);
5641
+ }
5642
+ date() {
5643
+ return new DatePropertyBuilder(this.name);
5644
+ }
5645
+ phone() {
5646
+ return new PhonePropertyBuilder(this.name);
5647
+ }
5648
+ currency() {
5649
+ return new CurrencyPropertyBuilder(this.name);
5650
+ }
5651
+ status() {
5652
+ return new StatusPropertyBuilder(this.name);
5653
+ }
5654
+ select() {
5655
+ return new SelectPropertyBuilder(this.name);
5656
+ }
5657
+ multiselect() {
5658
+ return new MultiselectPropertyBuilder(this.name);
5659
+ }
5660
+ rating() {
5661
+ return new RatingPropertyBuilder(this.name);
5662
+ }
5663
+ location() {
5664
+ return new LocationPropertyBuilder(this.name);
5665
+ }
5666
+ };
5667
+ var BasePropertyBuilder = class {
5668
+ constructor(name) {
5669
+ this.definition = { name };
5670
+ }
5671
+ /**
5672
+ * Set the label
5673
+ */
5674
+ label(label) {
5675
+ this.definition.label = label;
5676
+ return this;
5677
+ }
5678
+ /**
5679
+ * Mark as required
5680
+ */
5681
+ required() {
5682
+ this.definition.required = true;
5683
+ return this;
5684
+ }
5685
+ /**
5686
+ * Set description
5687
+ */
5688
+ description(description) {
5689
+ this.definition.description = description;
5690
+ return this;
5691
+ }
5692
+ /**
5693
+ * Build the final definition
5694
+ */
5695
+ build() {
5696
+ return this.definition;
5697
+ }
5698
+ };
5699
+ var TextPropertyBuilder = class extends BasePropertyBuilder {
5700
+ constructor(name) {
5701
+ super(name);
5702
+ this.definition.type = "text";
5703
+ }
5704
+ minLength(value) {
5705
+ this.definition.minLength = value;
5706
+ return this;
5707
+ }
5708
+ maxLength(value) {
5709
+ this.definition.maxLength = value;
5710
+ return this;
5711
+ }
5712
+ pattern(pattern) {
5713
+ this.definition.pattern = pattern;
5714
+ return this;
5715
+ }
5716
+ placeholder(value) {
5717
+ this.definition.placeholder = value;
5718
+ return this;
5719
+ }
5720
+ };
5721
+ var TextareaPropertyBuilder = class extends BasePropertyBuilder {
5722
+ constructor(name) {
5723
+ super(name);
5724
+ this.definition.type = "textarea";
5725
+ }
5726
+ minLength(value) {
5727
+ this.definition.minLength = value;
5728
+ return this;
5729
+ }
5730
+ maxLength(value) {
5731
+ this.definition.maxLength = value;
5732
+ return this;
5733
+ }
5734
+ placeholder(value) {
5735
+ this.definition.placeholder = value;
5736
+ return this;
5737
+ }
5738
+ };
5739
+ var NumberPropertyBuilder = class extends BasePropertyBuilder {
5740
+ constructor(name) {
5741
+ super(name);
5742
+ this.definition.type = "number";
5743
+ }
5744
+ min(value) {
5745
+ this.definition.min = value;
5746
+ return this;
5747
+ }
5748
+ max(value) {
5749
+ this.definition.max = value;
5750
+ return this;
5751
+ }
5752
+ decimal(places) {
5753
+ this.definition.decimal = places;
5754
+ return this;
5755
+ }
5756
+ integer() {
5757
+ this.definition.integer = true;
5758
+ return this;
5759
+ }
5760
+ placeholder(value) {
5761
+ this.definition.placeholder = value;
5762
+ return this;
5763
+ }
5764
+ };
5765
+ var CheckboxPropertyBuilder = class extends BasePropertyBuilder {
5766
+ constructor(name) {
5767
+ super(name);
5768
+ this.definition.type = "checkbox";
5769
+ }
5770
+ };
5771
+ var DatePropertyBuilder = class extends BasePropertyBuilder {
5772
+ constructor(name) {
5773
+ super(name);
5774
+ this.definition.type = "date";
5775
+ }
5776
+ includeTime() {
5777
+ this.definition.includeTime = true;
5778
+ return this;
5779
+ }
5780
+ min(date2) {
5781
+ this.definition.min = date2;
5782
+ return this;
5783
+ }
5784
+ max(date2) {
5785
+ this.definition.max = date2;
5786
+ return this;
5787
+ }
5788
+ };
5789
+ var PhonePropertyBuilder = class extends BasePropertyBuilder {
5790
+ constructor(name) {
5791
+ super(name);
5792
+ this.definition.type = "phone";
5793
+ }
5794
+ };
5795
+ var CurrencyPropertyBuilder = class extends BasePropertyBuilder {
5796
+ constructor(name) {
5797
+ super(name);
5798
+ this.definition.type = "currency";
5799
+ }
5800
+ currency(code) {
5801
+ this.definition.currency = code;
5802
+ return this;
5803
+ }
5804
+ min(value) {
5805
+ this.definition.min = value;
5806
+ return this;
5807
+ }
5808
+ max(value) {
5809
+ this.definition.max = value;
5810
+ return this;
5811
+ }
5812
+ };
5813
+ var StatusPropertyBuilder = class extends BasePropertyBuilder {
5814
+ constructor(name) {
5815
+ super(name);
5816
+ this.definition.type = "status";
5817
+ }
5818
+ options(options) {
5819
+ this.definition.options = options;
5820
+ return this;
5821
+ }
5822
+ };
5823
+ var SelectPropertyBuilder = class extends BasePropertyBuilder {
5824
+ constructor(name) {
5825
+ super(name);
5826
+ this.definition.type = "select";
5827
+ }
5828
+ options(options) {
5829
+ this.definition.options = options;
5830
+ return this;
5831
+ }
5832
+ };
5833
+ var MultiselectPropertyBuilder = class extends BasePropertyBuilder {
5834
+ constructor(name) {
5835
+ super(name);
5836
+ this.definition.type = "multiselect";
5837
+ }
5838
+ options(options) {
5839
+ this.definition.options = options;
5840
+ return this;
5841
+ }
5842
+ maxSelections(value) {
5843
+ this.definition.maxSelections = value;
5844
+ return this;
5845
+ }
5846
+ };
5847
+ var RatingPropertyBuilder = class extends BasePropertyBuilder {
5848
+ constructor(name) {
5849
+ super(name);
5850
+ this.definition.type = "rating";
5851
+ }
5852
+ max(value) {
5853
+ this.definition.max = value;
5854
+ return this;
5855
+ }
5856
+ icon(icon) {
5857
+ this.definition.icon = icon;
5858
+ return this;
5859
+ }
5860
+ };
5861
+ var LocationPropertyBuilder = class extends BasePropertyBuilder {
5862
+ constructor(name) {
5863
+ super(name);
5864
+ this.definition.type = "location";
5865
+ }
5866
+ };
5867
+ function validatePropertyType(type) {
5868
+ if (FORBIDDEN_PROPERTY_TYPES.includes(type)) {
5869
+ throw new Error(
5870
+ `Property type "${type}" is not supported in .qualifyWith(). Only simple types (text, number, date, select, etc.) are allowed. Complex types (formula, rollup, relation, file, user, document) would require duplicating backend behavior.`
5871
+ );
5872
+ }
5873
+ }
5874
+
5500
5875
  // src/builders/attribute-builders.ts
5501
5876
  var BaseAttributeBuilder = class {
5502
5877
  constructor(type, name, label) {
@@ -6053,6 +6428,32 @@ var SingleRelationAttributeBuilder = class extends BaseAttributeBuilder {
6053
6428
  );
6054
6429
  return multiBuilder;
6055
6430
  }
6431
+ /**
6432
+ * Add properties to qualify the relation
6433
+ * Must be called AFTER .to() to ensure targets are defined
6434
+ *
6435
+ * @example
6436
+ * ```typescript
6437
+ * relation({ name: "mainCompany", label: "Main Company" })
6438
+ * .to("companies")
6439
+ * .qualifyWith(props => props
6440
+ * .add("role", select => select.options([...]).required())
6441
+ * .add("shares", number => number.min(0))
6442
+ * )
6443
+ * ```
6444
+ */
6445
+ qualifyWith(configure) {
6446
+ const targets = this.attr.targets;
6447
+ if (!targets || targets.length === 0) {
6448
+ throw new Error(
6449
+ '.qualifyWith() must be called AFTER .to(). Example: relation({ name: "mainCompany" }).to("companies").qualifyWith(...)'
6450
+ );
6451
+ }
6452
+ const builder = new PropertySchemaBuilder();
6453
+ const schema = configure(builder).build();
6454
+ this.attr.properties = schema;
6455
+ return this;
6456
+ }
6056
6457
  required() {
6057
6458
  this.setRequired(true);
6058
6459
  return this;
@@ -6114,6 +6515,33 @@ var MultiRelationAttributeBuilder = class extends BaseAttributeBuilder {
6114
6515
  this.attr.maxItems = count;
6115
6516
  return this;
6116
6517
  }
6518
+ /**
6519
+ * Add properties to qualify the relation
6520
+ * Must be called AFTER .to() or .many() to ensure targets are defined
6521
+ *
6522
+ * @example
6523
+ * ```typescript
6524
+ * relation({ name: "companies", label: "Companies" })
6525
+ * .to("companies")
6526
+ * .many()
6527
+ * .qualifyWith(props => props
6528
+ * .add("role", select => select.options([...]).required())
6529
+ * .add("shares", number => number.min(0))
6530
+ * )
6531
+ * ```
6532
+ */
6533
+ qualifyWith(configure) {
6534
+ const targets = this.attr.targets;
6535
+ if (!targets || targets.length === 0) {
6536
+ throw new Error(
6537
+ '.qualifyWith() must be called AFTER .to() or .many(). Example: relation({ name: "companies" }).to("companies").many().qualifyWith(...)'
6538
+ );
6539
+ }
6540
+ const builder = new PropertySchemaBuilder();
6541
+ const schema = configure(builder).build();
6542
+ this.attr.properties = schema;
6543
+ return this;
6544
+ }
6117
6545
  required() {
6118
6546
  this.setRequired(true);
6119
6547
  return this;
@@ -6499,7 +6927,7 @@ function object(config) {
6499
6927
  }
6500
6928
 
6501
6929
  // src/builders/view-builder.ts
6502
- var _crypto = require('crypto');
6930
+
6503
6931
 
6504
6932
  var GroupBuilder = class {
6505
6933
  constructor(id, label) {
@@ -9799,7 +10227,14 @@ var RecordQueryService = class extends BaseService {
9799
10227
  effectiveTotal = exhausted ? collected.length : Math.max(collected.length, result.total);
9800
10228
  filteredRecords = collected.slice(requestedOffset, requestedOffset + requestedLimit);
9801
10229
  }
9802
- if (!_optionalChain([options, 'optionalAccess', _201 => _201.skipFormulas])) {
10230
+ if (_optionalChain([options, 'optionalAccess', _201 => _201.include]) && options.include.length > 0) {
10231
+ filteredRecords = await this.includeRelationsWithProperties(
10232
+ filteredRecords,
10233
+ schema,
10234
+ options.include
10235
+ );
10236
+ }
10237
+ if (!_optionalChain([options, 'optionalAccess', _202 => _202.skipFormulas])) {
9803
10238
  return {
9804
10239
  records: enrichRecordsWithFormulas(filteredRecords, schema),
9805
10240
  total: effectiveTotal
@@ -9859,14 +10294,14 @@ var RecordQueryService = class extends BaseService {
9859
10294
  * Internal search query execution
9860
10295
  */
9861
10296
  async executeSearchQuery(schema, objectId, query, options) {
9862
- if (_optionalChain([this, 'access', _202 => _202.options, 'optionalAccess', _203 => _203.permissionService]) && this.userId) {
10297
+ if (_optionalChain([this, 'access', _203 => _203.options, 'optionalAccess', _204 => _204.permissionService]) && this.userId) {
9863
10298
  await checkPermission(this.options.permissionService, this.userId, schema.name, "read");
9864
10299
  }
9865
10300
  const result = await runWithSchemaContext(
9866
10301
  [schema],
9867
10302
  () => this.adapter.objectRecords.search(objectId, query, options)
9868
10303
  );
9869
- if (!_optionalChain([options, 'optionalAccess', _204 => _204.skipFormulas])) {
10304
+ if (!_optionalChain([options, 'optionalAccess', _205 => _205.skipFormulas])) {
9870
10305
  return {
9871
10306
  records: enrichRecordsWithFormulas(result.records, schema),
9872
10307
  total: result.total
@@ -9874,6 +10309,79 @@ var RecordQueryService = class extends BaseService {
9874
10309
  }
9875
10310
  return result;
9876
10311
  }
10312
+ // ============================================================================
10313
+ // INCLUDE RELATIONS WITH PROPERTIES
10314
+ // ============================================================================
10315
+ /**
10316
+ * Include relation properties in records.
10317
+ *
10318
+ * For each requested relation attribute:
10319
+ * - If attribute has properties → Fetch from relation_attributes and return hybrid format
10320
+ * - If attribute has NO properties → Return legacy format (string[] or string)
10321
+ *
10322
+ * Uses batch loading to avoid N+1 queries.
10323
+ *
10324
+ * @param records - Records to enrich with relation properties
10325
+ * @param schema - Object schema
10326
+ * @param includes - Array of relation attribute names to include
10327
+ * @returns Records enriched with relation properties in hybrid format
10328
+ * @private
10329
+ */
10330
+ async includeRelationsWithProperties(records, schema, includes) {
10331
+ if (records.length === 0 || includes.length === 0) {
10332
+ return records;
10333
+ }
10334
+ for (const includeName of includes) {
10335
+ const attr = schema.attributes.find((a) => a.name === includeName);
10336
+ if (!attr || attr.type !== "relation") {
10337
+ continue;
10338
+ }
10339
+ if (attr.properties && this.adapter.relationAttributes) {
10340
+ const recordIds = records.map((r) => r.id);
10341
+ const relationAttributesRepo = this.adapter.relationAttributes;
10342
+ const allRelationProps = await Promise.all(
10343
+ recordIds.map(
10344
+ (recordId) => relationAttributesRepo.findBySource(schema.name, recordId, includeName)
10345
+ )
10346
+ );
10347
+ const propsByRecord = /* @__PURE__ */ new Map();
10348
+ allRelationProps.forEach((props, index) => {
10349
+ const recordId = recordIds[index];
10350
+ const propsMap = /* @__PURE__ */ new Map();
10351
+ for (const prop of props) {
10352
+ propsMap.set(prop.toId, prop.properties);
10353
+ }
10354
+ propsByRecord.set(recordId, propsMap);
10355
+ });
10356
+ for (const record of records) {
10357
+ const currentValue = record.values[includeName];
10358
+ const propsMap = propsByRecord.get(record.id);
10359
+ if (!currentValue) {
10360
+ continue;
10361
+ }
10362
+ if (!propsMap) {
10363
+ continue;
10364
+ }
10365
+ if (attr.cardinality === "many" && Array.isArray(currentValue)) {
10366
+ record.values[includeName] = currentValue.map((id) => {
10367
+ if (typeof id === "string") {
10368
+ const props = propsMap.get(id);
10369
+ return props ? { id, props } : { id };
10370
+ }
10371
+ return id;
10372
+ });
10373
+ } else if (attr.cardinality === "one") {
10374
+ const id = typeof currentValue === "string" ? currentValue : null;
10375
+ if (id) {
10376
+ const props = propsMap.get(id);
10377
+ record.values[includeName] = props ? { id, props } : { id };
10378
+ }
10379
+ }
10380
+ }
10381
+ }
10382
+ }
10383
+ return records;
10384
+ }
9877
10385
  };
9878
10386
 
9879
10387
  // src/runtime/services/record/record-resolver.service.ts
@@ -9968,6 +10476,280 @@ var RecordResolverService = class extends BaseService {
9968
10476
  }
9969
10477
  };
9970
10478
 
10479
+ // src/runtime/services/record/relation-properties.service.ts
10480
+
10481
+ var RelationPropertiesService = class extends BaseService {
10482
+ constructor(adapter) {
10483
+ super(adapter);
10484
+ }
10485
+ // ============================================================================
10486
+ // PUBLIC API
10487
+ // ============================================================================
10488
+ /**
10489
+ * Normalize relation values for storage in object_records table.
10490
+ *
10491
+ * Extracts IDs from hybrid format ({ id, props }) and returns legacy format (string[] or string).
10492
+ * This ensures object_records.values only contains IDs, while properties are in relation_attributes.
10493
+ *
10494
+ * @param schema - Object schema
10495
+ * @param data - Record data with hybrid relation values
10496
+ * @returns Data with relation values normalized to ID-only format
10497
+ */
10498
+ normalizeRelationValuesForStorage(schema, data) {
10499
+ const normalized = { ...data };
10500
+ for (const attr of schema.attributes) {
10501
+ if (attr.type !== "relation" || !attr.properties) {
10502
+ continue;
10503
+ }
10504
+ const value = data[attr.name];
10505
+ if (value === null || value === void 0) {
10506
+ continue;
10507
+ }
10508
+ if (attr.cardinality === "many" && Array.isArray(value)) {
10509
+ normalized[attr.name] = value.map((item) => {
10510
+ if (typeof item === "string") return item;
10511
+ if (typeof item === "object" && item !== null && "id" in item) {
10512
+ return item.id;
10513
+ }
10514
+ return item;
10515
+ });
10516
+ } else if (typeof value === "object" && value !== null && "id" in value) {
10517
+ normalized[attr.name] = value.id;
10518
+ }
10519
+ }
10520
+ return normalized;
10521
+ }
10522
+ /**
10523
+ * Synchronize relation properties for a given attribute.
10524
+ *
10525
+ * Handles:
10526
+ * - Format normalization (legacy → new)
10527
+ * - Validation of properties
10528
+ * - Upsert for present IDs
10529
+ * - Delete for absent IDs
10530
+ *
10531
+ * @param schema - Object schema
10532
+ * @param recordId - Source record ID
10533
+ * @param attributeName - Relation attribute name
10534
+ * @param relationValue - Relation value (hybrid format)
10535
+ * @param adapter - Database adapter
10536
+ */
10537
+ async syncRelationProperties(schema, recordId, attributeName, relationValue, adapter) {
10538
+ const attribute = schema.attributes.find((a) => a.name === attributeName);
10539
+ if (!attribute || attribute.type !== "relation") {
10540
+ return;
10541
+ }
10542
+ if (!attribute.properties) {
10543
+ return;
10544
+ }
10545
+ const normalized = this.normalizeRelationValue(relationValue);
10546
+ for (const item of normalized) {
10547
+ if (item.props) {
10548
+ this.validateProperties(attribute.properties, item.props);
10549
+ }
10550
+ }
10551
+ const existing = await _optionalChain([adapter, 'access', _206 => _206.relationAttributes, 'optionalAccess', _207 => _207.findBySource, 'call', _208 => _208(
10552
+ schema.name,
10553
+ recordId,
10554
+ attributeName
10555
+ )]);
10556
+ const existingIds = new Set((_nullishCoalesce(existing, () => ( []))).map((r) => r.toId));
10557
+ const newIds = new Set(normalized.map((item) => item.id));
10558
+ const toUpsert = normalized.filter((item) => item.props !== void 0);
10559
+ const toDelete = Array.from(existingIds).filter((id) => !newIds.has(id));
10560
+ if (toUpsert.length > 0 && adapter.relationAttributes) {
10561
+ const inputs = toUpsert.map((item) => ({
10562
+ fromObject: schema.name,
10563
+ fromId: recordId,
10564
+ fromAttribute: attributeName,
10565
+ toId: item.id,
10566
+ properties: _nullishCoalesce(item.props, () => ( {})),
10567
+ updatedBy: _nullishCoalesce(this.userId, () => ( void 0)),
10568
+ createdBy: _nullishCoalesce(this.userId, () => ( void 0))
10569
+ }));
10570
+ await adapter.relationAttributes.upsertBatch(inputs);
10571
+ }
10572
+ if (toDelete.length > 0 && adapter.relationAttributes && existing) {
10573
+ for (const toId of toDelete) {
10574
+ const relation2 = existing.find((r) => r.toId === toId);
10575
+ if (relation2) {
10576
+ }
10577
+ }
10578
+ await adapter.relationAttributes.deleteBySource(schema.name, recordId, attributeName);
10579
+ if (toUpsert.length > 0) {
10580
+ const inputs = toUpsert.map((item) => ({
10581
+ fromObject: schema.name,
10582
+ fromId: recordId,
10583
+ fromAttribute: attributeName,
10584
+ toId: item.id,
10585
+ properties: _nullishCoalesce(item.props, () => ( {})),
10586
+ updatedBy: _nullishCoalesce(this.userId, () => ( void 0)),
10587
+ createdBy: _nullishCoalesce(this.userId, () => ( void 0))
10588
+ }));
10589
+ await adapter.relationAttributes.upsertBatch(inputs);
10590
+ }
10591
+ }
10592
+ }
10593
+ /**
10594
+ * Validate relation properties against PropertySchema.
10595
+ *
10596
+ * Uses Zod for runtime validation based on PropertyDefinition types.
10597
+ *
10598
+ * @param propertySchema - Schema defining allowed properties
10599
+ * @param properties - Properties to validate
10600
+ * @throws {z.ZodError} if validation fails
10601
+ */
10602
+ validateProperties(propertySchema, properties) {
10603
+ const schema = this.buildZodSchema(propertySchema);
10604
+ schema.parse(properties);
10605
+ }
10606
+ // ============================================================================
10607
+ // PRIVATE HELPERS
10608
+ // ============================================================================
10609
+ /**
10610
+ * Normalize relation value to unified internal format.
10611
+ *
10612
+ * Converts:
10613
+ * - string[] → Array<{ id, props?: undefined }>
10614
+ * - string → [{ id, props?: undefined }]
10615
+ * - null → []
10616
+ * - Array<{ id, props }> → Array<{ id, props }> (passthrough)
10617
+ * - { id, props } → [{ id, props }] (single to array)
10618
+ *
10619
+ * @param value - Relation value in hybrid format
10620
+ * @returns Normalized array of relation items
10621
+ * @private
10622
+ */
10623
+ normalizeRelationValue(value) {
10624
+ if (value === null || value === void 0) {
10625
+ return [];
10626
+ }
10627
+ if (typeof value === "string") {
10628
+ return [{ id: value }];
10629
+ }
10630
+ if (!Array.isArray(value) && typeof value === "object" && "id" in value) {
10631
+ return [value];
10632
+ }
10633
+ if (Array.isArray(value)) {
10634
+ return value.map((item) => {
10635
+ if (typeof item === "string") {
10636
+ return { id: item };
10637
+ }
10638
+ return item;
10639
+ });
10640
+ }
10641
+ return [];
10642
+ }
10643
+ /**
10644
+ * Build Zod schema from PropertySchema definition.
10645
+ *
10646
+ * Dynamically generates validation schema based on PropertyDefinition types.
10647
+ *
10648
+ * @param propertySchema - PropertySchema with definitions
10649
+ * @returns Zod schema for validation
10650
+ * @private
10651
+ */
10652
+ buildZodSchema(propertySchema) {
10653
+ const shape = {};
10654
+ for (const def of propertySchema.definitions) {
10655
+ let fieldSchema = this.buildFieldSchema(def);
10656
+ if (!def.required) {
10657
+ fieldSchema = fieldSchema.optional();
10658
+ }
10659
+ shape[def.name] = fieldSchema;
10660
+ }
10661
+ return _zod.z.object(shape);
10662
+ }
10663
+ /**
10664
+ * Build Zod schema for a single property field.
10665
+ *
10666
+ * @param def - PropertyDefinition
10667
+ * @returns Zod schema for the field
10668
+ * @private
10669
+ */
10670
+ buildFieldSchema(def) {
10671
+ switch (def.type) {
10672
+ case "text":
10673
+ case "textarea": {
10674
+ let schema = _zod.z.string();
10675
+ if (def.minLength !== void 0) {
10676
+ schema = schema.min(def.minLength);
10677
+ }
10678
+ if (def.maxLength !== void 0) {
10679
+ schema = schema.max(def.maxLength);
10680
+ }
10681
+ if (def.type === "text" && def.pattern) {
10682
+ schema = schema.regex(new RegExp(def.pattern));
10683
+ }
10684
+ return schema;
10685
+ }
10686
+ case "number": {
10687
+ let schema = _zod.z.number();
10688
+ if (def.min !== void 0) {
10689
+ schema = schema.min(def.min);
10690
+ }
10691
+ if (def.max !== void 0) {
10692
+ schema = schema.max(def.max);
10693
+ }
10694
+ if (def.integer) {
10695
+ schema = schema.int();
10696
+ }
10697
+ return schema;
10698
+ }
10699
+ case "checkbox": {
10700
+ return _zod.z.boolean();
10701
+ }
10702
+ case "date": {
10703
+ const schema = _zod.z.string().datetime();
10704
+ return schema;
10705
+ }
10706
+ case "phone": {
10707
+ return _zod.z.string();
10708
+ }
10709
+ case "currency": {
10710
+ let schema = _zod.z.number();
10711
+ if (def.min !== void 0) {
10712
+ schema = schema.min(def.min);
10713
+ }
10714
+ if (def.max !== void 0) {
10715
+ schema = schema.max(def.max);
10716
+ }
10717
+ return schema;
10718
+ }
10719
+ case "status":
10720
+ case "select": {
10721
+ const validValues = def.options.map((opt) => opt.value);
10722
+ return _zod.z.enum(validValues);
10723
+ }
10724
+ case "multiselect": {
10725
+ const validValues = def.options.map((opt) => opt.value);
10726
+ let schema = _zod.z.array(_zod.z.enum(validValues));
10727
+ if (def.maxSelections !== void 0) {
10728
+ schema = schema.max(def.maxSelections);
10729
+ }
10730
+ return schema;
10731
+ }
10732
+ case "rating": {
10733
+ let schema = _zod.z.number().int();
10734
+ if (def.max !== void 0) {
10735
+ schema = schema.max(def.max);
10736
+ }
10737
+ return schema.min(0);
10738
+ }
10739
+ case "location": {
10740
+ return _zod.z.object({
10741
+ address: _zod.z.string().optional(),
10742
+ lat: _zod.z.number().optional(),
10743
+ lng: _zod.z.number().optional()
10744
+ });
10745
+ }
10746
+ default: {
10747
+ return _zod.z.unknown();
10748
+ }
10749
+ }
10750
+ }
10751
+ };
10752
+
9971
10753
  // src/runtime/services/record/relation.service.ts
9972
10754
  var RelationService = class extends BaseService {
9973
10755
  constructor(adapter, nativeRegistry, options) {
@@ -10045,7 +10827,7 @@ var RelationService = class extends BaseService {
10045
10827
  }
10046
10828
  const isUniversal = attr.targets.length === 1 && attr.targets[0].object === RELATION_TARGET_ANY;
10047
10829
  const validObjectIds = isUniversal ? null : await this.getValidObjectIds(attr.targets);
10048
- if (!isUniversal && _optionalChain([validObjectIds, 'optionalAccess', _205 => _205.size]) === 0) {
10830
+ if (!isUniversal && _optionalChain([validObjectIds, 'optionalAccess', _209 => _209.size]) === 0) {
10049
10831
  errors.push({
10050
10832
  attribute: attr.name,
10051
10833
  message: `No valid target objects found for ${attr.label}`
@@ -10098,7 +10880,7 @@ var RelationService = class extends BaseService {
10098
10880
  for (const target of targets) {
10099
10881
  try {
10100
10882
  const objectSchema = await this.schemaService.getObjectSchemaByName(target.object);
10101
- if (_optionalChain([objectSchema, 'optionalAccess', _206 => _206.id])) {
10883
+ if (_optionalChain([objectSchema, 'optionalAccess', _210 => _210.id])) {
10102
10884
  objectIds.add(objectSchema.id);
10103
10885
  }
10104
10886
  } catch (e12) {
@@ -10167,7 +10949,7 @@ var RelationService = class extends BaseService {
10167
10949
  const targetResults = await Promise.all(
10168
10950
  filteredTargets.map(async (target) => {
10169
10951
  const objectSchema = await this.schemaService.getObjectSchemaByName(target.object);
10170
- if (!_optionalChain([objectSchema, 'optionalAccess', _207 => _207.id])) return { options: [], total: 0 };
10952
+ if (!_optionalChain([objectSchema, 'optionalAccess', _211 => _211.id])) return { options: [], total: 0 };
10171
10953
  const objectId = objectSchema.id;
10172
10954
  const result = query ? await queryService.searchRecords(objectId, query, queryOptions) : await queryService.listRecords(objectId, queryOptions);
10173
10955
  const options = await Promise.all(
@@ -10324,8 +11106,8 @@ var RelationService = class extends BaseService {
10324
11106
  continue;
10325
11107
  }
10326
11108
  const attribute = attributeMap.get(attributeId);
10327
- const targetConfig = _optionalChain([attribute, 'optionalAccess', _208 => _208.targets, 'optionalAccess', _209 => _209.find, 'call', _210 => _210((t) => t.object === objectSchema.name)]);
10328
- const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _211 => _211.displayTemplate]);
11109
+ const targetConfig = _optionalChain([attribute, 'optionalAccess', _212 => _212.targets, 'optionalAccess', _213 => _213.find, 'call', _214 => _214((t) => t.object === objectSchema.name)]);
11110
+ const customTemplate = _optionalChain([targetConfig, 'optionalAccess', _215 => _215.displayTemplate]);
10329
11111
  const label = await this.resolveLabel(record, objectSchema, customTemplate);
10330
11112
  resolved.push({
10331
11113
  _compositeId: compositeId,
@@ -10475,14 +11257,14 @@ var RollupService = class extends BaseService {
10475
11257
  const sourceSchema = getSchemaByNameFromContext(sourceObjectName);
10476
11258
  let sourceObjectId;
10477
11259
  let reverseRelationAttrName;
10478
- if (_optionalChain([sourceSchema, 'optionalAccess', _212 => _212.id])) {
11260
+ if (_optionalChain([sourceSchema, 'optionalAccess', _216 => _216.id])) {
10479
11261
  sourceObjectId = sourceSchema.id;
10480
11262
  const reverseRelationAttr = sourceSchema.attributes.find((attr) => {
10481
11263
  if (attr.type !== "relation") return false;
10482
11264
  const relationConfig = attr;
10483
- return _optionalChain([relationConfig, 'optionalAccess', _213 => _213.targets, 'optionalAccess', _214 => _214.some, 'call', _215 => _215((t) => t.object === schema.name)]);
11265
+ return _optionalChain([relationConfig, 'optionalAccess', _217 => _217.targets, 'optionalAccess', _218 => _218.some, 'call', _219 => _219((t) => t.object === schema.name)]);
10484
11266
  });
10485
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _216 => _216.name]);
11267
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _220 => _220.name]);
10486
11268
  } else {
10487
11269
  const sourceObject = await this.adapter.objects.findByName(sourceObjectName);
10488
11270
  if (!sourceObject) {
@@ -10493,9 +11275,9 @@ var RollupService = class extends BaseService {
10493
11275
  const reverseRelationAttr = sourceAttributes.find((attr) => {
10494
11276
  if (attr.type !== "relation") return false;
10495
11277
  const relationConfig = attr.config;
10496
- return _optionalChain([relationConfig, 'optionalAccess', _217 => _217.targets, 'optionalAccess', _218 => _218.some, 'call', _219 => _219((t) => t.object === schema.name)]);
11278
+ return _optionalChain([relationConfig, 'optionalAccess', _221 => _221.targets, 'optionalAccess', _222 => _222.some, 'call', _223 => _223((t) => t.object === schema.name)]);
10497
11279
  });
10498
- reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _220 => _220.name]);
11280
+ reverseRelationAttrName = _optionalChain([reverseRelationAttr, 'optionalAccess', _224 => _224.name]);
10499
11281
  }
10500
11282
  if (!reverseRelationAttrName) {
10501
11283
  return { value: null, recordCount: 0 };
@@ -10751,13 +11533,13 @@ var RollupService = class extends BaseService {
10751
11533
  if (!obj) continue;
10752
11534
  for (const rollupDbAttr of rollupAttrs) {
10753
11535
  const rollupConfig = rollupDbAttr.config;
10754
- if (!_optionalChain([rollupConfig, 'optionalAccess', _221 => _221.relationAttribute])) continue;
11536
+ if (!_optionalChain([rollupConfig, 'optionalAccess', _225 => _225.relationAttribute])) continue;
10755
11537
  const relationAttr = attributes.find(
10756
11538
  (a) => a.type === "relation" && a.name === rollupConfig.relationAttribute
10757
11539
  );
10758
11540
  if (!relationAttr) continue;
10759
11541
  const relationConfig = relationAttr.config;
10760
- const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _222 => _222.targets, 'optionalAccess', _223 => _223.some, 'call', _224 => _224(
11542
+ const targetsChangedObject = _optionalChain([relationConfig, 'optionalAccess', _226 => _226.targets, 'optionalAccess', _227 => _227.some, 'call', _228 => _228(
10761
11543
  (t) => t.object === changedSchema.name
10762
11544
  )]);
10763
11545
  if (!targetsChangedObject) continue;
@@ -10782,11 +11564,11 @@ var RecordService = class extends BaseService {
10782
11564
  constructor(adapter, options) {
10783
11565
  super(adapter);
10784
11566
  this.schemaService = new ObjectSchemaService(adapter, registry, {
10785
- auditService: _optionalChain([options, 'optionalAccess', _225 => _225.auditService])
11567
+ auditService: _optionalChain([options, 'optionalAccess', _229 => _229.auditService])
10786
11568
  });
10787
- this.permissionService = _optionalChain([options, 'optionalAccess', _226 => _226.permissionService]);
10788
- this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _227 => _227.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
10789
- this.policyRegistry = _optionalChain([options, 'optionalAccess', _228 => _228.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _229 => _229.policyRegistry]), () => ( defaultPolicyRegistry));
11569
+ this.permissionService = _optionalChain([options, 'optionalAccess', _230 => _230.permissionService]);
11570
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _231 => _231.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
11571
+ this.policyRegistry = _optionalChain([options, 'optionalAccess', _232 => _232.policyRegistry]) === null ? null : _nullishCoalesce(_optionalChain([options, 'optionalAccess', _233 => _233.policyRegistry]), () => ( defaultPolicyRegistry));
10790
11572
  this.recordResolver = new RecordResolverService(adapter);
10791
11573
  this.queryService = new RecordQueryService(adapter, this.schemaService, {
10792
11574
  permissionService: this.permissionService,
@@ -10796,11 +11578,12 @@ var RecordService = class extends BaseService {
10796
11578
  queryService: this.queryService,
10797
11579
  recordResolver: this.recordResolver
10798
11580
  });
11581
+ this.relationPropertiesService = new RelationPropertiesService(adapter);
10799
11582
  this.rollupService = new RollupService(adapter, {
10800
11583
  recordResolver: this.recordResolver
10801
11584
  });
10802
11585
  this.userService = new UserService(adapter);
10803
- this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _230 => _230.hookRegistry]), () => ( new NoopHookRegistry()));
11586
+ this.hookRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _234 => _234.hookRegistry]), () => ( new NoopHookRegistry()));
10804
11587
  this.labelResolver = this.recordResolver.createLabelResolver(this.relationService);
10805
11588
  this.rollupContext = this.recordResolver.createRollupContext(
10806
11589
  this.rollupService,
@@ -10835,35 +11618,51 @@ var RecordService = class extends BaseService {
10835
11618
  schema,
10836
11619
  this.tenantId,
10837
11620
  dataWithDefaults,
10838
- _optionalChain([options, 'optionalAccess', _231 => _231.hookMetadata])
11621
+ _optionalChain([options, 'optionalAccess', _235 => _235.hookMetadata])
10839
11622
  );
10840
- if (!_optionalChain([options, 'optionalAccess', _232 => _232.skipHooks])) {
11623
+ if (!_optionalChain([options, 'optionalAccess', _236 => _236.skipHooks])) {
10841
11624
  await this.hookRegistry.execute("beforeCreate", schema.name, hookCtx);
10842
11625
  }
10843
- if (_optionalChain([options, 'optionalAccess', _233 => _233.validate]) !== false) {
10844
- if (_optionalChain([options, 'optionalAccess', _234 => _234.allowDraft])) {
10845
- _chunkU4AB53AMjs.validateDraftOrThrow.call(void 0, schema, dataWithDefaults);
11626
+ const normalizedData = this.relationPropertiesService.normalizeRelationValuesForStorage(
11627
+ schema,
11628
+ dataWithDefaults
11629
+ );
11630
+ if (_optionalChain([options, 'optionalAccess', _237 => _237.validate]) !== false) {
11631
+ if (_optionalChain([options, 'optionalAccess', _238 => _238.allowDraft])) {
11632
+ _chunkU4AB53AMjs.validateDraftOrThrow.call(void 0, schema, normalizedData);
10846
11633
  } else {
10847
- _chunkU4AB53AMjs.validateObjectOrThrow.call(void 0, schema, dataWithDefaults);
11634
+ _chunkU4AB53AMjs.validateObjectOrThrow.call(void 0, schema, normalizedData);
10848
11635
  }
10849
- if (!_optionalChain([options, 'optionalAccess', _235 => _235.skipRelationValidation])) {
10850
- await this.relationService.validateRelationsOrThrow(schema, dataWithDefaults);
11636
+ if (!_optionalChain([options, 'optionalAccess', _239 => _239.skipRelationValidation])) {
11637
+ await this.relationService.validateRelationsOrThrow(schema, normalizedData);
10851
11638
  }
10852
- if (!_optionalChain([options, 'optionalAccess', _236 => _236.skipUserValidation])) {
10853
- await this.userService.validateUsersOrThrow(schema, dataWithDefaults);
11639
+ if (!_optionalChain([options, 'optionalAccess', _240 => _240.skipUserValidation])) {
11640
+ await this.userService.validateUsersOrThrow(schema, normalizedData);
10854
11641
  }
10855
11642
  }
10856
- const completionStatus = _chunkU4AB53AMjs.computeRecordStatus.call(void 0, schema, dataWithDefaults);
10857
- const label = await computeLabel(schema, dataWithDefaults, this.labelResolver);
11643
+ const completionStatus = _chunkU4AB53AMjs.computeRecordStatus.call(void 0, schema, normalizedData);
11644
+ const label = await computeLabel(schema, normalizedData, this.labelResolver);
10858
11645
  const record = await this.adapter.objectRecords.create({
10859
11646
  objectId,
10860
- data: dataWithDefaults,
11647
+ data: normalizedData,
10861
11648
  label,
10862
11649
  completionStatus,
10863
- metadata: _optionalChain([options, 'optionalAccess', _237 => _237.metadata]),
11650
+ metadata: _optionalChain([options, 'optionalAccess', _241 => _241.metadata]),
10864
11651
  createdBy: this.userId
10865
11652
  });
10866
- if (!_optionalChain([options, 'optionalAccess', _238 => _238.skipHooks])) {
11653
+ for (const [attrName, value] of Object.entries(dataWithDefaults)) {
11654
+ const attr = schema.attributes.find((a) => a.name === attrName);
11655
+ if (_optionalChain([attr, 'optionalAccess', _242 => _242.type]) === "relation" && attr.properties) {
11656
+ await this.relationPropertiesService.syncRelationProperties(
11657
+ schema,
11658
+ record.id,
11659
+ attrName,
11660
+ value,
11661
+ this.adapter
11662
+ );
11663
+ }
11664
+ }
11665
+ if (!_optionalChain([options, 'optionalAccess', _243 => _243.skipHooks])) {
10867
11666
  const afterCtx = {
10868
11667
  ...hookCtx,
10869
11668
  recordId: record.id,
@@ -10881,7 +11680,7 @@ var RecordService = class extends BaseService {
10881
11680
  objectId: schema.id,
10882
11681
  recordId: record.id,
10883
11682
  recordLabel: record.label,
10884
- metadata: _optionalChain([options, 'optionalAccess', _239 => _239.hookMetadata])
11683
+ metadata: _optionalChain([options, 'optionalAccess', _244 => _244.hookMetadata])
10885
11684
  }).catch((err) => {
10886
11685
  console.error(
10887
11686
  "Audit log failed (record.created):",
@@ -10907,7 +11706,7 @@ var RecordService = class extends BaseService {
10907
11706
  return null;
10908
11707
  }
10909
11708
  const schema = await this.schemaService.getObjectSchema(record.objectId);
10910
- if (!_optionalChain([options, 'optionalAccess', _240 => _240.skipPolicyCheck])) {
11709
+ if (!_optionalChain([options, 'optionalAccess', _245 => _245.skipPolicyCheck])) {
10911
11710
  const policy = getPolicy(this.policyRegistry, this.userId, schema.name);
10912
11711
  if (policy) {
10913
11712
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
@@ -10917,10 +11716,10 @@ var RecordService = class extends BaseService {
10917
11716
  }
10918
11717
  }
10919
11718
  let enrichedRecord = record;
10920
- if (!_optionalChain([options, 'optionalAccess', _241 => _241.skipFormulas])) {
11719
+ if (!_optionalChain([options, 'optionalAccess', _246 => _246.skipFormulas])) {
10921
11720
  enrichedRecord = enrichWithFormulas(record, schema);
10922
11721
  }
10923
- if (_optionalChain([options, 'optionalAccess', _242 => _242.includeSchema])) {
11722
+ if (_optionalChain([options, 'optionalAccess', _247 => _247.includeSchema])) {
10924
11723
  const recordWithSchema = enrichedRecord;
10925
11724
  recordWithSchema.schema = schema;
10926
11725
  return recordWithSchema;
@@ -10982,9 +11781,9 @@ var RecordService = class extends BaseService {
10982
11781
  existing,
10983
11782
  mergedData,
10984
11783
  changedAttributes,
10985
- _optionalChain([options, 'optionalAccess', _243 => _243.hookMetadata])
11784
+ _optionalChain([options, 'optionalAccess', _248 => _248.hookMetadata])
10986
11785
  );
10987
- if (!_optionalChain([options, 'optionalAccess', _244 => _244.skipHooks])) {
11786
+ if (!_optionalChain([options, 'optionalAccess', _249 => _249.skipHooks])) {
10988
11787
  await this.hookRegistry.execute("beforeUpdate", schema.name, hookCtx);
10989
11788
  }
10990
11789
  const hookModifiedValues = {};
@@ -10993,36 +11792,35 @@ var RecordService = class extends BaseService {
10993
11792
  hookModifiedValues[key] = hookCtx.newValues[key];
10994
11793
  }
10995
11794
  }
10996
- if (_optionalChain([options, 'optionalAccess', _245 => _245.validate]) !== false) {
10997
- if (_optionalChain([options, 'optionalAccess', _246 => _246.partial])) {
10998
- _chunkU4AB53AMjs.validateDraftOrThrow.call(void 0, schema, mergedData);
11795
+ const dataToUpdate = { ...data, ...hookModifiedValues };
11796
+ const normalizedUpdate = this.relationPropertiesService.normalizeRelationValuesForStorage(
11797
+ schema,
11798
+ dataToUpdate
11799
+ );
11800
+ const normalizedMergedData = { ...existing.values, ...normalizedUpdate };
11801
+ if (_optionalChain([options, 'optionalAccess', _250 => _250.validate]) !== false) {
11802
+ if (_optionalChain([options, 'optionalAccess', _251 => _251.partial])) {
11803
+ _chunkU4AB53AMjs.validateDraftOrThrow.call(void 0, schema, normalizedMergedData);
10999
11804
  } else {
11000
- _chunkU4AB53AMjs.validateObjectOrThrow.call(void 0, schema, mergedData);
11805
+ _chunkU4AB53AMjs.validateObjectOrThrow.call(void 0, schema, normalizedMergedData);
11001
11806
  }
11002
- if (!_optionalChain([options, 'optionalAccess', _247 => _247.skipRelationValidation])) {
11003
- await this.relationService.validateRelationsOrThrow(schema, {
11004
- ...data,
11005
- ...hookModifiedValues
11006
- });
11807
+ if (!_optionalChain([options, 'optionalAccess', _252 => _252.skipRelationValidation])) {
11808
+ await this.relationService.validateRelationsOrThrow(schema, normalizedUpdate);
11007
11809
  }
11008
- if (!_optionalChain([options, 'optionalAccess', _248 => _248.skipUserValidation])) {
11009
- await this.userService.validateUsersOrThrow(schema, {
11010
- ...data,
11011
- ...hookModifiedValues
11012
- });
11810
+ if (!_optionalChain([options, 'optionalAccess', _253 => _253.skipUserValidation])) {
11811
+ await this.userService.validateUsersOrThrow(schema, normalizedUpdate);
11013
11812
  }
11014
11813
  }
11015
- const completionStatus = _chunkU4AB53AMjs.computeRecordStatus.call(void 0, schema, mergedData);
11016
- const label = await computeLabel(schema, mergedData, this.labelResolver);
11814
+ const completionStatus = _chunkU4AB53AMjs.computeRecordStatus.call(void 0, schema, normalizedMergedData);
11815
+ const label = await computeLabel(schema, normalizedMergedData, this.labelResolver);
11017
11816
  const updatePayload = {
11018
- ...data,
11019
- ...hookModifiedValues,
11817
+ ...normalizedUpdate,
11020
11818
  __completionStatus: completionStatus,
11021
11819
  __label: label,
11022
11820
  __lastUpdatedBy: this.userId,
11023
11821
  __expectedUpdatedAt: existing.updatedAt instanceof Date ? existing.updatedAt.toISOString() : existing.updatedAt
11024
11822
  };
11025
- if (_optionalChain([options, 'optionalAccess', _249 => _249.metadata]) !== void 0) {
11823
+ if (_optionalChain([options, 'optionalAccess', _254 => _254.metadata]) !== void 0) {
11026
11824
  const existingMetadata = _nullishCoalesce(existing.metadata, () => ( {}));
11027
11825
  const mergedMetadata = { ...existingMetadata, ...options.metadata };
11028
11826
  const cleanedMetadata = Object.fromEntries(
@@ -11032,7 +11830,19 @@ var RecordService = class extends BaseService {
11032
11830
  }
11033
11831
  const updated = await this.adapter.objectRecords.update(recordId, updatePayload);
11034
11832
  await this.invalidateRecordCaches(recordId, existing.objectId);
11035
- if (!_optionalChain([options, 'optionalAccess', _250 => _250.skipHooks])) {
11833
+ for (const [attrName, value] of Object.entries(dataToUpdate)) {
11834
+ const attr = schema.attributes.find((a) => a.name === attrName);
11835
+ if (_optionalChain([attr, 'optionalAccess', _255 => _255.type]) === "relation" && attr.properties) {
11836
+ await this.relationPropertiesService.syncRelationProperties(
11837
+ schema,
11838
+ recordId,
11839
+ attrName,
11840
+ value,
11841
+ this.adapter
11842
+ );
11843
+ }
11844
+ }
11845
+ if (!_optionalChain([options, 'optionalAccess', _256 => _256.skipHooks])) {
11036
11846
  const afterCtx = {
11037
11847
  ...hookCtx,
11038
11848
  record: updated
@@ -11047,7 +11857,7 @@ var RecordService = class extends BaseService {
11047
11857
  if (this.auditService && this.userId && allChangedAttributes.length > 0) {
11048
11858
  const changes = allChangedAttributes.map((attr) => ({
11049
11859
  field: attr,
11050
- oldValue: _optionalChain([hookCtx, 'access', _251 => _251.oldValues, 'optionalAccess', _252 => _252[attr]]),
11860
+ oldValue: _optionalChain([hookCtx, 'access', _257 => _257.oldValues, 'optionalAccess', _258 => _258[attr]]),
11051
11861
  newValue: hookCtx.newValues[attr]
11052
11862
  }));
11053
11863
  this.auditService.logRecordAction({
@@ -11058,7 +11868,7 @@ var RecordService = class extends BaseService {
11058
11868
  recordId: updated.id,
11059
11869
  recordLabel: updated.label,
11060
11870
  changes,
11061
- metadata: _optionalChain([options, 'optionalAccess', _253 => _253.hookMetadata])
11871
+ metadata: _optionalChain([options, 'optionalAccess', _259 => _259.hookMetadata])
11062
11872
  }).catch((err) => {
11063
11873
  console.error(
11064
11874
  "Audit log failed (record.updated):",
@@ -11093,22 +11903,22 @@ var RecordService = class extends BaseService {
11093
11903
  const ctx = buildPolicyContext(schema.name, this.userId, this.tenantId);
11094
11904
  checkRecordDeleteOrThrow(policy, record, ctx);
11095
11905
  }
11096
- if (_optionalChain([options, 'optionalAccess', _254 => _254.checkSystem]) && schema.system) {
11906
+ if (_optionalChain([options, 'optionalAccess', _260 => _260.checkSystem]) && schema.system) {
11097
11907
  throw new ProtectedResourceError("object", schema.name, "delete");
11098
11908
  }
11099
- if (!_optionalChain([options, 'optionalAccess', _255 => _255.skipReferenceCheck])) {
11909
+ if (!_optionalChain([options, 'optionalAccess', _261 => _261.skipReferenceCheck])) {
11100
11910
  const references = await this.adapter.objectRecords.countRecordsReferencingId(recordId);
11101
11911
  if (references.length > 0) {
11102
11912
  throw new RecordReferencedError(recordId, references);
11103
11913
  }
11104
11914
  }
11105
- const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _256 => _256.hookMetadata]));
11106
- if (!_optionalChain([options, 'optionalAccess', _257 => _257.skipHooks])) {
11915
+ const hookCtx = createContextForDelete(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _262 => _262.hookMetadata]));
11916
+ if (!_optionalChain([options, 'optionalAccess', _263 => _263.skipHooks])) {
11107
11917
  await this.hookRegistry.execute("beforeDelete", schema.name, hookCtx);
11108
11918
  }
11109
11919
  await this.adapter.objectRecords.delete(recordId);
11110
11920
  await this.invalidateRecordCaches(recordId, record.objectId);
11111
- if (!_optionalChain([options, 'optionalAccess', _258 => _258.skipHooks])) {
11921
+ if (!_optionalChain([options, 'optionalAccess', _264 => _264.skipHooks])) {
11112
11922
  await this.hookRegistry.execute("afterDelete", schema.name, hookCtx);
11113
11923
  }
11114
11924
  await recalculateParentRollups(record, schema, this.rollupContext);
@@ -11120,7 +11930,7 @@ var RecordService = class extends BaseService {
11120
11930
  objectId: schema.id,
11121
11931
  recordId: record.id,
11122
11932
  recordLabel: record.label,
11123
- metadata: _optionalChain([options, 'optionalAccess', _259 => _259.hookMetadata])
11933
+ metadata: _optionalChain([options, 'optionalAccess', _265 => _265.hookMetadata])
11124
11934
  }).catch((err) => {
11125
11935
  console.error(
11126
11936
  "Audit log failed (record.deleted):",
@@ -11163,13 +11973,13 @@ var RecordService = class extends BaseService {
11163
11973
  this.tenantId
11164
11974
  );
11165
11975
  await checkPermission(this.permissionService, this.userId, schema.name, "update");
11166
- const hookCtx = createContextForRestore(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _260 => _260.hookMetadata]));
11167
- if (!_optionalChain([options, 'optionalAccess', _261 => _261.skipHooks])) {
11976
+ const hookCtx = createContextForRestore(schema, this.tenantId, record, _optionalChain([options, 'optionalAccess', _266 => _266.hookMetadata]));
11977
+ if (!_optionalChain([options, 'optionalAccess', _267 => _267.skipHooks])) {
11168
11978
  await this.hookRegistry.execute("beforeRestore", schema.name, hookCtx);
11169
11979
  }
11170
11980
  const restored = await this.adapter.objectRecords.restore(recordId);
11171
11981
  await this.invalidateRecordCaches(recordId, record.objectId);
11172
- if (!_optionalChain([options, 'optionalAccess', _262 => _262.skipHooks])) {
11982
+ if (!_optionalChain([options, 'optionalAccess', _268 => _268.skipHooks])) {
11173
11983
  const afterCtx = {
11174
11984
  ...hookCtx,
11175
11985
  record: restored
@@ -11184,7 +11994,7 @@ var RecordService = class extends BaseService {
11184
11994
  objectId: schema.id,
11185
11995
  recordId: restored.id,
11186
11996
  recordLabel: restored.label,
11187
- metadata: _optionalChain([options, 'optionalAccess', _263 => _263.hookMetadata])
11997
+ metadata: _optionalChain([options, 'optionalAccess', _269 => _269.hookMetadata])
11188
11998
  }).catch((err) => {
11189
11999
  console.error(
11190
12000
  "Audit log failed (record.restored):",
@@ -11565,7 +12375,7 @@ var DocumentRendererService = class {
11565
12375
  throw new StorageDownloadNotSupportedError();
11566
12376
  }
11567
12377
  let storagePath = fileId;
11568
- if (_optionalChain([this, 'access', _264 => _264.options, 'optionalAccess', _265 => _265.filesRepository])) {
12378
+ if (_optionalChain([this, 'access', _270 => _270.options, 'optionalAccess', _271 => _271.filesRepository])) {
11569
12379
  const file2 = await this.options.filesRepository.findById(fileId);
11570
12380
  if (!file2) {
11571
12381
  throw new Error(`Template file not found: ${fileId}`);
@@ -11583,8 +12393,8 @@ var DocumentRendererService = class {
11583
12393
  for (const field of fields) {
11584
12394
  const rawValue = getContextValue(context, field.contextPath);
11585
12395
  const attrInfo = await this.getAttributeInfo(field.contextPath, workflow2);
11586
- if (_optionalChain([attrInfo, 'optionalAccess', _266 => _266.attribute])) {
11587
- if (attrInfo.attribute.type === "relation" && rawValue && _optionalChain([this, 'access', _267 => _267.options, 'optionalAccess', _268 => _268.relationService])) {
12396
+ if (_optionalChain([attrInfo, 'optionalAccess', _272 => _272.attribute])) {
12397
+ if (attrInfo.attribute.type === "relation" && rawValue && _optionalChain([this, 'access', _273 => _273.options, 'optionalAccess', _274 => _274.relationService])) {
11588
12398
  const ids = Array.isArray(rawValue) ? rawValue : [rawValue];
11589
12399
  const stringIds = ids.filter((id) => typeof id === "string");
11590
12400
  if (stringIds.length > 0) {
@@ -11605,7 +12415,7 @@ var DocumentRendererService = class {
11605
12415
  resolved.set(field.id, this.formatValueSimple(rawValue, field.fallback));
11606
12416
  }
11607
12417
  }
11608
- if (relationBatch.length > 0 && _optionalChain([this, 'access', _269 => _269.options, 'optionalAccess', _270 => _270.relationService])) {
12418
+ if (relationBatch.length > 0 && _optionalChain([this, 'access', _275 => _275.options, 'optionalAccess', _276 => _276.relationService])) {
11609
12419
  try {
11610
12420
  const batchResult = await this.options.relationService.resolveIdsBatch(
11611
12421
  relationBatch.map((r) => ({ attributeId: r.attributeId, ids: r.ids }))
@@ -11614,12 +12424,12 @@ var DocumentRendererService = class {
11614
12424
  const options = _nullishCoalesce(batchResult[attributeId], () => ( []));
11615
12425
  const labels = options.map((o) => o.label);
11616
12426
  const field = fields.find((f) => f.id === fieldId);
11617
- resolved.set(fieldId, labels.join(", ") || _optionalChain([field, 'optionalAccess', _271 => _271.fallback]) || "");
12427
+ resolved.set(fieldId, labels.join(", ") || _optionalChain([field, 'optionalAccess', _277 => _277.fallback]) || "");
11618
12428
  }
11619
12429
  } catch (e14) {
11620
12430
  for (const { fieldId, ids } of relationBatch) {
11621
12431
  const field = fields.find((f) => f.id === fieldId);
11622
- resolved.set(fieldId, ids.join(", ") || _optionalChain([field, 'optionalAccess', _272 => _272.fallback]) || "");
12432
+ resolved.set(fieldId, ids.join(", ") || _optionalChain([field, 'optionalAccess', _278 => _278.fallback]) || "");
11623
12433
  }
11624
12434
  }
11625
12435
  }
@@ -11630,7 +12440,7 @@ var DocumentRendererService = class {
11630
12440
  * Parses paths like "slots.client.firstName" to find the attribute definition
11631
12441
  */
11632
12442
  async getAttributeInfo(contextPath, workflow2) {
11633
- const schemaService = _optionalChain([this, 'access', _273 => _273.options, 'optionalAccess', _274 => _274.schemaService]);
12443
+ const schemaService = _optionalChain([this, 'access', _279 => _279.options, 'optionalAccess', _280 => _280.schemaService]);
11634
12444
  if (!schemaService) {
11635
12445
  return null;
11636
12446
  }
@@ -11643,7 +12453,7 @@ var DocumentRendererService = class {
11643
12453
  }
11644
12454
  const slotId = parts[1];
11645
12455
  const attributeName = parts[2];
11646
- const slot = _optionalChain([workflow2, 'access', _275 => _275.slots, 'optionalAccess', _276 => _276.find, 'call', _277 => _277((s) => s.id === slotId)]);
12456
+ const slot = _optionalChain([workflow2, 'access', _281 => _281.slots, 'optionalAccess', _282 => _282.find, 'call', _283 => _283((s) => s.id === slotId)]);
11647
12457
  if (!slot) {
11648
12458
  return null;
11649
12459
  }
@@ -11842,7 +12652,7 @@ var DocumentProcessingHook = class extends BaseService {
11842
12652
  const pendingIds = [];
11843
12653
  for (const [nodeId, doc] of Object.entries(context.documents)) {
11844
12654
  const metadata = doc.metadata;
11845
- if (_optionalChain([metadata, 'optionalAccess', _278 => _278.status]) === "pending") {
12655
+ if (_optionalChain([metadata, 'optionalAccess', _284 => _284.status]) === "pending") {
11846
12656
  pendingIds.push(nodeId);
11847
12657
  }
11848
12658
  }
@@ -11893,12 +12703,12 @@ var DocumentProcessingHook = class extends BaseService {
11893
12703
  }
11894
12704
  for (const slotId of targetSlotIds) {
11895
12705
  try {
11896
- const recordId = _optionalChain([context, 'access', _279 => _279.createdRecordIds, 'optionalAccess', _280 => _280[slotId]]);
12706
+ const recordId = _optionalChain([context, 'access', _285 => _285.createdRecordIds, 'optionalAccess', _286 => _286[slotId]]);
11897
12707
  if (!recordId) {
11898
12708
  continue;
11899
12709
  }
11900
- const slotDef = _optionalChain([workflow2, 'access', _281 => _281.slots, 'optionalAccess', _282 => _282.find, 'call', _283 => _283((s) => s.id === slotId)]);
11901
- const objectName = _optionalChain([slotDef, 'optionalAccess', _284 => _284.objectName]);
12710
+ const slotDef = _optionalChain([workflow2, 'access', _287 => _287.slots, 'optionalAccess', _288 => _288.find, 'call', _289 => _289((s) => s.id === slotId)]);
12711
+ const objectName = _optionalChain([slotDef, 'optionalAccess', _290 => _290.objectName]);
11902
12712
  if (!objectName) {
11903
12713
  continue;
11904
12714
  }
@@ -11915,7 +12725,7 @@ var DocumentProcessingHook = class extends BaseService {
11915
12725
  attachedDocumentIds.push(result.document.id);
11916
12726
  const record = await recordService.getRecord(recordId);
11917
12727
  if (record) {
11918
- const attachments = _nullishCoalesce(_optionalChain([record, 'access', _285 => _285.values, 'optionalAccess', _286 => _286.attachments]), () => ( []));
12728
+ const attachments = _nullishCoalesce(_optionalChain([record, 'access', _291 => _291.values, 'optionalAccess', _292 => _292.attachments]), () => ( []));
11919
12729
  await recordService.updateRecord(
11920
12730
  recordId,
11921
12731
  { attachments: [...attachments, result.document.id] },
@@ -12181,7 +12991,7 @@ var WorkflowAccessGrantService = class extends BaseService {
12181
12991
  * Check if a specific token has been revoked.
12182
12992
  */
12183
12993
  isTokenRevoked(dbGrant, jti) {
12184
- return _nullishCoalesce(_optionalChain([dbGrant, 'access', _287 => _287.revoked_token_jtis, 'optionalAccess', _288 => _288.includes, 'call', _289 => _289(jti)]), () => ( false));
12994
+ return _nullishCoalesce(_optionalChain([dbGrant, 'access', _293 => _293.revoked_token_jtis, 'optionalAccess', _294 => _294.includes, 'call', _295 => _295(jti)]), () => ( false));
12185
12995
  }
12186
12996
  /**
12187
12997
  * Validate access token payload against the grant.
@@ -12233,10 +13043,10 @@ var WorkflowInstanceService = class extends BaseService {
12233
13043
  constructor(adapter, workflowService, options) {
12234
13044
  super(adapter);
12235
13045
  this.workflowService = workflowService;
12236
- this.executorRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _290 => _290.executorRegistry]), () => ( getDefaultExecutorRegistry()));
12237
- this.schemaService = _optionalChain([options, 'optionalAccess', _291 => _291.schemaService]);
12238
- this.recordService = _optionalChain([options, 'optionalAccess', _292 => _292.recordService]);
12239
- this.documentProcessingHook = _optionalChain([options, 'optionalAccess', _293 => _293.documentProcessingHook]);
13046
+ this.executorRegistry = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _296 => _296.executorRegistry]), () => ( getDefaultExecutorRegistry()));
13047
+ this.schemaService = _optionalChain([options, 'optionalAccess', _297 => _297.schemaService]);
13048
+ this.recordService = _optionalChain([options, 'optionalAccess', _298 => _298.recordService]);
13049
+ this.documentProcessingHook = _optionalChain([options, 'optionalAccess', _299 => _299.documentProcessingHook]);
12240
13050
  }
12241
13051
  /**
12242
13052
  * Start a new workflow instance
@@ -12418,7 +13228,7 @@ var WorkflowInstanceService = class extends BaseService {
12418
13228
  if (!this.adapter.workflowInstances) {
12419
13229
  return { instances: [], total: 0 };
12420
13230
  }
12421
- if (_optionalChain([options, 'optionalAccess', _294 => _294.workflowName])) {
13231
+ if (_optionalChain([options, 'optionalAccess', _300 => _300.workflowName])) {
12422
13232
  const allDbInstances = await this.adapter.workflowInstances.findByWorkflowName(
12423
13233
  options.workflowName,
12424
13234
  { status: options.status }
@@ -12432,11 +13242,11 @@ var WorkflowInstanceService = class extends BaseService {
12432
13242
  return { instances: instances2, total: total2 };
12433
13243
  }
12434
13244
  const { instances: dbInstances, total } = await this.adapter.workflowInstances.list({
12435
- limit: _optionalChain([options, 'optionalAccess', _295 => _295.limit]),
12436
- offset: _optionalChain([options, 'optionalAccess', _296 => _296.offset])
13245
+ limit: _optionalChain([options, 'optionalAccess', _301 => _301.limit]),
13246
+ offset: _optionalChain([options, 'optionalAccess', _302 => _302.offset])
12437
13247
  });
12438
13248
  let instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
12439
- if (_optionalChain([options, 'optionalAccess', _297 => _297.status])) {
13249
+ if (_optionalChain([options, 'optionalAccess', _303 => _303.status])) {
12440
13250
  instances = instances.filter((i) => i.status === options.status);
12441
13251
  }
12442
13252
  instances = await this.markExpiredInstances(instances);
@@ -12457,9 +13267,9 @@ var WorkflowInstanceService = class extends BaseService {
12457
13267
  return { instances: [], total: 0 };
12458
13268
  }
12459
13269
  const { instances: dbInstances, total } = await this.adapter.workflowInstances.findByRecordInSlots(objectName, recordId, {
12460
- status: _optionalChain([options, 'optionalAccess', _298 => _298.status]),
12461
- limit: _optionalChain([options, 'optionalAccess', _299 => _299.limit]),
12462
- offset: _optionalChain([options, 'optionalAccess', _300 => _300.offset])
13270
+ status: _optionalChain([options, 'optionalAccess', _304 => _304.status]),
13271
+ limit: _optionalChain([options, 'optionalAccess', _305 => _305.limit]),
13272
+ offset: _optionalChain([options, 'optionalAccess', _306 => _306.offset])
12463
13273
  });
12464
13274
  const instances = dbInstances.map((db) => this.convertDBInstanceToInstance(db));
12465
13275
  return { instances, total };
@@ -12525,7 +13335,7 @@ var WorkflowInstanceService = class extends BaseService {
12525
13335
  try {
12526
13336
  const schemas = await Promise.all(
12527
13337
  current.workflowSnapshot.slots.map(
12528
- (slot) => _optionalChain([this, 'access', _301 => _301.schemaService, 'optionalAccess', _302 => _302.getObjectSchemaByName, 'call', _303 => _303(slot.objectName)])
13338
+ (slot) => _optionalChain([this, 'access', _307 => _307.schemaService, 'optionalAccess', _308 => _308.getObjectSchemaByName, 'call', _309 => _309(slot.objectName)])
12529
13339
  )
12530
13340
  );
12531
13341
  objectDefinitions = schemas.filter(
@@ -12790,8 +13600,8 @@ var WorkflowInstanceService = class extends BaseService {
12790
13600
  */
12791
13601
  async snapshotRecord(recordId) {
12792
13602
  try {
12793
- const record = await _optionalChain([this, 'access', _304 => _304.recordService, 'optionalAccess', _305 => _305.getRecord, 'call', _306 => _306(recordId, { skipPolicyCheck: true })]);
12794
- return _optionalChain([record, 'optionalAccess', _307 => _307.values]);
13603
+ const record = await _optionalChain([this, 'access', _310 => _310.recordService, 'optionalAccess', _311 => _311.getRecord, 'call', _312 => _312(recordId, { skipPolicyCheck: true })]);
13604
+ return _optionalChain([record, 'optionalAccess', _313 => _313.values]);
12795
13605
  } catch (e18) {
12796
13606
  return void 0;
12797
13607
  }
@@ -12810,13 +13620,13 @@ var WorkflowInstanceService = class extends BaseService {
12810
13620
  for (const op of [...operations].reverse()) {
12811
13621
  try {
12812
13622
  if (op.operation === "create") {
12813
- await _optionalChain([this, 'access', _308 => _308.recordService, 'optionalAccess', _309 => _309.deleteRecord, 'call', _310 => _310(op.recordId, {
13623
+ await _optionalChain([this, 'access', _314 => _314.recordService, 'optionalAccess', _315 => _315.deleteRecord, 'call', _316 => _316(op.recordId, {
12814
13624
  skipHooks: true,
12815
13625
  skipReferenceCheck: true
12816
13626
  })]);
12817
13627
  rolledBack.push(op.slotId);
12818
13628
  } else if (op.operation === "update" && op.previousData) {
12819
- await _optionalChain([this, 'access', _311 => _311.recordService, 'optionalAccess', _312 => _312.updateRecord, 'call', _313 => _313(op.recordId, op.previousData, {
13629
+ await _optionalChain([this, 'access', _317 => _317.recordService, 'optionalAccess', _318 => _318.updateRecord, 'call', _319 => _319(op.recordId, op.previousData, {
12820
13630
  partial: false
12821
13631
  })]);
12822
13632
  rolledBack.push(op.slotId);
@@ -12940,7 +13750,7 @@ var WorkflowInstanceService = class extends BaseService {
12940
13750
  if (!this.adapter.workflowInstances) {
12941
13751
  return;
12942
13752
  }
12943
- const currentVersion = _nullishCoalesce(_optionalChain([instance, 'access', _314 => _314.context, 'access', _315 => _315.variables, 'optionalAccess', _316 => _316.__version]), () => ( 0));
13753
+ const currentVersion = _nullishCoalesce(_optionalChain([instance, 'access', _320 => _320.context, 'access', _321 => _321.variables, 'optionalAccess', _322 => _322.__version]), () => ( 0));
12944
13754
  const nextVersion = currentVersion + 1;
12945
13755
  const instanceWithVersion = {
12946
13756
  ...instance,
@@ -13221,7 +14031,7 @@ var WorkflowRelationService = class extends BaseService {
13221
14031
  if (attr.type !== "relation") continue;
13222
14032
  for (const slot of slots) {
13223
14033
  const slotData = context.slots[slot.id];
13224
- const slotRecordId = _optionalChain([slotData, 'optionalAccess', _317 => _317.id]);
14034
+ const slotRecordId = _optionalChain([slotData, 'optionalAccess', _323 => _323.id]);
13225
14035
  if (!slotRecordId) continue;
13226
14036
  const targetsSlotObject = attr.targets.some(
13227
14037
  (t) => t.object === slot.objectName
@@ -13289,7 +14099,7 @@ var WorkflowService = class extends BaseService {
13289
14099
  if (Array.isArray(options)) {
13290
14100
  this.systemWorkflows = new Map(options.map((w) => [w.name, w]));
13291
14101
  } else {
13292
- this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _318 => _318.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
14102
+ this.systemWorkflows = new Map((_nullishCoalesce(_optionalChain([options, 'optionalAccess', _324 => _324.systemWorkflows]), () => ( []))).map((w) => [w.name, w]));
13293
14103
  }
13294
14104
  }
13295
14105
  // ============================================================================
@@ -13587,7 +14397,7 @@ var WorkflowService = class extends BaseService {
13587
14397
  var UserProfileService = class extends BaseService {
13588
14398
  constructor(adapter, options) {
13589
14399
  super(adapter);
13590
- this.auditService = _optionalChain([options, 'optionalAccess', _319 => _319.auditService]);
14400
+ this.auditService = _optionalChain([options, 'optionalAccess', _325 => _325.auditService]);
13591
14401
  }
13592
14402
  // ============================================================================
13593
14403
  // CACHE MANAGEMENT
@@ -13750,7 +14560,7 @@ var UserProfileService = class extends BaseService {
13750
14560
  */
13751
14561
  async deleteProfile(profileId, options) {
13752
14562
  const profile = await this.getProfileOrThrow(profileId);
13753
- if (_optionalChain([options, 'optionalAccess', _320 => _320.checkAdmin])) {
14563
+ if (_optionalChain([options, 'optionalAccess', _326 => _326.checkAdmin])) {
13754
14564
  if (profile.role === "admin") {
13755
14565
  const adminCount = await this.adapter.userProfiles.countByRole("admin");
13756
14566
  if (adminCount <= 1) {
@@ -13825,7 +14635,7 @@ var UserProfileService = class extends BaseService {
13825
14635
  */
13826
14636
  async hasRole(profileId, role) {
13827
14637
  const profile = await this.getProfile(profileId);
13828
- return _optionalChain([profile, 'optionalAccess', _321 => _321.role]) === role;
14638
+ return _optionalChain([profile, 'optionalAccess', _327 => _327.role]) === role;
13829
14639
  }
13830
14640
  /**
13831
14641
  * Check if user is admin
@@ -14259,7 +15069,7 @@ var DocumentTemplateService = class extends BaseService {
14259
15069
  * Includes both system templates and tenant-specific templates.
14260
15070
  */
14261
15071
  async listTemplates(options) {
14262
- if (_optionalChain([options, 'optionalAccess', _322 => _322.systemOnly])) {
15072
+ if (_optionalChain([options, 'optionalAccess', _328 => _328.systemOnly])) {
14263
15073
  return SYSTEM_TEMPLATES;
14264
15074
  }
14265
15075
  const templates = [...SYSTEM_TEMPLATES];
@@ -14342,8 +15152,8 @@ var DocumentTemplateService = class extends BaseService {
14342
15152
  var DocumentService = class extends BaseService {
14343
15153
  constructor(adapter, options) {
14344
15154
  super(adapter);
14345
- this.templateService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _323 => _323.templateService]), () => ( new DocumentTemplateService(adapter)));
14346
- this.fileService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _324 => _324.fileService]), () => ( null));
15155
+ this.templateService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _329 => _329.templateService]), () => ( new DocumentTemplateService(adapter)));
15156
+ this.fileService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _330 => _330.fileService]), () => ( null));
14347
15157
  }
14348
15158
  // ============================================================================
14349
15159
  // CREATE
@@ -14594,7 +15404,7 @@ var DocumentService = class extends BaseService {
14594
15404
  */
14595
15405
  async isComplete(documentId) {
14596
15406
  const document2 = await this.getDocument(documentId);
14597
- return _optionalChain([document2, 'optionalAccess', _325 => _325.status]) !== "draft";
15407
+ return _optionalChain([document2, 'optionalAccess', _331 => _331.status]) !== "draft";
14598
15408
  }
14599
15409
  /**
14600
15410
  * Get document with its template and slots.
@@ -14852,7 +15662,7 @@ var DocumentProcessingService = class extends BaseService {
14852
15662
  type: "signature",
14853
15663
  provider: this.config.signatureAdapter.name,
14854
15664
  input: { signers, ...options },
14855
- expiresAt: _optionalChain([options, 'optionalAccess', _326 => _326.expiresAt])
15665
+ expiresAt: _optionalChain([options, 'optionalAccess', _332 => _332.expiresAt])
14856
15666
  });
14857
15667
  return job;
14858
15668
  }
@@ -15009,7 +15819,7 @@ var DocumentProcessingService = class extends BaseService {
15009
15819
  }
15010
15820
  const document2 = await this.documentService.getDocumentOrThrow(documentId);
15011
15821
  const template = await this.templateService.getTemplateOrThrow(document2.templateId);
15012
- if (!_optionalChain([template, 'access', _327 => _327.autoProcessing, 'optionalAccess', _328 => _328.identityVerification, 'optionalAccess', _329 => _329.enabled])) {
15822
+ if (!_optionalChain([template, 'access', _333 => _333.autoProcessing, 'optionalAccess', _334 => _334.identityVerification, 'optionalAccess', _335 => _335.enabled])) {
15013
15823
  throw new Error("Identity verification is not enabled for this document type");
15014
15824
  }
15015
15825
  const job = await this.adapter.documentJobs.create({
@@ -15095,13 +15905,13 @@ var DocumentProcessingService = class extends BaseService {
15095
15905
  const template = await this.templateService.getTemplateOrThrow(document2.templateId);
15096
15906
  const slots = await this.documentService.getSlots(documentId);
15097
15907
  const jobs = [];
15098
- if (_optionalChain([template, 'access', _330 => _330.autoProcessing, 'optionalAccess', _331 => _331.ocr, 'optionalAccess', _332 => _332.enabled]) && this.config.ocrAdapter) {
15908
+ if (_optionalChain([template, 'access', _336 => _336.autoProcessing, 'optionalAccess', _337 => _337.ocr, 'optionalAccess', _338 => _338.enabled]) && this.config.ocrAdapter) {
15099
15909
  for (const slot of slots) {
15100
15910
  const job = await this.processOcr(documentId, slot.slotName);
15101
15911
  jobs.push(job);
15102
15912
  }
15103
15913
  }
15104
- if (_optionalChain([template, 'access', _333 => _333.autoProcessing, 'optionalAccess', _334 => _334.identityVerification, 'optionalAccess', _335 => _335.enabled]) && this.config.identityAdapter) {
15914
+ if (_optionalChain([template, 'access', _339 => _339.autoProcessing, 'optionalAccess', _340 => _340.identityVerification, 'optionalAccess', _341 => _341.enabled]) && this.config.identityAdapter) {
15105
15915
  const job = await this.verifyIdentity(documentId);
15106
15916
  jobs.push(job);
15107
15917
  }
@@ -15172,15 +15982,15 @@ var DocumentProcessingService = class extends BaseService {
15172
15982
  return {
15173
15983
  ocr: {
15174
15984
  available: !!this.config.ocrAdapter,
15175
- provider: _optionalChain([this, 'access', _336 => _336.config, 'access', _337 => _337.ocrAdapter, 'optionalAccess', _338 => _338.name])
15985
+ provider: _optionalChain([this, 'access', _342 => _342.config, 'access', _343 => _343.ocrAdapter, 'optionalAccess', _344 => _344.name])
15176
15986
  },
15177
15987
  signature: {
15178
15988
  available: !!this.config.signatureAdapter,
15179
- provider: _optionalChain([this, 'access', _339 => _339.config, 'access', _340 => _340.signatureAdapter, 'optionalAccess', _341 => _341.name])
15989
+ provider: _optionalChain([this, 'access', _345 => _345.config, 'access', _346 => _346.signatureAdapter, 'optionalAccess', _347 => _347.name])
15180
15990
  },
15181
15991
  identityVerification: {
15182
15992
  available: !!this.config.identityAdapter,
15183
- provider: _optionalChain([this, 'access', _342 => _342.config, 'access', _343 => _343.identityAdapter, 'optionalAccess', _344 => _344.name])
15993
+ provider: _optionalChain([this, 'access', _348 => _348.config, 'access', _349 => _349.identityAdapter, 'optionalAccess', _350 => _350.name])
15184
15994
  }
15185
15995
  };
15186
15996
  }
@@ -15190,7 +16000,7 @@ var DocumentProcessingService = class extends BaseService {
15190
16000
  var FileService = class extends BaseService {
15191
16001
  constructor(adapter, options) {
15192
16002
  super(adapter);
15193
- this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _345 => _345.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
16003
+ this.auditService = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _351 => _351.auditService]), () => ( (adapter.audit ? new AuditService(adapter) : void 0)));
15194
16004
  }
15195
16005
  // ============================================================================
15196
16006
  // UPLOAD (requires StorageAdapter)
@@ -15329,7 +16139,7 @@ var FileService = class extends BaseService {
15329
16139
  */
15330
16140
  async getFile(fileId) {
15331
16141
  const file2 = await this.adapter.files.findById(fileId);
15332
- if (_optionalChain([file2, 'optionalAccess', _346 => _346.deletedAt])) {
16142
+ if (_optionalChain([file2, 'optionalAccess', _352 => _352.deletedAt])) {
15333
16143
  return null;
15334
16144
  }
15335
16145
  return file2;
@@ -15391,12 +16201,12 @@ var FileService = class extends BaseService {
15391
16201
  */
15392
16202
  async deleteFile(fileId, options) {
15393
16203
  const file2 = await this.getFileOrThrow(fileId);
15394
- if (_optionalChain([options, 'optionalAccess', _347 => _347.checkOwnership]) && options.userId) {
16204
+ if (_optionalChain([options, 'optionalAccess', _353 => _353.checkOwnership]) && options.userId) {
15395
16205
  if (file2.uploadedBy !== options.userId) {
15396
16206
  throw new Error("You can only delete files you uploaded");
15397
16207
  }
15398
16208
  }
15399
- if (_optionalChain([options, 'optionalAccess', _348 => _348.hard])) {
16209
+ if (_optionalChain([options, 'optionalAccess', _354 => _354.hard])) {
15400
16210
  await this.adapter.files.hardDelete(fileId);
15401
16211
  } else {
15402
16212
  await this.adapter.files.delete(fileId);
@@ -15427,7 +16237,7 @@ var FileService = class extends BaseService {
15427
16237
  }
15428
16238
  const file2 = await this.getFileOrThrow(fileId);
15429
16239
  await this.adapter.storage.delete(file2.storagePath);
15430
- if (_optionalChain([options, 'optionalAccess', _349 => _349.hard])) {
16240
+ if (_optionalChain([options, 'optionalAccess', _355 => _355.hard])) {
15431
16241
  await this.adapter.files.hardDelete(fileId);
15432
16242
  } else {
15433
16243
  await this.adapter.files.delete(fileId);
@@ -15453,15 +16263,15 @@ var FileService = class extends BaseService {
15453
16263
  const fileResults = await Promise.all(fileIds.map((id) => this.getFile(id)));
15454
16264
  const files = fileResults.filter((f) => f !== null);
15455
16265
  if (files.length === 0) return;
15456
- if (_optionalChain([options, 'optionalAccess', _350 => _350.deleteFromStorage]) && this.adapter.storage) {
16266
+ if (_optionalChain([options, 'optionalAccess', _356 => _356.deleteFromStorage]) && this.adapter.storage) {
15457
16267
  const BATCH_SIZE = 10;
15458
16268
  for (let i = 0; i < files.length; i += BATCH_SIZE) {
15459
16269
  const batch = files.slice(i, i + BATCH_SIZE);
15460
- await Promise.all(batch.map((file2) => _optionalChain([this, 'access', _351 => _351.adapter, 'access', _352 => _352.storage, 'optionalAccess', _353 => _353.delete, 'call', _354 => _354(file2.storagePath)])));
16270
+ await Promise.all(batch.map((file2) => _optionalChain([this, 'access', _357 => _357.adapter, 'access', _358 => _358.storage, 'optionalAccess', _359 => _359.delete, 'call', _360 => _360(file2.storagePath)])));
15461
16271
  }
15462
16272
  }
15463
16273
  const idsToDelete = files.map((f) => f.id);
15464
- if (_optionalChain([options, 'optionalAccess', _355 => _355.hard])) {
16274
+ if (_optionalChain([options, 'optionalAccess', _361 => _361.hard])) {
15465
16275
  await Promise.all(idsToDelete.map((id) => this.adapter.files.hardDelete(id)));
15466
16276
  } else {
15467
16277
  await Promise.all(idsToDelete.map((id) => this.adapter.files.delete(id)));
@@ -15469,12 +16279,12 @@ var FileService = class extends BaseService {
15469
16279
  if (this.auditService && this.userId) {
15470
16280
  await Promise.all(
15471
16281
  files.map(
15472
- (file2) => _optionalChain([this, 'access', _356 => _356.auditService, 'optionalAccess', _357 => _357.logFileAction, 'call', _358 => _358({
16282
+ (file2) => _optionalChain([this, 'access', _362 => _362.auditService, 'optionalAccess', _363 => _363.logFileAction, 'call', _364 => _364({
15473
16283
  action: "file.deleted",
15474
16284
  actorId: _nullishCoalesce(this.userId, () => ( "")),
15475
16285
  fileId: file2.id,
15476
16286
  fileName: file2.name,
15477
- metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _359 => _359.deleteFromStorage]), () => ( false)) }
16287
+ metadata: { deletedFromStorage: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _365 => _365.deleteFromStorage]), () => ( false)) }
15478
16288
  })])
15479
16289
  )
15480
16290
  );
@@ -15552,7 +16362,7 @@ var FileService = class extends BaseService {
15552
16362
  if (!file2) {
15553
16363
  return false;
15554
16364
  }
15555
- if (_optionalChain([options, 'optionalAccess', _360 => _360.isAdmin])) {
16365
+ if (_optionalChain([options, 'optionalAccess', _366 => _366.isAdmin])) {
15556
16366
  return true;
15557
16367
  }
15558
16368
  if (file2.visibility === "public") {
@@ -15562,7 +16372,7 @@ var FileService = class extends BaseService {
15562
16372
  return true;
15563
16373
  }
15564
16374
  if (file2.visibility === "restricted") {
15565
- return _nullishCoalesce(_optionalChain([file2, 'access', _361 => _361.allowedUsers, 'optionalAccess', _362 => _362.includes, 'call', _363 => _363(userId)]), () => ( false));
16375
+ return _nullishCoalesce(_optionalChain([file2, 'access', _367 => _367.allowedUsers, 'optionalAccess', _368 => _368.includes, 'call', _369 => _369(userId)]), () => ( false));
15566
16376
  }
15567
16377
  return false;
15568
16378
  }
@@ -15657,7 +16467,7 @@ function withTimeout(promise, ms, label) {
15657
16467
  var GeocodingService = class {
15658
16468
  constructor(adapter, options) {
15659
16469
  this.adapter = adapter;
15660
- this.timeoutMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _364 => _364.timeoutMs]), () => ( GEOCODING_TIMEOUT_MS));
16470
+ this.timeoutMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _370 => _370.timeoutMs]), () => ( GEOCODING_TIMEOUT_MS));
15661
16471
  }
15662
16472
  /**
15663
16473
  * Search for address suggestions as the user types
@@ -15741,10 +16551,10 @@ var GlobalSearchService = class extends BaseService {
15741
16551
  */
15742
16552
  async executeSearch(query, options) {
15743
16553
  return await this.adapter.objectRecords.globalSearch(query, {
15744
- limit: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _365 => _365.limit]), () => ( 20)),
15745
- offset: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _366 => _366.offset]), () => ( 0)),
15746
- objectNames: _optionalChain([options, 'optionalAccess', _367 => _367.objectNames]),
15747
- includeObjectInfo: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _368 => _368.includeObjectInfo]), () => ( true))
16554
+ limit: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _371 => _371.limit]), () => ( 20)),
16555
+ offset: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _372 => _372.offset]), () => ( 0)),
16556
+ objectNames: _optionalChain([options, 'optionalAccess', _373 => _373.objectNames]),
16557
+ includeObjectInfo: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _374 => _374.includeObjectInfo]), () => ( true))
15748
16558
  });
15749
16559
  }
15750
16560
  /**
@@ -15755,7 +16565,7 @@ var GlobalSearchService = class extends BaseService {
15755
16565
  * @returns Results grouped by object name
15756
16566
  */
15757
16567
  async searchGrouped(query, options) {
15758
- const limitPerGroup = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _369 => _369.limitPerGroup]), () => ( 5));
16568
+ const limitPerGroup = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _375 => _375.limitPerGroup]), () => ( 5));
15759
16569
  const estimatedGroupCount = 10;
15760
16570
  const fetchLimit = Math.min(limitPerGroup * estimatedGroupCount, 100);
15761
16571
  const { results, total } = await this.search(query, {
@@ -15797,7 +16607,7 @@ var PermissionService = class extends BaseService {
15797
16607
  }
15798
16608
  this.permissionsRepo = adapter.permissions;
15799
16609
  this.permissionCache = _nullishCoalesce(adapter.cache, () => ( new NoopCacheAdapter()));
15800
- this.auditService = _optionalChain([options, 'optionalAccess', _370 => _370.auditService]);
16610
+ this.auditService = _optionalChain([options, 'optionalAccess', _376 => _376.auditService]);
15801
16611
  }
15802
16612
  // ============================================================================
15803
16613
  // PERMISSION CHECKS
@@ -15816,11 +16626,11 @@ var PermissionService = class extends BaseService {
15816
16626
  return true;
15817
16627
  }
15818
16628
  const wildcardPerms = permissions.objectPermissions["*"];
15819
- if (_optionalChain([wildcardPerms, 'optionalAccess', _371 => _371.includes, 'call', _372 => _372(action)])) {
16629
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _377 => _377.includes, 'call', _378 => _378(action)])) {
15820
16630
  return true;
15821
16631
  }
15822
16632
  const objectPerms = permissions.objectPermissions[objectName];
15823
- return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _373 => _373.includes, 'call', _374 => _374(action)]), () => ( false));
16633
+ return _nullishCoalesce(_optionalChain([objectPerms, 'optionalAccess', _379 => _379.includes, 'call', _380 => _380(action)]), () => ( false));
15824
16634
  }
15825
16635
  /**
15826
16636
  * Check if user can access an object, throw ForbiddenError if not.
@@ -15875,12 +16685,12 @@ var PermissionService = class extends BaseService {
15875
16685
  if (permissions.isAdmin) {
15876
16686
  return true;
15877
16687
  }
15878
- const wildcardPerms = _optionalChain([permissions, 'access', _375 => _375.systemPermissions, 'optionalAccess', _376 => _376["*"]]);
15879
- if (_optionalChain([wildcardPerms, 'optionalAccess', _377 => _377.includes, 'call', _378 => _378(action)])) {
16688
+ const wildcardPerms = _optionalChain([permissions, 'access', _381 => _381.systemPermissions, 'optionalAccess', _382 => _382["*"]]);
16689
+ if (_optionalChain([wildcardPerms, 'optionalAccess', _383 => _383.includes, 'call', _384 => _384(action)])) {
15880
16690
  return true;
15881
16691
  }
15882
- const resourcePerms = _optionalChain([permissions, 'access', _379 => _379.systemPermissions, 'optionalAccess', _380 => _380[resource]]);
15883
- return _nullishCoalesce(_optionalChain([resourcePerms, 'optionalAccess', _381 => _381.includes, 'call', _382 => _382(action)]), () => ( false));
16692
+ const resourcePerms = _optionalChain([permissions, 'access', _385 => _385.systemPermissions, 'optionalAccess', _386 => _386[resource]]);
16693
+ return _nullishCoalesce(_optionalChain([resourcePerms, 'optionalAccess', _387 => _387.includes, 'call', _388 => _388(action)]), () => ( false));
15884
16694
  }
15885
16695
  /**
15886
16696
  * Check if user can access a system resource, throw ForbiddenError if not.
@@ -15909,8 +16719,8 @@ var PermissionService = class extends BaseService {
15909
16719
  if (permissions.isAdmin) {
15910
16720
  return { canRead: true, canCreate: true, canUpdate: true, canDelete: true };
15911
16721
  }
15912
- const wildcardPerms = _nullishCoalesce(_optionalChain([permissions, 'access', _383 => _383.systemPermissions, 'optionalAccess', _384 => _384["*"]]), () => ( []));
15913
- const resourcePerms = _nullishCoalesce(_optionalChain([permissions, 'access', _385 => _385.systemPermissions, 'optionalAccess', _386 => _386[resource]]), () => ( []));
16722
+ const wildcardPerms = _nullishCoalesce(_optionalChain([permissions, 'access', _389 => _389.systemPermissions, 'optionalAccess', _390 => _390["*"]]), () => ( []));
16723
+ const resourcePerms = _nullishCoalesce(_optionalChain([permissions, 'access', _391 => _391.systemPermissions, 'optionalAccess', _392 => _392[resource]]), () => ( []));
15914
16724
  const allPerms = /* @__PURE__ */ new Set([...wildcardPerms, ...resourcePerms]);
15915
16725
  return {
15916
16726
  canRead: allPerms.has("read"),
@@ -16053,7 +16863,7 @@ var PermissionService = class extends BaseService {
16053
16863
  action: "role.updated",
16054
16864
  actorId: this.userId,
16055
16865
  roleId,
16056
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _387 => _387.label]), () => ( roleId)),
16866
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _393 => _393.label]), () => ( roleId)),
16057
16867
  metadata: { permissionsUpdated: true, permissionCount: permissions.length }
16058
16868
  });
16059
16869
  }
@@ -16083,7 +16893,7 @@ var PermissionService = class extends BaseService {
16083
16893
  action: "role.assigned",
16084
16894
  actorId: this.userId,
16085
16895
  roleId,
16086
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _388 => _388.label]), () => ( roleId)),
16896
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _394 => _394.label]), () => ( roleId)),
16087
16897
  targetUserId: userProfileId
16088
16898
  });
16089
16899
  }
@@ -16101,7 +16911,7 @@ var PermissionService = class extends BaseService {
16101
16911
  action: "role.revoked",
16102
16912
  actorId: this.userId,
16103
16913
  roleId,
16104
- roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _389 => _389.label]), () => ( roleId)),
16914
+ roleLabel: _nullishCoalesce(_optionalChain([role, 'optionalAccess', _395 => _395.label]), () => ( roleId)),
16105
16915
  targetUserId: userProfileId
16106
16916
  });
16107
16917
  }
@@ -16577,7 +17387,7 @@ var ViewService = class extends BaseService {
16577
17387
  dbView.objectName,
16578
17388
  dbView.type,
16579
17389
  objectDefinition,
16580
- dbView.type === "detail" ? _nullishCoalesce(_optionalChain([dbView, 'access', _390 => _390.config, 'optionalAccess', _391 => _391.layout]), () => ( "page")) : void 0
17390
+ dbView.type === "detail" ? _nullishCoalesce(_optionalChain([dbView, 'access', _396 => _396.config, 'optionalAccess', _397 => _397.layout]), () => ( "page")) : void 0
16581
17391
  );
16582
17392
  const newConfig = generated.config;
16583
17393
  const updated = await this.adapter.views.update(viewId, { config: newConfig });
@@ -17443,4 +18253,22 @@ var NoopGeocodingAdapter = class {
17443
18253
 
17444
18254
 
17445
18255
 
17446
- exports.IDENTITY_PROPERTIES = IDENTITY_PROPERTIES; exports.BEHAVIOR_PROPERTIES = BEHAVIOR_PROPERTIES; exports.PRESENTATION_PROPERTIES = PRESENTATION_PROPERTIES; exports.isIdentityProperty = isIdentityProperty; exports.isBehaviorProperty = isBehaviorProperty; exports.isPresentationProperty = isPresentationProperty; exports.RELATION_TARGET_ANY = RELATION_TARGET_ANY; exports.isUniversalRelation = isUniversalRelation; exports.RecordReferencedError = RecordReferencedError; exports.AttributeInUseError = AttributeInUseError; exports.ObjectReferencedError = ObjectReferencedError; exports.NoopGeocodingAdapter = NoopGeocodingAdapter; exports.SYSTEM_FIELD_NAMES = SYSTEM_FIELD_NAMES; exports.RESERVED_ATTRIBUTE_NAMES = RESERVED_ATTRIBUTE_NAMES; exports.PolicyViolationError = PolicyViolationError; exports.SYSTEM_ATTRIBUTES = SYSTEM_ATTRIBUTES; exports.getSystemAttributeList = getSystemAttributeList; exports.isSystemAttribute = isSystemAttribute; exports.isSystemAttributeObject = isSystemAttributeObject; exports.isSimpleFormNode = isSimpleFormNode; exports.isAdvancedFormNode = isAdvancedFormNode; exports.isStartNode = isStartNode; exports.isFormNode = isFormNode; exports.isConditionNode = isConditionNode; exports.isDocumentNode = isDocumentNode; exports.isEndNode = isEndNode; exports.getNodeOutputs = getNodeOutputs; exports.isConditionRule = isConditionRule; exports.isConditionGroup = isConditionGroup; exports.eq = eq; exports.neq = neq; exports.and = and; exports.or = or; exports.inValues = inValues; exports.isWorkflowDefinition = isWorkflowDefinition; exports.isWorkflowPublished = isWorkflowPublished; exports.isSystemWorkflow = isSystemWorkflow; exports.isInstanceTerminal = isInstanceTerminal; exports.isInstanceWaiting = isInstanceWaiting; exports.canResumeInstance = canResumeInstance; exports.createStartTransition = createStartTransition; exports.isInvitationValid = isInvitationValid; exports.isInvitationAccepted = isInvitationAccepted; exports.isInvitationExpired = isInvitationExpired; exports.isGrantValid = isGrantValid; exports.isGrantRevoked = isGrantRevoked; exports.isTokenRevoked = isTokenRevoked; exports.isGrantExpired = isGrantExpired; exports.canAccessNode = canAccessNode; exports.createEmptyContext = createEmptyContext; exports.getContextValue = getContextValue; exports.setContextValue = setContextValue; exports.DEFAULT_THEME = DEFAULT_THEME; exports.mergeWithDefaults = mergeWithDefaults; exports.generateCssVariables = generateCssVariables; exports.isInstanceEvent = isInstanceEvent; exports.isNodeEvent = isNodeEvent; exports.isInvitationOrGrantEvent = isInvitationOrGrantEvent; exports.ConditionOperatorSchema = ConditionOperatorSchema; exports.ConditionRuleSchema = ConditionRuleSchema; exports.ConditionGroupSchema = ConditionGroupSchema; exports.StartNodeSchema = StartNodeSchema; exports.FormFieldRefSchema = FormFieldRefSchema; exports.FlowRowFieldSchema = FlowRowFieldSchema; exports.FlowRowSchema = FlowRowSchema; exports.FormNodeSchema = FormNodeSchema; exports.ConditionNodeSchema = ConditionNodeSchema; exports.DocumentNodeSchema = DocumentNodeSchema; exports.EndNodeSchema = EndNodeSchema; exports.WorkflowNodeSchema = WorkflowNodeSchema; exports.SlotModeSchema = SlotModeSchema; exports.WorkflowSlotSchema = WorkflowSlotSchema; exports.AuthMethodSchema = AuthMethodSchema; exports.ShareStatusSchema = ShareStatusSchema; exports.WorkflowShareSchema = WorkflowShareSchema; exports.CreateShareInputSchema = CreateShareInputSchema; exports.NodePositionSchema = NodePositionSchema; exports.ViewportSchema = ViewportSchema; exports.WorkflowLayoutSchema = WorkflowLayoutSchema; exports.ThemeColorsSchema = ThemeColorsSchema; exports.ThemeLogoSchema = ThemeLogoSchema; exports.WorkflowThemeSchema = WorkflowThemeSchema; exports.WorkflowConfigSchema = WorkflowConfigSchema; exports.WorkflowStatusSchema = WorkflowStatusSchema; exports.WorkflowDefinitionSchema = WorkflowDefinitionSchema; exports.isEmpty = isEmpty; exports.isNotEmpty = isNotEmpty; exports.toUndefinedIfEmpty = toUndefinedIfEmpty; exports.hasProperties = hasProperties; exports.EMPTY_VALUE_PLACEHOLDER = EMPTY_VALUE_PLACEHOLDER; exports.formatAttributeValue = formatAttributeValue; exports.SchemaErrorCode = SchemaErrorCode; exports.SchemaError = SchemaError; exports.NotFoundError = NotFoundError; exports.ObjectNotFoundError = ObjectNotFoundError; exports.AttributeNotFoundError = AttributeNotFoundError; exports.RecordNotFoundError = RecordNotFoundError; exports.UserProfileNotFoundError = UserProfileNotFoundError; exports.FileNotFoundError = FileNotFoundError; exports.ValidationError = ValidationError; exports.ProtectedResourceError = ProtectedResourceError; exports.SyncError = SyncError; exports.NotSystemObjectError = NotSystemObjectError; exports.DuplicateError = DuplicateError; exports.isSchemaError = isSchemaError; exports.isNotFoundError = isNotFoundError; exports.isValidationError = isValidationError; exports.isProtectedResourceError = isProtectedResourceError; exports.ForbiddenError = ForbiddenError; exports.ProtectedRoleError = ProtectedRoleError; exports.RoleNotFoundError = RoleNotFoundError; exports.isForbiddenError = isForbiddenError; exports.ConcurrentModificationError = ConcurrentModificationError; exports.text = text; exports.textarea = textarea; exports.richtext = richtext; exports.number = number; exports.checkbox = checkbox; exports.date = date; exports.phone = phone; exports.currency = currency; exports.status = status; exports.select = select; exports.multiselect = multiselect; exports.location = location; exports.file = file; exports.user = user; exports.relation = relation; exports.rating = rating; exports.formula = formula; exports.rollup = rollup; exports.document = document; exports.ObjectBuilder = ObjectBuilder; exports.object = object; exports.GroupBuilder = GroupBuilder; exports.DirectTableTabConfig = DirectTableTabConfig; exports.InverseTableTabConfig = InverseTableTabConfig; exports.CustomTabConfig = CustomTabConfig; exports.NotesTabConfig = NotesTabConfig; exports.ActivityTabConfig = ActivityTabConfig; exports.FlowsTabConfig = FlowsTabConfig; exports.DocumentsTabConfig = DocumentsTabConfig; exports.TabBuilder = TabBuilder; exports.DetailViewBuilder = DetailViewBuilder; exports.ViewBuilder = ViewBuilder; exports.detailView = detailView; exports.view = view; exports.ListViewBuilder = ListViewBuilder; exports.ListViewTabConfigBuilder = ListViewTabConfigBuilder; exports.listView = listView; exports.group = group; exports.WorkflowFormRowBuilder = WorkflowFormRowBuilder; exports.WorkflowFormBuilder = WorkflowFormBuilder; exports.WorkflowSimpleFormBuilder = WorkflowSimpleFormBuilder; exports.WorkflowConditionBuilder = WorkflowConditionBuilder; exports.WorkflowEndBuilder = WorkflowEndBuilder; exports.WorkflowStartBuilder = WorkflowStartBuilder; exports.WorkflowBuilder = WorkflowBuilder; exports.workflow = workflow; exports.registry = registry; exports.SYSTEM_TEMPLATE_IDS = SYSTEM_TEMPLATE_IDS; exports.FRENCH_ID_CARD = FRENCH_ID_CARD; exports.PASSPORT = PASSPORT; exports.DRIVING_LICENSE = DRIVING_LICENSE; exports.PROOF_OF_ADDRESS = PROOF_OF_ADDRESS; exports.SIGNABLE_CONTRACT = SIGNABLE_CONTRACT; exports.GENERIC_DOCUMENT = GENERIC_DOCUMENT; exports.SYSTEM_TEMPLATES = SYSTEM_TEMPLATES; exports.getSystemTemplate = getSystemTemplate; exports.isSystemTemplate = isSystemTemplate; exports.WorkflowJwtService = WorkflowJwtService; exports.hashOptions = hashOptions; exports.cacheKeys = cacheKeys; exports.cacheTtl = cacheTtl; exports.defaultTtl = defaultTtl; exports.NoopCacheAdapter = NoopCacheAdapter; exports.formatRecord = formatRecord; exports.formatRecords = formatRecords; exports.createDefaultState = createDefaultState; exports.SHORTCUT_TO_FILTER_OPERATOR = SHORTCUT_TO_FILTER_OPERATOR; exports.QueryNoResultError = QueryNoResultError; exports.QueryMultipleResultsError = QueryMultipleResultsError; exports.TenantContextError = TenantContextError; exports.FeatureFlagsContextError = FeatureFlagsContextError; exports.isFeatureEnabled = isFeatureEnabled; exports.getFeatureValue = getFeatureValue; exports.getFeatureFlags = getFeatureFlags; exports.tryGetFeatureValue = tryGetFeatureValue; exports.hasFeatureFlagsContext = hasFeatureFlagsContext; exports.runWithFeatureFlags = runWithFeatureFlags; exports.withFeatureFlags = withFeatureFlags; exports.getSchemaFromContext = getSchemaFromContext; exports.getSchemaByNameFromContext = getSchemaByNameFromContext; exports.hasSchemaContext = hasSchemaContext; exports.getSchemaContext = getSchemaContext; exports.addSchemaToContext = addSchemaToContext; exports.runWithSchemaContext = runWithSchemaContext; exports.runWithMergedSchemaContext = runWithMergedSchemaContext; exports.getContext = getContext2; exports.getTenantId = getTenantId; exports.getUserId = getUserId; exports.hasContext = hasContext; exports.runWithContext = runWithContext; exports.withTenantContext = withTenantContext; exports.QueryBuilder = QueryBuilder; exports.createQueryBuilder = createQueryBuilder; exports.evaluateCondition = evaluateCondition; exports.evaluate = evaluate; exports.evaluateWithTrace = evaluateWithTrace; exports.ExecutorRegistry = ExecutorRegistry; exports.success = success; exports.wait = wait; exports.complete = complete; exports.error = error; exports.ConditionExecutor = ConditionExecutor; exports.DocumentExecutor = DocumentExecutor; exports.EndExecutor = EndExecutor; exports.FormExecutor = FormExecutor; exports.StartExecutor = StartExecutor; exports.createDefaultExecutorRegistry = createDefaultExecutorRegistry; exports.getDefaultExecutorRegistry = getDefaultExecutorRegistry; exports.evaluateFormula = evaluateFormula; exports.evaluateFormulaWithResult = evaluateFormulaWithResult; exports.formatFormulaResult = formatFormulaResult; exports.evaluateFormulaAttribute = evaluateFormulaAttribute; exports.validateFormulaExpression = validateFormulaExpression; exports.extractFormulaVariables = extractFormulaVariables; exports.extractRelationReferences = extractRelationReferences; exports.extractRelationNames = extractRelationNames; exports.hasRelationReferences = hasRelationReferences; exports.flattenRelationsForEval = flattenRelationsForEval; exports.evaluateFormulaWithRelations = evaluateFormulaWithRelations; exports.evaluateFormulaAttributeWithRelations = evaluateFormulaAttributeWithRelations; exports.InvalidPathError = InvalidPathError; exports.MaxDepthExceededError = MaxDepthExceededError; exports.parsePath = parsePath; exports.validatePath = validatePath; exports.pathHasManyCardinality = pathHasManyCardinality; exports.getPathDepth = getPathDepth; exports.getTargetAttributeName = getTargetAttributeName; exports.getRelationPath = getRelationPath; exports.traversePath = traversePath; exports.resolveSingleValue = resolveSingleValue; exports.resolveMultiplePaths = resolveMultiplePaths; exports.NoopHookRegistry = NoopHookRegistry; exports.DEFAULT_LABEL_FALLBACK = DEFAULT_LABEL_FALLBACK; exports.renderLabelExpression = renderLabelExpression; exports.isLabelExpression = isLabelExpression; exports.extractAttributeNames = extractAttributeNames; exports.enrichValuesForDisplay = enrichValuesForDisplay; exports.enrichValuesWithSelectLabels = enrichValuesWithSelectLabels; exports.extractRelationIds = extractRelationIds; exports.computeLabelWithRelations = computeLabelWithRelations; exports.createMockAdapter = createMockAdapter; exports.PolicyRegistry = PolicyRegistry; exports.defaultPolicyRegistry = defaultPolicyRegistry; exports.notesPolicy = notesPolicy; exports.BaseService = BaseService; exports.BaseRepository = BaseRepository; exports.SchemaContextAwareRepository = SchemaContextAwareRepository; exports.buildAuditChanges = buildAuditChanges; exports.ObjectSchemaService = ObjectSchemaService; exports.AuditService = AuditService; exports.UserService = UserService; exports.applyDefaultValues = applyDefaultValues; exports.checkPermission = checkPermission; exports.getPolicy = getPolicy; exports.buildPolicyContext = buildPolicyContext; exports.checkRecordAccess = checkRecordAccess; exports.checkRecordModifyOrThrow = checkRecordModifyOrThrow; exports.checkRecordDeleteOrThrow = checkRecordDeleteOrThrow; exports.checkSharedObjectWriteAccess = checkSharedObjectWriteAccess; exports.computeLabel = computeLabel; exports.enrichWithFormulas = enrichWithFormulas; exports.enrichRecordsWithFormulas = enrichRecordsWithFormulas; exports.createContextForCreate = createContextForCreate; exports.createContextForUpdate = createContextForUpdate; exports.createContextForDelete = createContextForDelete; exports.createContextForRestore = createContextForRestore; exports.recalculateParentRollups = recalculateParentRollups; exports.RecordQueryService = RecordQueryService; exports.RecordResolverService = RecordResolverService; exports.RelationService = RelationService; exports.RollupService = RollupService; exports.RecordService = RecordService; exports.FormulaResolverService = FormulaResolverService; exports.RollupScheduler = RollupScheduler; exports.DocumentRenderError = DocumentRenderError; exports.StorageDownloadNotSupportedError = StorageDownloadNotSupportedError; exports.DocumentRendererService = DocumentRendererService; exports.DocumentProcessingHook = DocumentProcessingHook; exports.GrantNotFoundError = GrantNotFoundError; exports.GrantExpiredError = GrantExpiredError; exports.GrantRevokedError = GrantRevokedError; exports.TokenRevokedError = TokenRevokedError; exports.WorkflowAccessGrantService = WorkflowAccessGrantService; exports.WorkflowInstanceService = WorkflowInstanceService; exports.InvitationNotFoundError = InvitationNotFoundError; exports.InvitationExpiredError = InvitationExpiredError; exports.InvitationAlreadyAcceptedError = InvitationAlreadyAcceptedError; exports.InvitationRevokedError = InvitationRevokedError; exports.WorkflowInvitationService = WorkflowInvitationService; exports.WorkflowRelationService = WorkflowRelationService; exports.WorkflowService = WorkflowService; exports.UserProfileService = UserProfileService; exports.DocumentGenerationTemplateNotFoundError = DocumentGenerationTemplateNotFoundError; exports.DocumentGenerationNotConfiguredError = DocumentGenerationNotConfiguredError; exports.DocumentGenerationService = DocumentGenerationService; exports.DocumentTemplateService = DocumentTemplateService; exports.DocumentService = DocumentService; exports.DocumentProcessingService = DocumentProcessingService; exports.FileService = FileService; exports.GeocodingService = GeocodingService; exports.GlobalSearchService = GlobalSearchService; exports.PermissionService = PermissionService; exports.ViewService = ViewService; exports.seedRegistryViews = seedRegistryViews; exports.syncNativeViews = syncNativeViews; exports.verifyRegistryViewsSeeded = verifyRegistryViewsSeeded; exports.verifyNativeViewsSync = verifyNativeViewsSync; exports.getViewSeedPreview = getViewSeedPreview; exports.getViewSyncPreview = getViewSyncPreview; exports.syncNativeObjects = syncNativeObjects; exports.verifyNativeObjectsSync = verifyNativeObjectsSync; exports.getSyncPreview = getSyncPreview; exports.syncAll = syncAll;
18256
+
18257
+
18258
+
18259
+
18260
+
18261
+
18262
+
18263
+
18264
+
18265
+
18266
+
18267
+
18268
+
18269
+
18270
+
18271
+
18272
+
18273
+
18274
+ exports.IDENTITY_PROPERTIES = IDENTITY_PROPERTIES; exports.BEHAVIOR_PROPERTIES = BEHAVIOR_PROPERTIES; exports.PRESENTATION_PROPERTIES = PRESENTATION_PROPERTIES; exports.isIdentityProperty = isIdentityProperty; exports.isBehaviorProperty = isBehaviorProperty; exports.isPresentationProperty = isPresentationProperty; exports.RELATION_TARGET_ANY = RELATION_TARGET_ANY; exports.isUniversalRelation = isUniversalRelation; exports.RecordReferencedError = RecordReferencedError; exports.AttributeInUseError = AttributeInUseError; exports.ObjectReferencedError = ObjectReferencedError; exports.NoopGeocodingAdapter = NoopGeocodingAdapter; exports.SYSTEM_FIELD_NAMES = SYSTEM_FIELD_NAMES; exports.RESERVED_ATTRIBUTE_NAMES = RESERVED_ATTRIBUTE_NAMES; exports.PolicyViolationError = PolicyViolationError; exports.FORBIDDEN_PROPERTY_TYPES = FORBIDDEN_PROPERTY_TYPES; exports.SYSTEM_ATTRIBUTES = SYSTEM_ATTRIBUTES; exports.getSystemAttributeList = getSystemAttributeList; exports.isSystemAttribute = isSystemAttribute; exports.isSystemAttributeObject = isSystemAttributeObject; exports.isSimpleFormNode = isSimpleFormNode; exports.isAdvancedFormNode = isAdvancedFormNode; exports.isStartNode = isStartNode; exports.isFormNode = isFormNode; exports.isConditionNode = isConditionNode; exports.isDocumentNode = isDocumentNode; exports.isEndNode = isEndNode; exports.getNodeOutputs = getNodeOutputs; exports.isConditionRule = isConditionRule; exports.isConditionGroup = isConditionGroup; exports.eq = eq; exports.neq = neq; exports.and = and; exports.or = or; exports.inValues = inValues; exports.isWorkflowDefinition = isWorkflowDefinition; exports.isWorkflowPublished = isWorkflowPublished; exports.isSystemWorkflow = isSystemWorkflow; exports.isInstanceTerminal = isInstanceTerminal; exports.isInstanceWaiting = isInstanceWaiting; exports.canResumeInstance = canResumeInstance; exports.createStartTransition = createStartTransition; exports.isInvitationValid = isInvitationValid; exports.isInvitationAccepted = isInvitationAccepted; exports.isInvitationExpired = isInvitationExpired; exports.isGrantValid = isGrantValid; exports.isGrantRevoked = isGrantRevoked; exports.isTokenRevoked = isTokenRevoked; exports.isGrantExpired = isGrantExpired; exports.canAccessNode = canAccessNode; exports.createEmptyContext = createEmptyContext; exports.getContextValue = getContextValue; exports.setContextValue = setContextValue; exports.DEFAULT_THEME = DEFAULT_THEME; exports.mergeWithDefaults = mergeWithDefaults; exports.generateCssVariables = generateCssVariables; exports.isInstanceEvent = isInstanceEvent; exports.isNodeEvent = isNodeEvent; exports.isInvitationOrGrantEvent = isInvitationOrGrantEvent; exports.ConditionOperatorSchema = ConditionOperatorSchema; exports.ConditionRuleSchema = ConditionRuleSchema; exports.ConditionGroupSchema = ConditionGroupSchema; exports.StartNodeSchema = StartNodeSchema; exports.FormFieldRefSchema = FormFieldRefSchema; exports.FlowRowFieldSchema = FlowRowFieldSchema; exports.FlowRowSchema = FlowRowSchema; exports.FormNodeSchema = FormNodeSchema; exports.ConditionNodeSchema = ConditionNodeSchema; exports.DocumentNodeSchema = DocumentNodeSchema; exports.EndNodeSchema = EndNodeSchema; exports.WorkflowNodeSchema = WorkflowNodeSchema; exports.SlotModeSchema = SlotModeSchema; exports.WorkflowSlotSchema = WorkflowSlotSchema; exports.AuthMethodSchema = AuthMethodSchema; exports.ShareStatusSchema = ShareStatusSchema; exports.WorkflowShareSchema = WorkflowShareSchema; exports.CreateShareInputSchema = CreateShareInputSchema; exports.NodePositionSchema = NodePositionSchema; exports.ViewportSchema = ViewportSchema; exports.WorkflowLayoutSchema = WorkflowLayoutSchema; exports.ThemeColorsSchema = ThemeColorsSchema; exports.ThemeLogoSchema = ThemeLogoSchema; exports.WorkflowThemeSchema = WorkflowThemeSchema; exports.WorkflowConfigSchema = WorkflowConfigSchema; exports.WorkflowStatusSchema = WorkflowStatusSchema; exports.WorkflowDefinitionSchema = WorkflowDefinitionSchema; exports.isEmpty = isEmpty; exports.isNotEmpty = isNotEmpty; exports.toUndefinedIfEmpty = toUndefinedIfEmpty; exports.hasProperties = hasProperties; exports.EMPTY_VALUE_PLACEHOLDER = EMPTY_VALUE_PLACEHOLDER; exports.formatAttributeValue = formatAttributeValue; exports.SchemaErrorCode = SchemaErrorCode; exports.SchemaError = SchemaError; exports.NotFoundError = NotFoundError; exports.ObjectNotFoundError = ObjectNotFoundError; exports.AttributeNotFoundError = AttributeNotFoundError; exports.RecordNotFoundError = RecordNotFoundError; exports.UserProfileNotFoundError = UserProfileNotFoundError; exports.FileNotFoundError = FileNotFoundError; exports.ValidationError = ValidationError; exports.ProtectedResourceError = ProtectedResourceError; exports.SyncError = SyncError; exports.NotSystemObjectError = NotSystemObjectError; exports.DuplicateError = DuplicateError; exports.isSchemaError = isSchemaError; exports.isNotFoundError = isNotFoundError; exports.isValidationError = isValidationError; exports.isProtectedResourceError = isProtectedResourceError; exports.ForbiddenError = ForbiddenError; exports.ProtectedRoleError = ProtectedRoleError; exports.RoleNotFoundError = RoleNotFoundError; exports.isForbiddenError = isForbiddenError; exports.ConcurrentModificationError = ConcurrentModificationError; exports.PropertySchemaBuilder = PropertySchemaBuilder; exports.PropertyTypeBuilder = PropertyTypeBuilder; exports.BasePropertyBuilder = BasePropertyBuilder; exports.TextPropertyBuilder = TextPropertyBuilder; exports.TextareaPropertyBuilder = TextareaPropertyBuilder; exports.NumberPropertyBuilder = NumberPropertyBuilder; exports.CheckboxPropertyBuilder = CheckboxPropertyBuilder; exports.DatePropertyBuilder = DatePropertyBuilder; exports.PhonePropertyBuilder = PhonePropertyBuilder; exports.CurrencyPropertyBuilder = CurrencyPropertyBuilder; exports.StatusPropertyBuilder = StatusPropertyBuilder; exports.SelectPropertyBuilder = SelectPropertyBuilder; exports.MultiselectPropertyBuilder = MultiselectPropertyBuilder; exports.RatingPropertyBuilder = RatingPropertyBuilder; exports.LocationPropertyBuilder = LocationPropertyBuilder; exports.validatePropertyType = validatePropertyType; exports.text = text; exports.textarea = textarea; exports.richtext = richtext; exports.number = number; exports.checkbox = checkbox; exports.date = date; exports.phone = phone; exports.currency = currency; exports.status = status; exports.select = select; exports.multiselect = multiselect; exports.location = location; exports.file = file; exports.user = user; exports.relation = relation; exports.rating = rating; exports.formula = formula; exports.rollup = rollup; exports.document = document; exports.ObjectBuilder = ObjectBuilder; exports.object = object; exports.GroupBuilder = GroupBuilder; exports.DirectTableTabConfig = DirectTableTabConfig; exports.InverseTableTabConfig = InverseTableTabConfig; exports.CustomTabConfig = CustomTabConfig; exports.NotesTabConfig = NotesTabConfig; exports.ActivityTabConfig = ActivityTabConfig; exports.FlowsTabConfig = FlowsTabConfig; exports.DocumentsTabConfig = DocumentsTabConfig; exports.TabBuilder = TabBuilder; exports.DetailViewBuilder = DetailViewBuilder; exports.ViewBuilder = ViewBuilder; exports.detailView = detailView; exports.view = view; exports.ListViewBuilder = ListViewBuilder; exports.ListViewTabConfigBuilder = ListViewTabConfigBuilder; exports.listView = listView; exports.group = group; exports.WorkflowFormRowBuilder = WorkflowFormRowBuilder; exports.WorkflowFormBuilder = WorkflowFormBuilder; exports.WorkflowSimpleFormBuilder = WorkflowSimpleFormBuilder; exports.WorkflowConditionBuilder = WorkflowConditionBuilder; exports.WorkflowEndBuilder = WorkflowEndBuilder; exports.WorkflowStartBuilder = WorkflowStartBuilder; exports.WorkflowBuilder = WorkflowBuilder; exports.workflow = workflow; exports.registry = registry; exports.SYSTEM_TEMPLATE_IDS = SYSTEM_TEMPLATE_IDS; exports.FRENCH_ID_CARD = FRENCH_ID_CARD; exports.PASSPORT = PASSPORT; exports.DRIVING_LICENSE = DRIVING_LICENSE; exports.PROOF_OF_ADDRESS = PROOF_OF_ADDRESS; exports.SIGNABLE_CONTRACT = SIGNABLE_CONTRACT; exports.GENERIC_DOCUMENT = GENERIC_DOCUMENT; exports.SYSTEM_TEMPLATES = SYSTEM_TEMPLATES; exports.getSystemTemplate = getSystemTemplate; exports.isSystemTemplate = isSystemTemplate; exports.WorkflowJwtService = WorkflowJwtService; exports.hashOptions = hashOptions; exports.cacheKeys = cacheKeys; exports.cacheTtl = cacheTtl; exports.defaultTtl = defaultTtl; exports.NoopCacheAdapter = NoopCacheAdapter; exports.formatRecord = formatRecord; exports.formatRecords = formatRecords; exports.createDefaultState = createDefaultState; exports.SHORTCUT_TO_FILTER_OPERATOR = SHORTCUT_TO_FILTER_OPERATOR; exports.QueryNoResultError = QueryNoResultError; exports.QueryMultipleResultsError = QueryMultipleResultsError; exports.TenantContextError = TenantContextError; exports.FeatureFlagsContextError = FeatureFlagsContextError; exports.isFeatureEnabled = isFeatureEnabled; exports.getFeatureValue = getFeatureValue; exports.getFeatureFlags = getFeatureFlags; exports.tryGetFeatureValue = tryGetFeatureValue; exports.hasFeatureFlagsContext = hasFeatureFlagsContext; exports.runWithFeatureFlags = runWithFeatureFlags; exports.withFeatureFlags = withFeatureFlags; exports.getSchemaFromContext = getSchemaFromContext; exports.getSchemaByNameFromContext = getSchemaByNameFromContext; exports.hasSchemaContext = hasSchemaContext; exports.getSchemaContext = getSchemaContext; exports.addSchemaToContext = addSchemaToContext; exports.runWithSchemaContext = runWithSchemaContext; exports.runWithMergedSchemaContext = runWithMergedSchemaContext; exports.getContext = getContext2; exports.getTenantId = getTenantId; exports.getUserId = getUserId; exports.hasContext = hasContext; exports.runWithContext = runWithContext; exports.withTenantContext = withTenantContext; exports.QueryBuilder = QueryBuilder; exports.createQueryBuilder = createQueryBuilder; exports.evaluateCondition = evaluateCondition; exports.evaluate = evaluate; exports.evaluateWithTrace = evaluateWithTrace; exports.ExecutorRegistry = ExecutorRegistry; exports.success = success; exports.wait = wait; exports.complete = complete; exports.error = error; exports.ConditionExecutor = ConditionExecutor; exports.DocumentExecutor = DocumentExecutor; exports.EndExecutor = EndExecutor; exports.FormExecutor = FormExecutor; exports.StartExecutor = StartExecutor; exports.createDefaultExecutorRegistry = createDefaultExecutorRegistry; exports.getDefaultExecutorRegistry = getDefaultExecutorRegistry; exports.evaluateFormula = evaluateFormula; exports.evaluateFormulaWithResult = evaluateFormulaWithResult; exports.formatFormulaResult = formatFormulaResult; exports.evaluateFormulaAttribute = evaluateFormulaAttribute; exports.validateFormulaExpression = validateFormulaExpression; exports.extractFormulaVariables = extractFormulaVariables; exports.extractRelationReferences = extractRelationReferences; exports.extractRelationNames = extractRelationNames; exports.hasRelationReferences = hasRelationReferences; exports.flattenRelationsForEval = flattenRelationsForEval; exports.evaluateFormulaWithRelations = evaluateFormulaWithRelations; exports.evaluateFormulaAttributeWithRelations = evaluateFormulaAttributeWithRelations; exports.InvalidPathError = InvalidPathError; exports.MaxDepthExceededError = MaxDepthExceededError; exports.parsePath = parsePath; exports.validatePath = validatePath; exports.pathHasManyCardinality = pathHasManyCardinality; exports.getPathDepth = getPathDepth; exports.getTargetAttributeName = getTargetAttributeName; exports.getRelationPath = getRelationPath; exports.traversePath = traversePath; exports.resolveSingleValue = resolveSingleValue; exports.resolveMultiplePaths = resolveMultiplePaths; exports.NoopHookRegistry = NoopHookRegistry; exports.DEFAULT_LABEL_FALLBACK = DEFAULT_LABEL_FALLBACK; exports.renderLabelExpression = renderLabelExpression; exports.isLabelExpression = isLabelExpression; exports.extractAttributeNames = extractAttributeNames; exports.enrichValuesForDisplay = enrichValuesForDisplay; exports.enrichValuesWithSelectLabels = enrichValuesWithSelectLabels; exports.extractRelationIds = extractRelationIds; exports.computeLabelWithRelations = computeLabelWithRelations; exports.createMockAdapter = createMockAdapter; exports.PolicyRegistry = PolicyRegistry; exports.defaultPolicyRegistry = defaultPolicyRegistry; exports.notesPolicy = notesPolicy; exports.BaseService = BaseService; exports.BaseRepository = BaseRepository; exports.SchemaContextAwareRepository = SchemaContextAwareRepository; exports.buildAuditChanges = buildAuditChanges; exports.ObjectSchemaService = ObjectSchemaService; exports.AuditService = AuditService; exports.UserService = UserService; exports.applyDefaultValues = applyDefaultValues; exports.checkPermission = checkPermission; exports.getPolicy = getPolicy; exports.buildPolicyContext = buildPolicyContext; exports.checkRecordAccess = checkRecordAccess; exports.checkRecordModifyOrThrow = checkRecordModifyOrThrow; exports.checkRecordDeleteOrThrow = checkRecordDeleteOrThrow; exports.checkSharedObjectWriteAccess = checkSharedObjectWriteAccess; exports.computeLabel = computeLabel; exports.enrichWithFormulas = enrichWithFormulas; exports.enrichRecordsWithFormulas = enrichRecordsWithFormulas; exports.createContextForCreate = createContextForCreate; exports.createContextForUpdate = createContextForUpdate; exports.createContextForDelete = createContextForDelete; exports.createContextForRestore = createContextForRestore; exports.recalculateParentRollups = recalculateParentRollups; exports.RecordQueryService = RecordQueryService; exports.RecordResolverService = RecordResolverService; exports.RelationPropertiesService = RelationPropertiesService; exports.RelationService = RelationService; exports.RollupService = RollupService; exports.RecordService = RecordService; exports.FormulaResolverService = FormulaResolverService; exports.RollupScheduler = RollupScheduler; exports.DocumentRenderError = DocumentRenderError; exports.StorageDownloadNotSupportedError = StorageDownloadNotSupportedError; exports.DocumentRendererService = DocumentRendererService; exports.DocumentProcessingHook = DocumentProcessingHook; exports.GrantNotFoundError = GrantNotFoundError; exports.GrantExpiredError = GrantExpiredError; exports.GrantRevokedError = GrantRevokedError; exports.TokenRevokedError = TokenRevokedError; exports.WorkflowAccessGrantService = WorkflowAccessGrantService; exports.WorkflowInstanceService = WorkflowInstanceService; exports.InvitationNotFoundError = InvitationNotFoundError; exports.InvitationExpiredError = InvitationExpiredError; exports.InvitationAlreadyAcceptedError = InvitationAlreadyAcceptedError; exports.InvitationRevokedError = InvitationRevokedError; exports.WorkflowInvitationService = WorkflowInvitationService; exports.WorkflowRelationService = WorkflowRelationService; exports.WorkflowService = WorkflowService; exports.UserProfileService = UserProfileService; exports.DocumentGenerationTemplateNotFoundError = DocumentGenerationTemplateNotFoundError; exports.DocumentGenerationNotConfiguredError = DocumentGenerationNotConfiguredError; exports.DocumentGenerationService = DocumentGenerationService; exports.DocumentTemplateService = DocumentTemplateService; exports.DocumentService = DocumentService; exports.DocumentProcessingService = DocumentProcessingService; exports.FileService = FileService; exports.GeocodingService = GeocodingService; exports.GlobalSearchService = GlobalSearchService; exports.PermissionService = PermissionService; exports.ViewService = ViewService; exports.seedRegistryViews = seedRegistryViews; exports.syncNativeViews = syncNativeViews; exports.verifyRegistryViewsSeeded = verifyRegistryViewsSeeded; exports.verifyNativeViewsSync = verifyNativeViewsSync; exports.getViewSeedPreview = getViewSeedPreview; exports.getViewSyncPreview = getViewSyncPreview; exports.syncNativeObjects = syncNativeObjects; exports.verifyNativeObjectsSync = verifyNativeObjectsSync; exports.getSyncPreview = getSyncPreview; exports.syncAll = syncAll;