@stndrds/schema 0.1.0-alpha.51 → 0.1.0-alpha.52

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.
@@ -178,6 +178,16 @@ interface AITodoList {
178
178
  progress: number;
179
179
  isComplete: boolean;
180
180
  }
181
+ /**
182
+ * Resolved attachment metadata (populated when fetching messages)
183
+ */
184
+ interface AIMessageAttachment {
185
+ id: string;
186
+ name: string;
187
+ size: number;
188
+ mimeType: string;
189
+ url: string;
190
+ }
181
191
  /**
182
192
  * AI Conversation record
183
193
  */
@@ -211,6 +221,8 @@ interface AIMessage {
211
221
  model: string | null;
212
222
  /** File attachment IDs (references files table) */
213
223
  attachmentIds: string[] | null;
224
+ /** Resolved attachments (populated when fetching messages) */
225
+ attachments?: AIMessageAttachment[];
214
226
  createdAt: Date;
215
227
  }
216
228
  /**
@@ -8097,6 +8109,7 @@ interface RecordServiceOptions {
8097
8109
  declare class RecordService extends BaseService {
8098
8110
  private schemaService;
8099
8111
  private queryService;
8112
+ private recordResolver;
8100
8113
  private relationService;
8101
8114
  private userService;
8102
8115
  private rollupService;
@@ -8202,451 +8215,711 @@ declare class RecordService extends BaseService {
8202
8215
  }
8203
8216
 
8204
8217
  /**
8205
- * Result of relation validation
8218
+ * Default fallback value when expression resolves to empty string
8206
8219
  */
8207
- interface RelationValidationResult {
8208
- valid: boolean;
8209
- errors: RelationValidationError[];
8210
- }
8220
+ declare const DEFAULT_LABEL_FALLBACK = "(Untitled)";
8221
+ declare function renderLabelExpression(template: string, values: Record<string, unknown>, fallback?: string): string;
8211
8222
  /**
8212
- * Individual relation validation error
8223
+ * Check if a string is a valid label expression template
8224
+ * A valid template contains at least one {{ variable }} block with a non-empty variable
8213
8225
  */
8214
- interface RelationValidationError {
8215
- /** Attribute name */
8216
- attribute: string;
8217
- /** Error message */
8218
- message: string;
8219
- /** Invalid record IDs */
8220
- invalidIds?: string[];
8221
- }
8226
+ declare function isLabelExpression(value: string): boolean;
8222
8227
  /**
8223
- * Resolved relation option
8228
+ * Extract attribute names referenced in a label expression
8229
+ * Useful for validation or dependency tracking
8224
8230
  *
8225
- * SECURITY: This type intentionally excludes raw record data.
8226
- * Only the computed label is exposed to prevent unauthorized data access
8227
- * through relation lookups. Users must have explicit read permissions
8228
- * on an object to access its record data.
8231
+ * @example
8232
+ * extractAttributeNames("{{ firstName }} {{ lastName | UPPER }}")
8233
+ * // ["firstName", "lastName"]
8229
8234
  */
8230
- interface RelationOption {
8231
- /** Record ID */
8232
- id: string;
8233
- /** Object ID */
8234
- objectId: string;
8235
- /** Object name (technical name) */
8236
- objectName: string;
8237
- /** Object label (display name) */
8238
- objectLabel: string;
8239
- /** Object icon */
8240
- objectIcon?: string;
8241
- /** Display label (computed from labelExpression) */
8242
- label: string;
8243
- }
8235
+ declare function extractAttributeNames(template: string): string[];
8244
8236
  /**
8245
- * Response for relation options
8237
+ * Enrich record values by formatting complex types for display
8238
+ *
8239
+ * Transforms raw values (objects, dates, etc.) into human-readable strings
8240
+ * for use in label expression rendering. Uses formatAttributeValue internally.
8241
+ *
8242
+ * @param values - Record values containing raw attribute values
8243
+ * @param attributes - Attribute definitions for formatting
8244
+ * @returns New object with complex values formatted as strings
8245
+ *
8246
+ * @example
8247
+ * ```typescript
8248
+ * const enriched = enrichValuesForDisplay(
8249
+ * { status: "active", price: { value: 1500, code: "EUR" } },
8250
+ * [
8251
+ * { type: "select", name: "status", options: [{ value: "active", label: "Active" }] },
8252
+ * { type: "currency", name: "price" }
8253
+ * ]
8254
+ * );
8255
+ * // → { status: "Active", price: "1,500.00 EUR" }
8256
+ * ```
8246
8257
  */
8247
- interface RelationOptionsResponse {
8248
- options: RelationOption[];
8249
- hasMore: boolean;
8250
- total: number;
8251
- }
8258
+ declare function enrichValuesForDisplay(values: Record<string, unknown>, attributes: Attribute[]): Record<string, unknown>;
8252
8259
  /**
8253
- * Parameters for fetching relation options
8260
+ * @deprecated Use `enrichValuesForDisplay` instead
8254
8261
  */
8255
- interface GetRelationOptionsParams {
8256
- /** Search query */
8257
- query?: string;
8258
- /** Page number (1-based) */
8259
- page?: number;
8260
- /** Page size */
8261
- pageSize?: number;
8262
- /** Filter by specific target object */
8263
- targetObject?: string;
8264
- /** Additional filter to apply (e.g., workflow context filtering) */
8265
- filter?: FilterState;
8266
- }
8262
+ declare const enrichValuesWithSelectLabels: typeof enrichValuesForDisplay;
8267
8263
  /**
8268
- * Options for RelationService constructor
8264
+ * Extract relation IDs from a value (string or array)
8265
+ * For cardinality "many", only the first ID is extracted for label display
8266
+ *
8267
+ * @param val - Relation value (string ID or array of IDs)
8268
+ * @returns Array of IDs (max 1 element for display purposes)
8269
+ *
8270
+ * @example
8271
+ * ```typescript
8272
+ * extractRelationIds("rec-123") // → ["rec-123"]
8273
+ * extractRelationIds(["rec-1", "rec-2"]) // → ["rec-1"]
8274
+ * extractRelationIds(null) // → []
8275
+ * ```
8269
8276
  */
8270
- interface RelationServiceOptions {
8271
- /**
8272
- * Record query service for fetching relation options.
8273
- * Required for getOptions() to work.
8274
- * If not provided, getOptions() will throw.
8275
- */
8276
- queryService?: RecordQueryService;
8277
- }
8277
+ declare function extractRelationIds(val: unknown): string[];
8278
8278
  /**
8279
- * Request item for batch relation resolution
8279
+ * Resolver function type for fetching relation labels
8280
+ * Takes an array of record IDs and returns a map of ID → label
8280
8281
  */
8281
- interface ResolveIdsBatchRequest {
8282
- /** Relation attribute ID */
8283
- attributeId: string;
8284
- /** Record IDs to resolve for this attribute */
8285
- ids: string[];
8286
- }
8282
+ type RelationLabelResolver = (ids: string[]) => Promise<Map<string, string>>;
8287
8283
  /**
8288
- * Response for batch relation resolution
8289
- * Maps attributeId to resolved options
8284
+ * Compute a label from a template with full relation resolution (1 level deep)
8285
+ *
8286
+ * Uses pre-computed record.label for nested relations to avoid infinite recursion.
8287
+ * This function enriches select/multiselect values AND resolves relation IDs to their labels.
8288
+ *
8289
+ * @param template - Label expression template (e.g., "{{ company }} - {{ name }}")
8290
+ * @param values - Record values to interpolate
8291
+ * @param attributes - Attribute definitions for the object
8292
+ * @param resolveRelationIds - Function to resolve record IDs to their labels
8293
+ * @returns The rendered label string
8294
+ *
8295
+ * @example
8296
+ * ```typescript
8297
+ * const label = await computeLabelWithRelations(
8298
+ * "{{ company }} - {{ name }}",
8299
+ * { company: "rec-123", name: "Product A" },
8300
+ * objectSchema.attributes,
8301
+ * async (ids) => {
8302
+ * const records = await adapter.objectRecords.findByIds(ids);
8303
+ * return new Map(records.map(r => [r.id, r.label]));
8304
+ * }
8305
+ * );
8306
+ * // → "Acme Corp - Product A"
8307
+ * ```
8290
8308
  */
8291
- interface ResolveIdsBatchResponse {
8292
- [attributeId: string]: RelationOption[];
8309
+ declare function computeLabelWithRelations(template: string, values: Record<string, unknown>, attributes: Attribute[], resolveRelationIds: RelationLabelResolver): Promise<string>;
8310
+
8311
+ /**
8312
+ * Interface for resolving relation labels.
8313
+ * Allows dependency injection for testing and decoupling.
8314
+ */
8315
+ interface LabelResolver {
8316
+ resolveRelationIds(ids: string[], attributeId: string): Promise<Array<{
8317
+ id: string;
8318
+ label: string;
8319
+ }>>;
8320
+ findRecordLabels(ids: string[]): Promise<Array<{
8321
+ id: string;
8322
+ label?: string;
8323
+ }>>;
8293
8324
  }
8294
8325
  /**
8295
- * Service for validating relation attributes.
8296
- * Ensures referenced records exist and belong to valid target objects.
8297
- * Automatically uses tenant context from AsyncLocalStorage.
8326
+ * Compute display label from schema expression.
8327
+ * Automatically resolves relation attribute values to their labels
8328
+ * and select/multiselect values to their option labels.
8298
8329
  *
8299
- * Supports optional caching via CacheAdapter for improved performance
8300
- * on relation options lookups.
8330
+ * @param schema - Object schema with labelExpression
8331
+ * @param values - Record values
8332
+ * @param resolver - Resolver for relation labels
8333
+ * @returns Computed label string
8301
8334
  */
8302
- declare class RelationService extends BaseService {
8303
- private schemaService;
8304
- private queryService?;
8305
- constructor(adapter: DatabaseAdapter, nativeRegistry: typeof registry, options?: RelationServiceOptions);
8306
- /**
8307
- * Set the query service after construction.
8308
- * Useful for breaking circular dependencies during initialization.
8309
- */
8310
- setQueryService(queryService: RecordQueryService): void;
8335
+ declare function computeLabel(schema: ObjectDefinition, values: Record<string, unknown>, resolver: LabelResolver): Promise<string>;
8336
+
8337
+ /**
8338
+ * Result of a rollup calculation
8339
+ */
8340
+ interface RollupResult {
8341
+ /** Computed value */
8342
+ value: unknown;
8343
+ /** Number of records that contributed to the calculation */
8344
+ recordCount: number;
8345
+ }
8346
+ /**
8347
+ * Options for RollupService constructor
8348
+ */
8349
+ interface RollupServiceOptions {
8311
8350
  /**
8312
- * Get the query service, throwing if not configured.
8351
+ * Record resolver for cached record fetching.
8352
+ * Required for cached access to records.
8313
8353
  */
8314
- private getQueryServiceOrThrow;
8354
+ recordResolver: RecordResolverService;
8355
+ }
8356
+ /**
8357
+ * Service for calculating rollup attribute values
8358
+ *
8359
+ * Rollups aggregate values from related records (e.g., sum of order amounts
8360
+ * for a company). They are calculated when needed and can be materialized
8361
+ * (stored) for performance.
8362
+ *
8363
+ * Supports optional caching via CacheAdapter for improved performance.
8364
+ * Rollup values have a short TTL (2 minutes) due to high volatility.
8365
+ *
8366
+ * Phase 3: Supports single-level relation rollups
8367
+ */
8368
+ declare class RollupService extends BaseService {
8369
+ private recordResolver;
8370
+ constructor(adapter: DatabaseAdapter, options: RollupServiceOptions);
8315
8371
  /**
8316
- * Validate all relation attributes in the data
8372
+ * Calculate a rollup value for a record
8317
8373
  *
8318
- * @param schema - Object schema containing attribute definitions
8319
- * @param data - Record data to validate
8320
- * @returns Validation result with errors if any
8374
+ * Results are cached if a CacheAdapter is configured.
8375
+ *
8376
+ * @param recordId - ID of the parent record
8377
+ * @param rollupAttr - Rollup attribute definition
8378
+ * @param schema - Schema of the parent object
8379
+ * @returns Computed rollup value
8321
8380
  *
8322
8381
  * @example
8323
8382
  * ```typescript
8324
- * const result = await relationService.validateRelations(schema, {
8325
- * company: "rec-123",
8326
- * contacts: ["rec-456", "rec-789"]
8327
- * });
8328
- *
8329
- * if (!result.valid) {
8330
- * console.log(result.errors);
8331
- * // [{ attribute: "company", message: "Record not found", invalidIds: ["rec-123"] }]
8332
- * }
8383
+ * // Sum all order amounts for a company
8384
+ * const totalOrders = await rollupService.calculate(
8385
+ * "company-123",
8386
+ * {
8387
+ * type: "rollup",
8388
+ * name: "totalOrders",
8389
+ * relationAttribute: "orders",
8390
+ * targetAttribute: "amount",
8391
+ * function: "sum",
8392
+ * ...
8393
+ * },
8394
+ * companySchema
8395
+ * );
8333
8396
  * ```
8334
8397
  */
8335
- validateRelations(schema: ObjectDefinition, data: Record<string, unknown>): Promise<RelationValidationResult>;
8398
+ calculate(recordId: string, rollupAttr: RollupAttribute, schema: ObjectDefinition): Promise<RollupResult>;
8336
8399
  /**
8337
- * Validate a single relation attribute value
8338
- *
8339
- * Uses batch fetching (findByIds) to avoid N+1 query pattern.
8400
+ * Internal method to compute rollup value (no caching)
8340
8401
  */
8341
- private validateRelationAttribute;
8402
+ private computeRollup;
8342
8403
  /**
8343
- * Extract IDs from relation value based on cardinality
8404
+ * Forward pattern: this record has a relation attribute pointing to other records
8405
+ * Example: entreprise222 has relation "entreprises" → companies, rollup collects from companies
8344
8406
  */
8345
- private extractIds;
8407
+ private calculateForward;
8346
8408
  /**
8347
- * Get valid object IDs from relation targets
8348
- * Note: Universal relations (toAny) are handled earlier in validateRelationAttribute
8409
+ * Reverse pattern: other records have a relation pointing to this record
8410
+ * Example: Company has rollup on "orders", Order has relation "company" → companies
8349
8411
  */
8350
- private getValidObjectIds;
8412
+ private calculateReverse;
8351
8413
  /**
8352
- * Validate relations and throw if invalid
8414
+ * Extract and aggregate values from related records
8353
8415
  */
8354
- validateRelationsOrThrow(schema: ObjectDefinition, data: Record<string, unknown>): Promise<void>;
8416
+ private aggregateValues;
8355
8417
  /**
8356
- * Get available options for a relation attribute.
8357
- * Searches across all target objects defined in the relation.
8358
- * Automatically uses tenant context from AsyncLocalStorage.
8359
- *
8360
- * @param attribute - Relation attribute definition
8361
- * @param params - Query parameters
8418
+ * Calculate rollup values for multiple records (batched)
8362
8419
  *
8363
- * @example
8364
- * ```typescript
8365
- * const options = await relationService.getOptions(attribute, {
8366
- * query: "nike",
8367
- * page: 1,
8368
- * pageSize: 20
8369
- * });
8370
- * ```
8420
+ * More efficient than calling calculate() for each record individually.
8371
8421
  */
8372
- getOptions(attribute: RelationAttribute, params?: GetRelationOptionsParams): Promise<RelationOptionsResponse>;
8422
+ calculateForMany(recordIds: string[], rollupAttr: RollupAttribute, schema: ObjectDefinition): Promise<Map<string, RollupResult>>;
8373
8423
  /**
8374
- * Internal method to fetch relation options (extracted for caching)
8424
+ * Apply aggregation function to a set of values
8375
8425
  */
8376
- private fetchOptions;
8426
+ private aggregate;
8377
8427
  /**
8378
- * Resolve record IDs to their display labels.
8379
- * Useful for displaying current values in the UI.
8380
- *
8381
- * Uses caching per individual record ID for optimal performance.
8382
- * Cache key format: `${attributeId}:${recordId}` to handle different displayTemplates.
8383
- *
8384
- * @param ids - Record IDs to resolve
8385
- * @param attributeId - Relation attribute ID to use its displayTemplate for label rendering
8386
- *
8387
- * @example
8388
- * ```typescript
8389
- * const resolved = await relationService.resolveIds(["rec-1", "rec-2"], "attr-123");
8390
- * // [{ id: "rec-1", label: "Nike Air Max", objectName: "products", ... }]
8391
- * ```
8428
+ * Get the default empty value for a rollup function
8392
8429
  */
8393
- resolveIds(ids: string[], attributeId: string): Promise<RelationOption[]>;
8430
+ private getEmptyValue;
8394
8431
  /**
8395
- * Resolve multiple attribute/IDs batches in a single operation.
8396
- * Optimized for DataGrid scenarios with multiple relation columns.
8397
- *
8398
- * Benefits over multiple resolveIds() calls:
8399
- * - Single DB query for all records across all attributes
8400
- * - Deduplication of records referenced by multiple attributes
8401
- * - Single schema lookup per objectId
8402
- *
8403
- * Uses caching per individual record ID for optimal performance.
8404
- *
8405
- * @param requests - Array of { attributeId, ids } to resolve
8406
- * @returns Map of attributeId to resolved options
8432
+ * Sum numeric values
8433
+ */
8434
+ private sumNumbers;
8435
+ /**
8436
+ * Average numeric values
8437
+ */
8438
+ private averageNumbers;
8439
+ /**
8440
+ * Get earliest date from values
8441
+ */
8442
+ private earliestDate;
8443
+ /**
8444
+ * Get latest date from values
8445
+ */
8446
+ private latestDate;
8447
+ /**
8448
+ * Recalculate all rollup attributes for a record and update it
8407
8449
  *
8408
- * @example
8409
- * ```typescript
8410
- * const results = await relationService.resolveIdsBatch([
8411
- * { attributeId: "attr-company", ids: ["rec-1", "rec-2"] },
8412
- * { attributeId: "attr-contact", ids: ["rec-3", "rec-4"] },
8413
- * ]);
8414
- * // { "attr-company": [...], "attr-contact": [...] }
8415
- * ```
8450
+ * Called after related records change to keep rollups up-to-date.
8416
8451
  */
8417
- resolveIdsBatch(requests: ResolveIdsBatchRequest[]): Promise<ResolveIdsBatchResponse>;
8452
+ recalculateAndUpdate(record: ObjectRecord, schema: ObjectDefinition): Promise<ObjectRecord>;
8418
8453
  /**
8419
- * Internal method to fetch and resolve multiple composite IDs at once.
8420
- * Optimized for batch operations - single DB query for all records.
8454
+ * Find parent records that need rollup recalculation when a child record changes
8455
+ *
8456
+ * Used by hooks to determine which parent records to recalculate after
8457
+ * a child record is created, updated, or deleted.
8458
+ *
8459
+ * @param changedRecord - The record that was modified
8460
+ * @param changedSchema - Schema of the changed record's object
8461
+ * @returns Array of parent record IDs that need recalculation
8421
8462
  */
8422
- private fetchResolveIdsBatch;
8463
+ findAffectedParentRecords(changedRecord: ObjectRecord, changedSchema: ObjectDefinition): Promise<string[]>;
8423
8464
  /**
8424
- * Internal method to fetch and resolve relation IDs (no caching).
8425
- * Uses batch fetching for performance - fetches all records in one query,
8426
- * then groups by objectId to minimize schema lookups.
8465
+ * Invalidate cached rollups for affected parent records.
8466
+ * Call this after a child record is created, updated, or deleted.
8467
+ *
8468
+ * @param affectedParentIds - Array of parent record IDs whose rollups need invalidation
8427
8469
  */
8428
- private fetchResolveIds;
8470
+ invalidateAffectedRollups(affectedParentIds: string[]): Promise<void>;
8429
8471
  /**
8430
- * Find a relation attribute by ID.
8431
- * Results are cached if a CacheAdapter is configured.
8432
- * Cache is invalidated by ObjectSchemaService.invalidateSchemaCache() via allAttributes pattern.
8472
+ * Invalidate all cached rollups for the current tenant.
8473
+ * Use sparingly - prefer targeted invalidation.
8433
8474
  */
8434
- findAttributeById(attributeId: string): Promise<RelationAttribute | null>;
8475
+ invalidateAllRollups(): Promise<void>;
8435
8476
  /**
8436
- * Internal method to fetch attribute by ID (no caching)
8477
+ * Find records that have forward rollups pointing to the modified record.
8478
+ *
8479
+ * Forward rollups are rollups where the record has a relation attribute
8480
+ * pointing to another object, and the rollup aggregates values from that target.
8481
+ * When the target record changes, we need to recalculate these rollups.
8482
+ *
8483
+ * Example: Order has relation "company" → Company, and rollup "capitalSocial"
8484
+ * aggregating from the Company. When Company.capitalSocial changes,
8485
+ * all Orders pointing to that Company need their rollup recalculated.
8486
+ *
8487
+ * @param changedRecord - The record that was modified
8488
+ * @param changedSchema - Schema of the changed record's object
8489
+ * @returns Array of records that need their forward rollups recalculated
8437
8490
  */
8438
- private fetchAttributeById;
8491
+ findRecordsWithForwardRollup(changedRecord: ObjectRecord, changedSchema: ObjectDefinition): Promise<ObjectRecord[]>;
8439
8492
  }
8440
8493
 
8441
8494
  /**
8442
- * Resolved relation values for a record
8443
- * Maps relation attribute name to the resolved record's values
8495
+ * Context for rollup cascade operations.
8496
+ * Provides the necessary services via dependency injection.
8444
8497
  */
8445
- type ResolvedRelations = Record<string, Record<string, unknown>>;
8498
+ interface RollupCascadeContext {
8499
+ rollupService: RollupService;
8500
+ schemaService: ObjectSchemaService;
8501
+ findRecordsByIds: (ids: string[]) => Promise<ObjectRecord[]>;
8502
+ }
8446
8503
  /**
8447
- * Service for resolving relation values from related records
8504
+ * Recalculate rollups after a record changes.
8448
8505
  *
8449
- * Used by formula evaluation to access values from related records
8450
- * (e.g., "company.name" in a formula on an order)
8506
+ * This handles three cases:
8507
+ * 1. The record itself has rollups (e.g., aggregating from related records it points to)
8508
+ * 2. Parent records have rollups that aggregate from this record (reverse pattern)
8509
+ * 3. Records that have forward rollups pointing to this record (forward pattern)
8510
+ *
8511
+ * Optimized: Pre-loads schemas by objectId to avoid N redundant calls
8512
+ * when multiple records share the same objectId.
8513
+ *
8514
+ * @param record - The record that was modified
8515
+ * @param schema - Schema of the record's object
8516
+ * @param ctx - Context with required services
8451
8517
  */
8452
- declare class RelationResolverService {
8453
- private adapter;
8518
+ declare function recalculateParentRollups(record: ObjectRecord, schema: ObjectDefinition, ctx: RollupCascadeContext): Promise<void>;
8519
+
8520
+ /**
8521
+ * Service for cached record resolution.
8522
+ *
8523
+ * Centralizes all record fetching with automatic caching to avoid
8524
+ * redundant database queries across services (relation, rollup, formulas).
8525
+ *
8526
+ * Also provides factory methods for creating resolver interfaces used by
8527
+ * helpers (label computation, rollup cascade).
8528
+ *
8529
+ * @example
8530
+ * ```typescript
8531
+ * const resolver = new RecordResolverService(adapter);
8532
+ *
8533
+ * // Cached record fetching
8534
+ * const record = await resolver.findById("rec-123");
8535
+ * const records = await resolver.findByIds(["rec-1", "rec-2"]);
8536
+ *
8537
+ * // Factory methods for helpers
8538
+ * const labelResolver = resolver.createLabelResolver(relationService);
8539
+ * const rollupContext = resolver.createRollupContext(rollupService, schemaService);
8540
+ * ```
8541
+ */
8542
+ declare class RecordResolverService extends BaseService {
8454
8543
  constructor(adapter: DatabaseAdapter);
8455
8544
  /**
8456
- * Resolve values from related records for formula evaluation
8545
+ * Find a record by ID with caching.
8457
8546
  *
8458
- * Phase 2: Supports 1 level of relation traversal only
8547
+ * Uses the shared record cache for optimal performance.
8548
+ * Delegates to findByIds for consistent cache handling.
8459
8549
  *
8460
- * @param record - The source record
8461
- * @param schema - Schema of the source object
8462
- * @param relationNames - Names of relation attributes to resolve
8463
- * @returns Map of relation name to related record's values
8550
+ * @param id - Record ID
8551
+ * @returns Record or null if not found
8552
+ */
8553
+ findById(id: string): Promise<ObjectRecord | null>;
8554
+ /**
8555
+ * Find multiple records by IDs with caching.
8464
8556
  *
8465
- * @example
8466
- * ```typescript
8467
- * // For an order with company relation
8468
- * const resolved = await resolver.resolveRelationValues(
8469
- * orderRecord,
8470
- * orderSchema,
8471
- * ["company"]
8472
- * );
8473
- * // → { company: { id: "...", name: "Acme Corp", ... } }
8474
- * ```
8557
+ * Each record is cached individually for reuse across services.
8558
+ * Only fetches records not already in cache.
8559
+ *
8560
+ * @param ids - Record IDs to fetch
8561
+ * @returns Array of found records (missing IDs are not included)
8475
8562
  */
8476
- resolveRelationValues(record: ObjectRecord, schema: ObjectDefinition, relationNames: string[]): Promise<ResolvedRelations>;
8563
+ findByIds(ids: string[]): Promise<ObjectRecord[]>;
8477
8564
  /**
8478
- * Resolve relation values for multiple records (batched)
8565
+ * Create a RelationLabelResolver callback for computeLabelWithRelations.
8479
8566
  *
8480
- * Optimized for list operations - fetches all related records in one batch
8567
+ * Used by RelationService.resolveLabel() and ObjectSchemaService.
8481
8568
  *
8482
- * @param records - Source records
8483
- * @param schema - Schema of the source object
8484
- * @param relationNames - Names of relation attributes to resolve
8485
- * @returns Map of record ID to resolved relations
8569
+ * @returns Callback that resolves record IDs to their labels (cached)
8486
8570
  */
8487
- resolveRelationValuesForMany(records: ObjectRecord[], schema: ObjectDefinition, relationNames: string[]): Promise<Map<string, ResolvedRelations>>;
8571
+ createRelationLabelResolver(): RelationLabelResolver;
8488
8572
  /**
8489
- * Flatten resolved relations for formula evaluation
8573
+ * Create a LabelResolver interface for label computation helpers.
8490
8574
  *
8491
- * Converts nested structure to dot-notation keys:
8492
- * { company: { name: "Acme" } } → { "company.name": "Acme" }
8575
+ * Used by RecordService for computing record labels.
8493
8576
  *
8494
- * @param resolved - Resolved relations from resolveRelationValues
8495
- * @returns Flattened values suitable for formula evaluation
8577
+ * @param relationService - RelationService for resolving relation display labels
8578
+ * @returns LabelResolver interface with cached record fetching
8496
8579
  */
8497
- flattenResolvedRelations(resolved: ResolvedRelations): Record<string, unknown>;
8580
+ createLabelResolver(relationService: RelationService): LabelResolver;
8498
8581
  /**
8499
- * Extract a single relation ID from a value
8500
- * Handles both single (string) and multi (array) relations
8501
- * @internal
8582
+ * Create a RollupCascadeContext for rollup recalculation.
8583
+ *
8584
+ * Used by RecordService after create/update/delete operations.
8585
+ *
8586
+ * @param rollupService - RollupService for recalculating rollups
8587
+ * @param schemaService - ObjectSchemaService for fetching schemas
8588
+ * @returns Context with cached record fetching
8502
8589
  */
8503
- private extractSingleId;
8590
+ createRollupContext(rollupService: RollupService, schemaService: ObjectSchemaService): RollupCascadeContext;
8504
8591
  }
8505
8592
 
8506
8593
  /**
8507
- * Result of a rollup calculation
8594
+ * Result of relation validation
8508
8595
  */
8509
- interface RollupResult {
8510
- /** Computed value */
8511
- value: unknown;
8512
- /** Number of records that contributed to the calculation */
8513
- recordCount: number;
8596
+ interface RelationValidationResult {
8597
+ valid: boolean;
8598
+ errors: RelationValidationError[];
8514
8599
  }
8515
8600
  /**
8516
- * Service for calculating rollup attribute values
8517
- *
8518
- * Rollups aggregate values from related records (e.g., sum of order amounts
8519
- * for a company). They are calculated when needed and can be materialized
8520
- * (stored) for performance.
8601
+ * Individual relation validation error
8602
+ */
8603
+ interface RelationValidationError {
8604
+ /** Attribute name */
8605
+ attribute: string;
8606
+ /** Error message */
8607
+ message: string;
8608
+ /** Invalid record IDs */
8609
+ invalidIds?: string[];
8610
+ }
8611
+ /**
8612
+ * Resolved relation option
8521
8613
  *
8522
- * Supports optional caching via CacheAdapter for improved performance.
8523
- * Rollup values have a short TTL (2 minutes) due to high volatility.
8614
+ * SECURITY: This type intentionally excludes raw record data.
8615
+ * Only the computed label is exposed to prevent unauthorized data access
8616
+ * through relation lookups. Users must have explicit read permissions
8617
+ * on an object to access its record data.
8618
+ */
8619
+ interface RelationOption {
8620
+ /** Record ID */
8621
+ id: string;
8622
+ /** Object ID */
8623
+ objectId: string;
8624
+ /** Object name (technical name) */
8625
+ objectName: string;
8626
+ /** Object label (display name) */
8627
+ objectLabel: string;
8628
+ /** Object icon */
8629
+ objectIcon?: string;
8630
+ /** Display label (computed from labelExpression) */
8631
+ label: string;
8632
+ }
8633
+ /**
8634
+ * Response for relation options
8635
+ */
8636
+ interface RelationOptionsResponse {
8637
+ options: RelationOption[];
8638
+ hasMore: boolean;
8639
+ total: number;
8640
+ }
8641
+ /**
8642
+ * Parameters for fetching relation options
8643
+ */
8644
+ interface GetRelationOptionsParams {
8645
+ /** Search query */
8646
+ query?: string;
8647
+ /** Page number (1-based) */
8648
+ page?: number;
8649
+ /** Page size */
8650
+ pageSize?: number;
8651
+ /** Filter by specific target object */
8652
+ targetObject?: string;
8653
+ /** Additional filter to apply (e.g., workflow context filtering) */
8654
+ filter?: FilterState;
8655
+ }
8656
+ /**
8657
+ * Options for RelationService constructor
8658
+ */
8659
+ interface RelationServiceOptions {
8660
+ /**
8661
+ * Record query service for fetching relation options.
8662
+ * Required for getOptions() to work.
8663
+ * If not provided, getOptions() will throw.
8664
+ */
8665
+ queryService?: RecordQueryService;
8666
+ /**
8667
+ * Record resolver for cached record fetching.
8668
+ * Required for cached access to records.
8669
+ */
8670
+ recordResolver: RecordResolverService;
8671
+ }
8672
+ /**
8673
+ * Request item for batch relation resolution
8674
+ */
8675
+ interface ResolveIdsBatchRequest {
8676
+ /** Relation attribute ID */
8677
+ attributeId: string;
8678
+ /** Record IDs to resolve for this attribute */
8679
+ ids: string[];
8680
+ }
8681
+ /**
8682
+ * Response for batch relation resolution
8683
+ * Maps attributeId to resolved options
8684
+ */
8685
+ interface ResolveIdsBatchResponse {
8686
+ [attributeId: string]: RelationOption[];
8687
+ }
8688
+ /**
8689
+ * Service for validating relation attributes.
8690
+ * Ensures referenced records exist and belong to valid target objects.
8691
+ * Automatically uses tenant context from AsyncLocalStorage.
8524
8692
  *
8525
- * Phase 3: Supports single-level relation rollups
8693
+ * Supports optional caching via CacheAdapter for improved performance
8694
+ * on relation options lookups.
8526
8695
  */
8527
- declare class RollupService extends BaseService {
8528
- constructor(adapter: DatabaseAdapter);
8696
+ declare class RelationService extends BaseService {
8697
+ private schemaService;
8698
+ private queryService?;
8699
+ private recordResolver;
8700
+ constructor(adapter: DatabaseAdapter, nativeRegistry: typeof registry, options: RelationServiceOptions);
8529
8701
  /**
8530
- * Calculate a rollup value for a record
8531
- *
8532
- * Results are cached if a CacheAdapter is configured.
8702
+ * Set the query service after construction.
8703
+ * Useful for breaking circular dependencies during initialization.
8704
+ */
8705
+ setQueryService(queryService: RecordQueryService): void;
8706
+ /**
8707
+ * Get the query service, throwing if not configured.
8708
+ */
8709
+ private getQueryServiceOrThrow;
8710
+ /**
8711
+ * Validate all relation attributes in the data
8533
8712
  *
8534
- * @param recordId - ID of the parent record
8535
- * @param rollupAttr - Rollup attribute definition
8536
- * @param schema - Schema of the parent object
8537
- * @returns Computed rollup value
8713
+ * @param schema - Object schema containing attribute definitions
8714
+ * @param data - Record data to validate
8715
+ * @returns Validation result with errors if any
8538
8716
  *
8539
8717
  * @example
8540
8718
  * ```typescript
8541
- * // Sum all order amounts for a company
8542
- * const totalOrders = await rollupService.calculate(
8543
- * "company-123",
8544
- * {
8545
- * type: "rollup",
8546
- * name: "totalOrders",
8547
- * relationAttribute: "orders",
8548
- * targetAttribute: "amount",
8549
- * function: "sum",
8550
- * ...
8551
- * },
8552
- * companySchema
8553
- * );
8719
+ * const result = await relationService.validateRelations(schema, {
8720
+ * company: "rec-123",
8721
+ * contacts: ["rec-456", "rec-789"]
8722
+ * });
8723
+ *
8724
+ * if (!result.valid) {
8725
+ * console.log(result.errors);
8726
+ * // [{ attribute: "company", message: "Record not found", invalidIds: ["rec-123"] }]
8727
+ * }
8554
8728
  * ```
8555
8729
  */
8556
- calculate(recordId: string, rollupAttr: RollupAttribute, schema: ObjectDefinition): Promise<RollupResult>;
8730
+ validateRelations(schema: ObjectDefinition, data: Record<string, unknown>): Promise<RelationValidationResult>;
8557
8731
  /**
8558
- * Internal method to compute rollup value (no caching)
8732
+ * Validate a single relation attribute value
8733
+ *
8734
+ * Uses batch fetching (findByIds) to avoid N+1 query pattern.
8559
8735
  */
8560
- private computeRollup;
8736
+ private validateRelationAttribute;
8561
8737
  /**
8562
- * Forward pattern: this record has a relation attribute pointing to other records
8563
- * Example: entreprise222 has relation "entreprises" → companies, rollup collects from companies
8738
+ * Extract IDs from relation value based on cardinality
8564
8739
  */
8565
- private calculateForward;
8740
+ private extractIds;
8566
8741
  /**
8567
- * Reverse pattern: other records have a relation pointing to this record
8568
- * Example: Company has rollup on "orders", Order has relation "company" → companies
8742
+ * Get valid object IDs from relation targets
8743
+ * Note: Universal relations (toAny) are handled earlier in validateRelationAttribute
8569
8744
  */
8570
- private calculateReverse;
8745
+ private getValidObjectIds;
8571
8746
  /**
8572
- * Extract and aggregate values from related records
8747
+ * Validate relations and throw if invalid
8573
8748
  */
8574
- private aggregateValues;
8749
+ validateRelationsOrThrow(schema: ObjectDefinition, data: Record<string, unknown>): Promise<void>;
8575
8750
  /**
8576
- * Calculate rollup values for multiple records (batched)
8751
+ * Get available options for a relation attribute.
8752
+ * Searches across all target objects defined in the relation.
8753
+ * Automatically uses tenant context from AsyncLocalStorage.
8577
8754
  *
8578
- * More efficient than calling calculate() for each record individually.
8755
+ * @param attribute - Relation attribute definition
8756
+ * @param params - Query parameters
8757
+ *
8758
+ * @example
8759
+ * ```typescript
8760
+ * const options = await relationService.getOptions(attribute, {
8761
+ * query: "nike",
8762
+ * page: 1,
8763
+ * pageSize: 20
8764
+ * });
8765
+ * ```
8579
8766
  */
8580
- calculateForMany(recordIds: string[], rollupAttr: RollupAttribute, schema: ObjectDefinition): Promise<Map<string, RollupResult>>;
8767
+ getOptions(attribute: RelationAttribute, params?: GetRelationOptionsParams): Promise<RelationOptionsResponse>;
8581
8768
  /**
8582
- * Apply aggregation function to a set of values
8769
+ * Internal method to fetch relation options (extracted for caching)
8770
+ */
8771
+ private fetchOptions;
8772
+ /**
8773
+ * Resolve record IDs to their display labels.
8774
+ * Useful for displaying current values in the UI.
8775
+ *
8776
+ * Uses caching per individual record ID for optimal performance.
8777
+ * Cache key format: `${attributeId}:${recordId}` to handle different displayTemplates.
8778
+ *
8779
+ * @param ids - Record IDs to resolve
8780
+ * @param attributeId - Relation attribute ID to use its displayTemplate for label rendering
8781
+ *
8782
+ * @example
8783
+ * ```typescript
8784
+ * const resolved = await relationService.resolveIds(["rec-1", "rec-2"], "attr-123");
8785
+ * // [{ id: "rec-1", label: "Nike Air Max", objectName: "products", ... }]
8786
+ * ```
8787
+ */
8788
+ resolveIds(ids: string[], attributeId: string): Promise<RelationOption[]>;
8789
+ /**
8790
+ * Resolve multiple attribute/IDs batches in a single operation.
8791
+ * Optimized for DataGrid scenarios with multiple relation columns.
8792
+ *
8793
+ * Benefits over multiple resolveIds() calls:
8794
+ * - Single DB query for all records across all attributes
8795
+ * - Deduplication of records referenced by multiple attributes
8796
+ * - Single schema lookup per objectId
8797
+ *
8798
+ * Uses caching per individual record ID for optimal performance.
8799
+ *
8800
+ * @param requests - Array of { attributeId, ids } to resolve
8801
+ * @returns Map of attributeId to resolved options
8802
+ *
8803
+ * @example
8804
+ * ```typescript
8805
+ * const results = await relationService.resolveIdsBatch([
8806
+ * { attributeId: "attr-company", ids: ["rec-1", "rec-2"] },
8807
+ * { attributeId: "attr-contact", ids: ["rec-3", "rec-4"] },
8808
+ * ]);
8809
+ * // { "attr-company": [...], "attr-contact": [...] }
8810
+ * ```
8583
8811
  */
8584
- private aggregate;
8812
+ resolveIdsBatch(requests: ResolveIdsBatchRequest[]): Promise<ResolveIdsBatchResponse>;
8585
8813
  /**
8586
- * Get the default empty value for a rollup function
8814
+ * Internal method to resolve multiple composite IDs at once.
8815
+ * Optimized for batch operations - single DB query for all records.
8816
+ *
8817
+ * @param compositeIds - Array of composite IDs in format "attributeId:recordId"
8587
8818
  */
8588
- private getEmptyValue;
8819
+ private resolveCompositeIds;
8589
8820
  /**
8590
- * Sum numeric values
8821
+ * Resolve the display label for a record.
8822
+ * Uses custom template if provided, otherwise falls back to pre-computed label.
8591
8823
  */
8592
- private sumNumbers;
8824
+ private resolveLabel;
8593
8825
  /**
8594
- * Average numeric values
8826
+ * Find a relation attribute by ID.
8827
+ * Results are cached if a CacheAdapter is configured.
8828
+ * Cache is invalidated by ObjectSchemaService.invalidateSchemaCache() via allAttributes pattern.
8595
8829
  */
8596
- private averageNumbers;
8830
+ findAttributeById(attributeId: string): Promise<RelationAttribute | null>;
8597
8831
  /**
8598
- * Get earliest date from values
8832
+ * Internal method to fetch attribute by ID (no caching)
8599
8833
  */
8600
- private earliestDate;
8834
+ private fetchAttributeById;
8835
+ }
8836
+
8837
+ /**
8838
+ * Resolved relation values for a record
8839
+ * Maps relation attribute name to the resolved record's values
8840
+ */
8841
+ type ResolvedRelations = Record<string, Record<string, unknown>>;
8842
+ /**
8843
+ * Options for FormulaResolverService constructor
8844
+ */
8845
+ interface FormulaResolverServiceOptions {
8601
8846
  /**
8602
- * Get latest date from values
8847
+ * Record resolver for cached record fetching.
8848
+ * Required for cached access to records.
8603
8849
  */
8604
- private latestDate;
8850
+ recordResolver: RecordResolverService;
8851
+ }
8852
+ /**
8853
+ * Service for resolving relation values from related records.
8854
+ *
8855
+ * Used by formula evaluation to access values from related records
8856
+ * (e.g., "company.name" in a formula on an order).
8857
+ *
8858
+ * Supports optional RecordResolverService injection for cached record fetching.
8859
+ *
8860
+ * @example
8861
+ * ```typescript
8862
+ * const resolver = new FormulaResolverService(adapter, { recordResolver });
8863
+ *
8864
+ * // Resolve relation values for formula evaluation
8865
+ * const resolved = await resolver.resolveRelationValues(
8866
+ * orderRecord,
8867
+ * orderSchema,
8868
+ * ["company"]
8869
+ * );
8870
+ * // → { company: { id: "...", name: "Acme Corp", ... } }
8871
+ * ```
8872
+ */
8873
+ declare class FormulaResolverService extends BaseService {
8874
+ private recordResolver;
8875
+ constructor(adapter: DatabaseAdapter, options: FormulaResolverServiceOptions);
8605
8876
  /**
8606
- * Recalculate all rollup attributes for a record and update it
8877
+ * Resolve values from related records for formula evaluation
8607
8878
  *
8608
- * Called after related records change to keep rollups up-to-date.
8609
- */
8610
- recalculateAndUpdate(record: ObjectRecord, schema: ObjectDefinition): Promise<ObjectRecord>;
8611
- /**
8612
- * Find parent records that need rollup recalculation when a child record changes
8879
+ * Supports 1 level of relation traversal only.
8613
8880
  *
8614
- * Used by hooks to determine which parent records to recalculate after
8615
- * a child record is created, updated, or deleted.
8881
+ * @param record - The source record
8882
+ * @param schema - Schema of the source object
8883
+ * @param relationNames - Names of relation attributes to resolve
8884
+ * @returns Map of relation name to related record's values
8616
8885
  *
8617
- * @param changedRecord - The record that was modified
8618
- * @param changedSchema - Schema of the changed record's object
8619
- * @returns Array of parent record IDs that need recalculation
8886
+ * @example
8887
+ * ```typescript
8888
+ * const resolved = await resolver.resolveRelationValues(
8889
+ * orderRecord,
8890
+ * orderSchema,
8891
+ * ["company"]
8892
+ * );
8893
+ * // → { company: { id: "...", name: "Acme Corp", ... } }
8894
+ * ```
8620
8895
  */
8621
- findAffectedParentRecords(changedRecord: ObjectRecord, changedSchema: ObjectDefinition): Promise<string[]>;
8896
+ resolveRelationValues(record: ObjectRecord, schema: ObjectDefinition, relationNames: string[]): Promise<ResolvedRelations>;
8622
8897
  /**
8623
- * Invalidate cached rollups for affected parent records.
8624
- * Call this after a child record is created, updated, or deleted.
8898
+ * Resolve relation values for multiple records (batched)
8625
8899
  *
8626
- * @param affectedParentIds - Array of parent record IDs whose rollups need invalidation
8627
- */
8628
- invalidateAffectedRollups(affectedParentIds: string[]): Promise<void>;
8629
- /**
8630
- * Invalidate all cached rollups for the current tenant.
8631
- * Use sparingly - prefer targeted invalidation.
8900
+ * Optimized for list operations - fetches all related records in one batch
8901
+ *
8902
+ * @param records - Source records
8903
+ * @param schema - Schema of the source object
8904
+ * @param relationNames - Names of relation attributes to resolve
8905
+ * @returns Map of record ID to resolved relations
8632
8906
  */
8633
- invalidateAllRollups(): Promise<void>;
8907
+ resolveRelationValuesForMany(records: ObjectRecord[], schema: ObjectDefinition, relationNames: string[]): Promise<Map<string, ResolvedRelations>>;
8634
8908
  /**
8635
- * Find records that have forward rollups pointing to the modified record.
8636
- *
8637
- * Forward rollups are rollups where the record has a relation attribute
8638
- * pointing to another object, and the rollup aggregates values from that target.
8639
- * When the target record changes, we need to recalculate these rollups.
8909
+ * Flatten resolved relations for formula evaluation
8640
8910
  *
8641
- * Example: Order has relation "company" → Company, and rollup "capitalSocial"
8642
- * aggregating from the Company. When Company.capitalSocial changes,
8643
- * all Orders pointing to that Company need their rollup recalculated.
8911
+ * Converts nested structure to dot-notation keys:
8912
+ * { company: { name: "Acme" } } → { "company.name": "Acme" }
8644
8913
  *
8645
- * @param changedRecord - The record that was modified
8646
- * @param changedSchema - Schema of the changed record's object
8647
- * @returns Array of records that need their forward rollups recalculated
8914
+ * @param resolved - Resolved relations from resolveRelationValues
8915
+ * @returns Flattened values suitable for formula evaluation
8648
8916
  */
8649
- findRecordsWithForwardRollup(changedRecord: ObjectRecord, changedSchema: ObjectDefinition): Promise<ObjectRecord[]>;
8917
+ flattenResolvedRelations(resolved: ResolvedRelations): Record<string, unknown>;
8918
+ /**
8919
+ * Extract a single relation ID from a value
8920
+ * Handles both single (string) and multi (array) relations
8921
+ */
8922
+ private extractSingleId;
8650
8923
  }
8651
8924
 
8652
8925
  /**
@@ -8657,6 +8930,8 @@ interface RollupSchedulerOptions {
8657
8930
  debounceMs?: number;
8658
8931
  /** Maximum pending recalculations before forced flush (default: 100) */
8659
8932
  maxPending?: number;
8933
+ /** Record resolver for cached record fetching (required) */
8934
+ recordResolver: RecordResolverService;
8660
8935
  }
8661
8936
  /**
8662
8937
  * Scheduler for debouncing rollup recalculations
@@ -8666,7 +8941,8 @@ interface RollupSchedulerOptions {
8666
8941
  *
8667
8942
  * @example
8668
8943
  * ```typescript
8669
- * const scheduler = new RollupScheduler(adapter, {
8944
+ * const scheduler = new RollupScheduler(adapter, getSchemaById, {
8945
+ * recordResolver,
8670
8946
  * debounceMs: 100,
8671
8947
  * maxPending: 50,
8672
8948
  * });
@@ -8686,7 +8962,7 @@ declare class RollupScheduler {
8686
8962
  private rollupService;
8687
8963
  private debounceMs;
8688
8964
  private maxPending;
8689
- constructor(adapter: DatabaseAdapter, getSchemaById: (id: string) => Promise<ObjectDefinition | null>, options?: RollupSchedulerOptions);
8965
+ constructor(adapter: DatabaseAdapter, getSchemaById: (id: string) => Promise<ObjectDefinition | null>, options: RollupSchedulerOptions);
8690
8966
  /**
8691
8967
  * Schedule a rollup recalculation for a parent record.
8692
8968
  *
@@ -8755,32 +9031,6 @@ declare function checkRecordModifyOrThrow(policy: RecordPolicy, record: ObjectRe
8755
9031
  */
8756
9032
  declare function checkRecordDeleteOrThrow(policy: RecordPolicy, record: ObjectRecord, context: PolicyContext): void;
8757
9033
 
8758
- /**
8759
- * Interface for resolving relation labels.
8760
- * Allows dependency injection for testing and decoupling.
8761
- */
8762
- interface LabelResolver {
8763
- resolveRelationIds(ids: string[], attributeId: string): Promise<Array<{
8764
- id: string;
8765
- label: string;
8766
- }>>;
8767
- findRecordLabels(ids: string[]): Promise<Array<{
8768
- id: string;
8769
- label?: string;
8770
- }>>;
8771
- }
8772
- /**
8773
- * Compute display label from schema expression.
8774
- * Automatically resolves relation attribute values to their labels
8775
- * and select/multiselect values to their option labels.
8776
- *
8777
- * @param schema - Object schema with labelExpression
8778
- * @param values - Record values
8779
- * @param resolver - Resolver for relation labels
8780
- * @returns Computed label string
8781
- */
8782
- declare function computeLabel(schema: ObjectDefinition, values: Record<string, unknown>, resolver: LabelResolver): Promise<string>;
8783
-
8784
9034
  /**
8785
9035
  * Enrich a record with computed formula values.
8786
9036
  *
@@ -8818,32 +9068,6 @@ declare function createContextForDelete(schema: ObjectDefinition, tenantId: stri
8818
9068
  */
8819
9069
  declare function createContextForRestore(schema: ObjectDefinition, tenantId: string, record: ObjectRecord, metadata?: Record<string, unknown>): HookContext;
8820
9070
 
8821
- /**
8822
- * Context for rollup cascade operations.
8823
- * Provides the necessary services via dependency injection.
8824
- */
8825
- interface RollupCascadeContext {
8826
- rollupService: RollupService;
8827
- schemaService: ObjectSchemaService;
8828
- findRecordsByIds: (ids: string[]) => Promise<ObjectRecord[]>;
8829
- }
8830
- /**
8831
- * Recalculate rollups after a record changes.
8832
- *
8833
- * This handles three cases:
8834
- * 1. The record itself has rollups (e.g., aggregating from related records it points to)
8835
- * 2. Parent records have rollups that aggregate from this record (reverse pattern)
8836
- * 3. Records that have forward rollups pointing to this record (forward pattern)
8837
- *
8838
- * Optimized: Pre-loads schemas by objectId to avoid N redundant calls
8839
- * when multiple records share the same objectId.
8840
- *
8841
- * @param record - The record that was modified
8842
- * @param schema - Schema of the record's object
8843
- * @param ctx - Context with required services
8844
- */
8845
- declare function recalculateParentRollups(record: ObjectRecord, schema: ObjectDefinition, ctx: RollupCascadeContext): Promise<void>;
8846
-
8847
9071
  /**
8848
9072
  * Fluent query builder for schema records.
8849
9073
  * Supports chained filters, sorts, and pagination.
@@ -9861,7 +10085,7 @@ declare function flattenRelationsForEval(resolvedRelations: ResolvedRelations):
9861
10085
  * // → "Acme Corp - ORD-001"
9862
10086
  * ```
9863
10087
  */
9864
- declare function evaluateFormulaWithRelations(expression: string, record: ObjectRecord, schema: ObjectDefinition, resolver: RelationResolverService): Promise<unknown>;
10088
+ declare function evaluateFormulaWithRelations(expression: string, record: ObjectRecord, schema: ObjectDefinition, resolver: FormulaResolverService): Promise<unknown>;
9865
10089
  /**
9866
10090
  * Evaluate a formula attribute that may contain relation references
9867
10091
  *
@@ -9871,7 +10095,7 @@ declare function evaluateFormulaWithRelations(expression: string, record: Object
9871
10095
  * @param resolver - Relation resolver service
9872
10096
  * @returns Formatted computed value
9873
10097
  */
9874
- declare function evaluateFormulaAttributeWithRelations(attr: FormulaAttribute, record: ObjectRecord, schema: ObjectDefinition, resolver: RelationResolverService): Promise<unknown>;
10098
+ declare function evaluateFormulaAttributeWithRelations(attr: FormulaAttribute, record: ObjectRecord, schema: ObjectDefinition, resolver: FormulaResolverService): Promise<unknown>;
9875
10099
 
9876
10100
  /**
9877
10101
  * Type of a path segment
@@ -11484,98 +11708,4 @@ interface FullSyncOptions extends SyncOptions, ViewSyncOptions {
11484
11708
  */
11485
11709
  declare function syncAll(adapter: DatabaseAdapter, objectRegistry: typeof registry, nativeViewRegistry: typeof viewRegistry, options?: FullSyncOptions): Promise<FullSyncResult>;
11486
11710
 
11487
- /**
11488
- * Default fallback value when expression resolves to empty string
11489
- */
11490
- declare const DEFAULT_LABEL_FALLBACK = "(Untitled)";
11491
- declare function renderLabelExpression(template: string, values: Record<string, unknown>, fallback?: string): string;
11492
- /**
11493
- * Check if a string is a valid label expression template
11494
- * A valid template contains at least one {{ variable }} block with a non-empty variable
11495
- */
11496
- declare function isLabelExpression(value: string): boolean;
11497
- /**
11498
- * Extract attribute names referenced in a label expression
11499
- * Useful for validation or dependency tracking
11500
- *
11501
- * @example
11502
- * extractAttributeNames("{{ firstName }} {{ lastName | UPPER }}")
11503
- * // → ["firstName", "lastName"]
11504
- */
11505
- declare function extractAttributeNames(template: string): string[];
11506
- /**
11507
- * Enrich record values by formatting complex types for display
11508
- *
11509
- * Transforms raw values (objects, dates, etc.) into human-readable strings
11510
- * for use in label expression rendering. Uses formatAttributeValue internally.
11511
- *
11512
- * @param values - Record values containing raw attribute values
11513
- * @param attributes - Attribute definitions for formatting
11514
- * @returns New object with complex values formatted as strings
11515
- *
11516
- * @example
11517
- * ```typescript
11518
- * const enriched = enrichValuesForDisplay(
11519
- * { status: "active", price: { value: 1500, code: "EUR" } },
11520
- * [
11521
- * { type: "select", name: "status", options: [{ value: "active", label: "Active" }] },
11522
- * { type: "currency", name: "price" }
11523
- * ]
11524
- * );
11525
- * // → { status: "Active", price: "1,500.00 EUR" }
11526
- * ```
11527
- */
11528
- declare function enrichValuesForDisplay(values: Record<string, unknown>, attributes: Attribute[]): Record<string, unknown>;
11529
- /**
11530
- * @deprecated Use `enrichValuesForDisplay` instead
11531
- */
11532
- declare const enrichValuesWithSelectLabels: typeof enrichValuesForDisplay;
11533
- /**
11534
- * Extract relation IDs from a value (string or array)
11535
- * For cardinality "many", only the first ID is extracted for label display
11536
- *
11537
- * @param val - Relation value (string ID or array of IDs)
11538
- * @returns Array of IDs (max 1 element for display purposes)
11539
- *
11540
- * @example
11541
- * ```typescript
11542
- * extractRelationIds("rec-123") // → ["rec-123"]
11543
- * extractRelationIds(["rec-1", "rec-2"]) // → ["rec-1"]
11544
- * extractRelationIds(null) // → []
11545
- * ```
11546
- */
11547
- declare function extractRelationIds(val: unknown): string[];
11548
- /**
11549
- * Resolver function type for fetching relation labels
11550
- * Takes an array of record IDs and returns a map of ID → label
11551
- */
11552
- type RelationLabelResolver = (ids: string[]) => Promise<Map<string, string>>;
11553
- /**
11554
- * Compute a label from a template with full relation resolution (1 level deep)
11555
- *
11556
- * Uses pre-computed record.label for nested relations to avoid infinite recursion.
11557
- * This function enriches select/multiselect values AND resolves relation IDs to their labels.
11558
- *
11559
- * @param template - Label expression template (e.g., "{{ company }} - {{ name }}")
11560
- * @param values - Record values to interpolate
11561
- * @param attributes - Attribute definitions for the object
11562
- * @param resolveRelationIds - Function to resolve record IDs to their labels
11563
- * @returns The rendered label string
11564
- *
11565
- * @example
11566
- * ```typescript
11567
- * const label = await computeLabelWithRelations(
11568
- * "{{ company }} - {{ name }}",
11569
- * { company: "rec-123", name: "Product A" },
11570
- * objectSchema.attributes,
11571
- * async (ids) => {
11572
- * const records = await adapter.objectRecords.findByIds(ids);
11573
- * return new Map(records.map(r => [r.id, r.label]));
11574
- * }
11575
- * );
11576
- * // → "Acme Corp - Product A"
11577
- * ```
11578
- */
11579
- declare function computeLabelWithRelations(template: string, values: Record<string, unknown>, attributes: Attribute[], resolveRelationIds: RelationLabelResolver): Promise<string>;
11580
-
11581
- export { type FlowRow as $, type Attribute as A, type DirectTableTab as B, type CheckboxAttribute as C, type DateAttribute as D, type WorkflowConfig as E, type FileAttribute as F, type Group as G, type SlotMode as H, type InferAttributeValue as I, type AuthMethod as J, type AuthChannel as K, type LocationAttribute as L, type MultiselectAttribute as M, type NumberAttribute as N, type ObjectAction as O, type PhoneAttribute as P, type ParticipantTemplate as Q, type RichtextAttribute as R, type SystemResource as S, type TextAttribute as T, type UserAttribute as U, type ViewLayout as V, type WorkflowTheme as W, type ConditionGroup as X, type ConditionRule as Y, type WorkflowNode as Z, type WorkflowDefinition as _, type SystemAction as a, type AuditServiceOptions as a$, type BlockNoteContent as a0, type AIMessageRole as a1, type AIThinkingLevel as a2, type AIToolCallStatus as a3, type AIToolCall as a4, type AIChatMessagePartType as a5, type TextPartData as a6, type ToolPartData as a7, type ThinkingPartData as a8, type ReasoningPartData as a9, RELATION_TARGET_ANY as aA, type RelationAttribute as aB, isUniversalRelation as aC, type BlockNoteBlock as aD, type BlockNoteCustomInlineContent as aE, type BlockNoteDefaultProps as aF, type BlockNoteInlineContent as aG, type BlockNoteLink as aH, type BlockNoteStyledText as aI, type BlockNoteStyles as aJ, type BlockNoteTableCell as aK, type BlockNoteTableCellProps as aL, type BlockNoteTableContent as aM, type PartialBlockNoteBlock as aN, type PartialBlockNoteContent as aO, type PartialBlockNoteInlineContent as aP, type PartialBlockNoteLink as aQ, type PartialBlockNoteStyledText as aR, type PartialBlockNoteTableCell as aS, type PartialBlockNoteTableContent as aT, type AuditResourceType as aU, type AuditAction as aV, type AuditActorType as aW, type AuditChange as aX, type AuditLogEntry as aY, type CreateAuditLogInput as aZ, type AuditListOptions as a_, type AIChatMessagePart as aa, type AIChatMessage as ab, type AIQuestionType as ac, type AIQuestionOption as ad, type AIQuestion as ae, type AIQuestionAnswer as af, type AITodoStatus as ag, type AITodoItem as ah, type AITodoList as ai, type AIConversation as aj, type AIMessage as ak, type AIToolCallRecord as al, type AIUserMemory as am, type AIUsageMetrics as an, type AIProviderMetrics as ao, type CreateAIMessageInput as ap, type StatusGroup as aq, type AttributeGroup as ar, type BaseAttribute as as, type NumberUnit as at, type DateFormat as au, type DateValue as av, type Phone as aw, type Currency as ax, type Location as ay, type LocationGranularity as az, type TextAreaAttribute as b, type ExtractRecordUpdate as b$, type StorageProvider as b0, type FileVisibility as b1, type File as b2, type CreateFile as b3, type UpdateFile as b4, type TextFilterOperator as b5, type NumberFilterOperator as b6, type CheckboxFilterOperator as b7, type DateFilterOperator as b8, type SelectFilterOperator as b9, type FlowDefinition as bA, isFlowDefinition as bB, isFlowPublished as bC, isSystemFlow as bD, type GeocodingSuggestion as bE, type GeocodingAutocompleteParams as bF, type ReverseGeocodingParams as bG, type GeocodingParams as bH, type GeocodingAdapter as bI, NoopGeocodingAdapter as bJ, type AttributeSchema as bK, type InferRecordFromSchema as bL, type InferRecordWithRequirements as bM, type TypedAttribute as bN, type AttributeMap as bO, type AddAttribute as bP, type InferRecord as bQ, type InferRecordInput as bR, type InferRecordUpdate as bS, type CustomAttributeValue as bT, type WithCustomAttributes as bU, type RecordMetadata as bV, type SystemFields as bW, type ExtractRecord as bX, type ExtractRecordStrict as bY, type ExtractRecordInput as bZ, type ExtractRecordInputStrict as b_, type MultiselectFilterOperator as ba, type RelationFilterOperator as bb, type FilterOperator as bc, type RelativeDateValue as bd, type CurrencyFilterValue as be, type PhoneFilterValue as bf, type FilterValue as bg, type FilterRule as bh, type ExtendedFilterRule as bi, type FilterCombinator as bj, type FilterGroup as bk, type AdvancedFilterState as bl, isAdvancedFilterState as bm, toAdvancedFilterState as bn, toSimpleFilterState as bo, type SortDirection as bp, type QueryState as bq, OPERATORS_BY_TYPE as br, type NoValueOperator as bs, NO_VALUE_OPERATORS as bt, isNoValueOperator as bu, type FlowSlot as bv, type FlowRowField as bw, type FlowPage as bx, type FlowRelation as by, type FlowStatus as bz, type RichtextFeature as c, eq as c$, type ExtractRecordUpdateStrict as c0, type ExtractAttributes as c1, type TypedObjectRecord as c2, type ExtractObjectRecord as c3, type ExtractObjectRecordWithCustom as c4, RESERVED_ATTRIBUTE_NAMES as c5, SYSTEM_FIELD_NAMES as c6, type ReservedAttributeName as c7, type SystemFieldName as c8, type Timestamps as c9, type ActivityTab as cA, type NotesTab as cB, type FlowsTab as cC, isFormTab as cD, isTableTab as cE, isDirectTableTab as cF, isInverseTableTab as cG, isCustomTab as cH, isActivityTab as cI, isNotesTab as cJ, isFlowsTab as cK, type StartNode as cL, type FormNode as cM, type FormFieldRef as cN, type ConditionNode as cO, type EndNode as cP, type WorkflowNodeType as cQ, isStartNode as cR, isFormNode as cS, isConditionNode as cT, isEndNode as cU, isSimpleFormNode as cV, isAdvancedFormNode as cW, getNodeOutputs as cX, type ConditionOperator as cY, isConditionRule as cZ, isConditionGroup as c_, type ObjectAttribute as ca, type CompletionStatus as cb, type ObjectRecord as cc, type PermissionScope as cd, type Role as ce, type Permission as cf, type UserRoleAssignment as cg, type EffectivePermissions as ch, type ObjectPermissions as ci, type SystemPermissions as cj, type CreateRoleInput as ck, type UpdateRoleInput as cl, type CreatePermissionInput as cm, type AssignRoleInput as cn, type PolicyContext as co, type RecordPolicy as cp, PolicyViolationError as cq, type UserRole as cr, type UserStatus as cs, type UserProfile as ct, type CreateUserProfile as cu, type UpdateUserProfile as cv, type InviteUserInput as cw, type TabType as cx, type FormTab as cy, type CustomTab as cz, type CurrencyAttribute as d, textConfigSchema as d$, neq as d0, and as d1, or as d2, inValues as d3, isEmpty as d4, isNotEmpty as d5, type WorkflowSlot as d6, type NodePosition as d7, type CanvasViewport as d8, type WorkflowLayout as d9, createEmptyContext as dA, getContextValue as dB, setContextValue as dC, mergeFormToSlot as dD, type WorkflowAccessMode as dE, type ReadOnlyReason as dF, type FormFieldContext as dG, type FormFieldRow as dH, type FormNodeInfo as dI, type FormContextResponse as dJ, type ThemeLogo as dK, type ThemeColors as dL, type ThemeTypography as dM, DEFAULT_THEME as dN, mergeWithDefaults as dO, generateCssVariables as dP, type Uuid as dQ, type TenantId as dR, type UserId as dS, asTenantId as dT, asUserId as dU, generateId as dV, generatePrefixedId as dW, registry as dX, viewRegistry as dY, type ValidationMessages as dZ, DEFAULT_VALIDATION_MESSAGES as d_, type ParticipantAuthConfig as da, type WorkflowStatus as db, isWorkflowDefinition as dc, isWorkflowPublished as dd, isSystemWorkflow as de, type WorkflowTransition as df, type WorkflowError as dg, type PendingAction as dh, type WorkflowInstance as di, isInstanceTerminal as dj, isInstanceWaiting as dk, canResumeInstance as dl, createStartTransition as dm, type ParticipationStatus as dn, type SignedLinkAuth as dp, type PinCodeAuth as dq, type ParticipationAuth as dr, type WorkflowParticipation as ds, isSignedLinkAuth as dt, isPinCodeAuth as du, canParticipate as dv, canAuthenticate as dw, canExecuteNode as dx, type GeneratedDocument as dy, type WorkflowExecutionContext as dz, type Option as e, getDefaultPinCodeService as e$, textareaConfigSchema as e0, richtextConfigSchema as e1, numberConfigSchema as e2, checkboxConfigSchema as e3, dateConfigSchema as e4, phoneConfigSchema as e5, currencyConfigSchema as e6, statusConfigSchema as e7, locationConfigSchema as e8, selectConfigSchema as e9, createRelationValidator as eA, createRatingValidator as eB, createFormulaValidator as eC, createRollupValidator as eD, createTextAreaValidator as eE, createRichtextValidator as eF, createAttributeValidator as eG, createFormAttributeValidator as eH, createObjectValidator as eI, type ValidationResult as eJ, validateAttribute as eK, validateObject as eL, validateObjectOrThrow as eM, createDraftValidator as eN, validateDraft as eO, validateDraftOrThrow as eP, getMissingRequiredAttributes as eQ, isRecordComplete as eR, computeRecordStatus as eS, type DatabaseAdapter as eT, ParticipationTokenService as eU, getDefaultTokenService as eV, initializeTokenService as eW, type ParticipationTokenPayload as eX, type TokenGenerationOptions as eY, type TokenVerificationResult as eZ, PinCodeService as e_, multiselectConfigSchema as ea, fileConfigSchema as eb, userConfigSchema as ec, relationConfigSchema as ed, ratingConfigSchema as ee, formulaConfigSchema as ef, rollupConfigSchema as eg, attributeConfigSchemas as eh, getAttributeConfigSchema as ei, validateAttributeConfig as ej, parseAttributeConfig as ek, safeParseAttributeConfig as el, createTextValidator as em, createNumberValidator as en, createCheckboxValidator as eo, createDateValidator as ep, createPhoneValidator as eq, createCurrencyValidator as er, createStatusValidator as es, createSelectValidator as et, createMultiselectValidator as eu, createLocationValidator as ev, createFileValidator as ew, createUserValidator as ex, createSingleRelationValidator as ey, createMultiRelationValidator as ez, type StatusAttribute as f, ConditionExecutor as f$, initializePinCodeService as f0, type PinCodeGenerationOptions as f1, type PinCodeVerificationResult as f2, type CacheKeyType as f3, hashOptions as f4, type CacheAdapter as f5, type CacheOptions as f6, cacheKeys as f7, cacheTtl as f8, defaultTtl as f9, getSchemaContext as fA, getSchemaFromContext as fB, hasSchemaContext as fC, runWithMergedSchemaContext as fD, runWithSchemaContext as fE, type SchemaContext as fF, getContext as fG, getTenantId as fH, getUserId as fI, hasContext as fJ, runWithContext as fK, withTenantContext as fL, type TenantContext as fM, createDefaultExecutorRegistry as fN, getDefaultExecutorRegistry as fO, type ExecutorCompleteResult as fP, type ExecutorContext as fQ, type ExecutorErrorResult as fR, type ExecutorResult as fS, type ExecutorSuccessResult as fT, type ExecutorWaitResult as fU, type NodeExecutor as fV, complete as fW, error as fX, ExecutorRegistry as fY, success as fZ, wait as f_, NoopCacheAdapter as fa, type FetchResult as fb, type FormattedRecord as fc, type GroupedFetchResult as fd, type InsertOptions as fe, type QueryBuilderState as ff, type RegistryMap as fg, type RegistryObjectNames as fh, type ShortcutOperator as fi, createDefaultState as fj, formatRecord as fk, formatRecords as fl, QueryMultipleResultsError as fm, QueryNoResultError as fn, SHORTCUT_TO_FILTER_OPERATOR as fo, createQueryBuilder as fp, QueryBuilder as fq, type QueryBuilderOptions as fr, type EvaluationResult as fs, type EvaluationTrace as ft, evaluateCondition as fu, evaluate as fv, evaluateWithTrace as fw, TenantContextError as fx, addSchemaToContext as fy, getSchemaByNameFromContext as fz, type SelectAttribute as g, TenantAwareService as g$, EndExecutor as g0, FormExecutor as g1, StartExecutor as g2, evaluateFormula as g3, evaluateFormulaAttribute as g4, evaluateFormulaAttributeWithRelations as g5, evaluateFormulaWithRelations as g6, evaluateFormulaWithResult as g7, extractFormulaVariables as g8, extractRelationNames as g9, type HookHandler as gA, type HookType as gB, NoopHookRegistry as gC, type HookRegistry as gD, createMockAdapter as gE, defaultPolicyRegistry as gF, PolicyRegistry as gG, notesPolicy as gH, type ObjectsRepository as gI, type AttributesRepository as gJ, type UserProfilesRepository as gK, type FilesRepository as gL, type ObjectRecordsRepository as gM, type ViewsRepository as gN, type WorkflowsRepository as gO, type WorkflowInstancesRepository as gP, type WorkflowParticipationsRepository as gQ, type AuditRepository as gR, type PermissionsRepository as gS, type AIConversationsRepository as gT, type AIUserMemoryRepository as gU, type AIUsageMetricsRepository as gV, BaseService as gW, BaseRepository as gX, type SchemaContextAware as gY, SchemaContextAwareRepository as gZ, TenantAwareRepository as g_, extractRelationReferences as ga, flattenRelationsForEval as gb, formatFormulaResult as gc, hasRelationReferences as gd, validateFormulaExpression as ge, type FormulaResult as gf, getPathDepth as gg, getRelationPath as gh, getTargetAttributeName as gi, InvalidPathError as gj, MaxDepthExceededError as gk, parsePath as gl, pathHasManyCardinality as gm, validatePath as gn, type PathCardinality as go, type PathSegment as gp, type PathSegmentType as gq, type SchemaResolver as gr, resolveMultiplePaths as gs, resolveSingleValue as gt, traversePath as gu, type TraversalOptions as gv, type TraversalResult as gw, type AttributeChange as gx, type HookContext as gy, type HookDefinition as gz, type SingleRelationAttribute as h, AuditService as h$, type CreateCustomObjectInput as h0, type AddAttributeInput as h1, type UpdateObjectInput as h2, type ObjectSchemaServiceOptions as h3, ObjectSchemaService as h4, type RecordServiceOptions as h5, RecordService as h6, type RecordQueryServiceOptions as h7, type QueryOptions as h8, type SearchQueryOptions as h9, enrichWithFormulas as hA, enrichRecordsWithFormulas as hB, createContextForCreate as hC, createContextForUpdate as hD, createContextForDelete as hE, createContextForRestore as hF, recalculateParentRollups as hG, type RollupCascadeContext as hH, type CreateWorkflowInput as hI, type UpdateWorkflowInput as hJ, type WorkflowServiceOptions as hK, WorkflowService as hL, type StartWorkflowInput as hM, type ResumeWorkflowInput as hN, type WorkflowInstanceServiceOptions as hO, WorkflowInstanceService as hP, type CreateParticipationInput as hQ, type CreateParticipationResult as hR, type AuthenticationResult as hS, WorkflowParticipationService as hT, type FieldReadOnlyResult as hU, WorkflowRelationService as hV, type UserValidationResult as hW, type UserValidationError as hX, UserService as hY, type UserProfileServiceOptions as hZ, UserProfileService as h_, type QueryResult as ha, RecordQueryService as hb, type RelationValidationResult as hc, type RelationValidationError as hd, type RelationOption as he, type RelationOptionsResponse as hf, type GetRelationOptionsParams as hg, type RelationServiceOptions as hh, type ResolveIdsBatchRequest as hi, type ResolveIdsBatchResponse as hj, RelationService as hk, type ResolvedRelations as hl, RelationResolverService as hm, type RollupResult as hn, RollupService as ho, type RollupSchedulerOptions as hp, RollupScheduler as hq, applyDefaultValues as hr, checkPermission as hs, getPolicy as ht, buildPolicyContext as hu, checkRecordAccess as hv, checkRecordModifyOrThrow as hw, checkRecordDeleteOrThrow as hx, computeLabel as hy, type LabelResolver as hz, type MultiRelationAttribute as i, type ViewSyncResult as i$, buildAuditChanges as i0, type FileServiceOptions as i1, FileService as i2, GeocodingService as i3, GlobalSearchService as i4, type PermissionServiceOptions as i5, PermissionService as i6, type CreateViewInput as i7, type UpdateViewInput as i8, ViewService as i9, type CreateDBObject as iA, type UpdateDBObject as iB, type UpsertDBObject as iC, type DBAttribute as iD, type CreateDBAttribute as iE, type UpdateDBAttribute as iF, type UpsertDBAttribute as iG, type CreateObjectRecord as iH, type ListOptions as iI, type SearchOptions as iJ, type GlobalSearchOptions as iK, type GlobalSearchResultItem as iL, type FileListOptions as iM, type DBView as iN, type CreateDBView as iO, type UpdateDBView as iP, type UpsertDBView as iQ, type DBWorkflow as iR, type CreateDBWorkflow as iS, type UpdateDBWorkflow as iT, type DBWorkflowInstance as iU, type CreateDBWorkflowInstance as iV, type UpdateDBWorkflowInstance as iW, type DBWorkflowParticipation as iX, type CreateDBWorkflowParticipation as iY, type UpdateDBWorkflowParticipation as iZ, type OperationResult as i_, type FileContent as ia, type StorageUploadInput as ib, type StorageUploadResult as ic, type SignedUrlOptions as id, type StorageAdapter as ie, type UploadFileInput as ig, type SyncResult as ih, type SyncOptions as ii, syncNativeObjects as ij, verifyNativeObjectsSync as ik, getSyncPreview as il, type FullSyncResult as im, type FullSyncOptions as io, syncAll as ip, DEFAULT_LABEL_FALLBACK as iq, renderLabelExpression as ir, isLabelExpression as is, extractAttributeNames as it, enrichValuesForDisplay as iu, enrichValuesWithSelectLabels as iv, extractRelationIds as iw, type RelationLabelResolver as ix, computeLabelWithRelations as iy, type DBObject as iz, type RelationTarget as j, type ViewSyncOptions as j0, syncNativeViews as j1, verifyNativeViewsSync as j2, getViewSyncPreview as j3, type RatingAttribute as k, type FormulaAttribute as l, type FormulaReturnType as m, type RollupAttribute as n, type RollupFunction as o, type AttributeType as p, type ObjectDefinition as q, type Field as r, type AttributeGroupField as s, type TableTab as t, type InverseTableTab as u, type ViewDefinition as v, type InstanceStatus as w, type Tab as x, type FilterState as y, type SortRule as z };
11711
+ export { type FlowRow as $, type Attribute as A, type DirectTableTab as B, type CheckboxAttribute as C, type DateAttribute as D, type WorkflowConfig as E, type FileAttribute as F, type Group as G, type SlotMode as H, type InferAttributeValue as I, type AuthMethod as J, type AuthChannel as K, type LocationAttribute as L, type MultiselectAttribute as M, type NumberAttribute as N, type ObjectAction as O, type PhoneAttribute as P, type ParticipantTemplate as Q, type RichtextAttribute as R, type SystemResource as S, type TextAttribute as T, type UserAttribute as U, type ViewLayout as V, type WorkflowTheme as W, type ConditionGroup as X, type ConditionRule as Y, type WorkflowNode as Z, type WorkflowDefinition as _, type SystemAction as a, type AuditListOptions as a$, type BlockNoteContent as a0, type AIMessageRole as a1, type AIThinkingLevel as a2, type AIToolCallStatus as a3, type AIToolCall as a4, type AIChatMessagePartType as a5, type TextPartData as a6, type ToolPartData as a7, type ThinkingPartData as a8, type ReasoningPartData as a9, type LocationGranularity as aA, RELATION_TARGET_ANY as aB, type RelationAttribute as aC, isUniversalRelation as aD, type BlockNoteBlock as aE, type BlockNoteCustomInlineContent as aF, type BlockNoteDefaultProps as aG, type BlockNoteInlineContent as aH, type BlockNoteLink as aI, type BlockNoteStyledText as aJ, type BlockNoteStyles as aK, type BlockNoteTableCell as aL, type BlockNoteTableCellProps as aM, type BlockNoteTableContent as aN, type PartialBlockNoteBlock as aO, type PartialBlockNoteContent as aP, type PartialBlockNoteInlineContent as aQ, type PartialBlockNoteLink as aR, type PartialBlockNoteStyledText as aS, type PartialBlockNoteTableCell as aT, type PartialBlockNoteTableContent as aU, type AuditResourceType as aV, type AuditAction as aW, type AuditActorType as aX, type AuditChange as aY, type AuditLogEntry as aZ, type CreateAuditLogInput as a_, type AIChatMessagePart as aa, type AIChatMessage as ab, type AIQuestionType as ac, type AIQuestionOption as ad, type AIQuestion as ae, type AIQuestionAnswer as af, type AITodoStatus as ag, type AITodoItem as ah, type AITodoList as ai, type AIMessageAttachment as aj, type AIConversation as ak, type AIMessage as al, type AIToolCallRecord as am, type AIUserMemory as an, type AIUsageMetrics as ao, type AIProviderMetrics as ap, type CreateAIMessageInput as aq, type StatusGroup as ar, type AttributeGroup as as, type BaseAttribute as at, type NumberUnit as au, type DateFormat as av, type DateValue as aw, type Phone as ax, type Currency as ay, type Location as az, type TextAreaAttribute as b, type ExtractRecordInputStrict as b$, type AuditServiceOptions as b0, type StorageProvider as b1, type FileVisibility as b2, type File as b3, type CreateFile as b4, type UpdateFile as b5, type TextFilterOperator as b6, type NumberFilterOperator as b7, type CheckboxFilterOperator as b8, type DateFilterOperator as b9, type FlowStatus as bA, type FlowDefinition as bB, isFlowDefinition as bC, isFlowPublished as bD, isSystemFlow as bE, type GeocodingSuggestion as bF, type GeocodingAutocompleteParams as bG, type ReverseGeocodingParams as bH, type GeocodingParams as bI, type GeocodingAdapter as bJ, NoopGeocodingAdapter as bK, type AttributeSchema as bL, type InferRecordFromSchema as bM, type InferRecordWithRequirements as bN, type TypedAttribute as bO, type AttributeMap as bP, type AddAttribute as bQ, type InferRecord as bR, type InferRecordInput as bS, type InferRecordUpdate as bT, type CustomAttributeValue as bU, type WithCustomAttributes as bV, type RecordMetadata as bW, type SystemFields as bX, type ExtractRecord as bY, type ExtractRecordStrict as bZ, type ExtractRecordInput as b_, type SelectFilterOperator as ba, type MultiselectFilterOperator as bb, type RelationFilterOperator as bc, type FilterOperator as bd, type RelativeDateValue as be, type CurrencyFilterValue as bf, type PhoneFilterValue as bg, type FilterValue as bh, type FilterRule as bi, type ExtendedFilterRule as bj, type FilterCombinator as bk, type FilterGroup as bl, type AdvancedFilterState as bm, isAdvancedFilterState as bn, toAdvancedFilterState as bo, toSimpleFilterState as bp, type SortDirection as bq, type QueryState as br, OPERATORS_BY_TYPE as bs, type NoValueOperator as bt, NO_VALUE_OPERATORS as bu, isNoValueOperator as bv, type FlowSlot as bw, type FlowRowField as bx, type FlowPage as by, type FlowRelation as bz, type RichtextFeature as c, isConditionGroup as c$, type ExtractRecordUpdate as c0, type ExtractRecordUpdateStrict as c1, type ExtractAttributes as c2, type TypedObjectRecord as c3, type ExtractObjectRecord as c4, type ExtractObjectRecordWithCustom as c5, RESERVED_ATTRIBUTE_NAMES as c6, SYSTEM_FIELD_NAMES as c7, type ReservedAttributeName as c8, type SystemFieldName as c9, type CustomTab as cA, type ActivityTab as cB, type NotesTab as cC, type FlowsTab as cD, isFormTab as cE, isTableTab as cF, isDirectTableTab as cG, isInverseTableTab as cH, isCustomTab as cI, isActivityTab as cJ, isNotesTab as cK, isFlowsTab as cL, type StartNode as cM, type FormNode as cN, type FormFieldRef as cO, type ConditionNode as cP, type EndNode as cQ, type WorkflowNodeType as cR, isStartNode as cS, isFormNode as cT, isConditionNode as cU, isEndNode as cV, isSimpleFormNode as cW, isAdvancedFormNode as cX, getNodeOutputs as cY, type ConditionOperator as cZ, isConditionRule as c_, type Timestamps as ca, type ObjectAttribute as cb, type CompletionStatus as cc, type ObjectRecord as cd, type PermissionScope as ce, type Role as cf, type Permission as cg, type UserRoleAssignment as ch, type EffectivePermissions as ci, type ObjectPermissions as cj, type SystemPermissions as ck, type CreateRoleInput as cl, type UpdateRoleInput as cm, type CreatePermissionInput as cn, type AssignRoleInput as co, type PolicyContext as cp, type RecordPolicy as cq, PolicyViolationError as cr, type UserRole as cs, type UserStatus as ct, type UserProfile as cu, type CreateUserProfile as cv, type UpdateUserProfile as cw, type InviteUserInput as cx, type TabType as cy, type FormTab as cz, type CurrencyAttribute as d, DEFAULT_VALIDATION_MESSAGES as d$, eq as d0, neq as d1, and as d2, or as d3, inValues as d4, isEmpty as d5, isNotEmpty as d6, type WorkflowSlot as d7, type NodePosition as d8, type CanvasViewport as d9, type WorkflowExecutionContext as dA, createEmptyContext as dB, getContextValue as dC, setContextValue as dD, mergeFormToSlot as dE, type WorkflowAccessMode as dF, type ReadOnlyReason as dG, type FormFieldContext as dH, type FormFieldRow as dI, type FormNodeInfo as dJ, type FormContextResponse as dK, type ThemeLogo as dL, type ThemeColors as dM, type ThemeTypography as dN, DEFAULT_THEME as dO, mergeWithDefaults as dP, generateCssVariables as dQ, type Uuid as dR, type TenantId as dS, type UserId as dT, asTenantId as dU, asUserId as dV, generateId as dW, generatePrefixedId as dX, registry as dY, viewRegistry as dZ, type ValidationMessages as d_, type WorkflowLayout as da, type ParticipantAuthConfig as db, type WorkflowStatus as dc, isWorkflowDefinition as dd, isWorkflowPublished as de, isSystemWorkflow as df, type WorkflowTransition as dg, type WorkflowError as dh, type PendingAction as di, type WorkflowInstance as dj, isInstanceTerminal as dk, isInstanceWaiting as dl, canResumeInstance as dm, createStartTransition as dn, type ParticipationStatus as dp, type SignedLinkAuth as dq, type PinCodeAuth as dr, type ParticipationAuth as ds, type WorkflowParticipation as dt, isSignedLinkAuth as du, isPinCodeAuth as dv, canParticipate as dw, canAuthenticate as dx, canExecuteNode as dy, type GeneratedDocument as dz, type Option as e, PinCodeService as e$, textConfigSchema as e0, textareaConfigSchema as e1, richtextConfigSchema as e2, numberConfigSchema as e3, checkboxConfigSchema as e4, dateConfigSchema as e5, phoneConfigSchema as e6, currencyConfigSchema as e7, statusConfigSchema as e8, locationConfigSchema as e9, createMultiRelationValidator as eA, createRelationValidator as eB, createRatingValidator as eC, createFormulaValidator as eD, createRollupValidator as eE, createTextAreaValidator as eF, createRichtextValidator as eG, createAttributeValidator as eH, createFormAttributeValidator as eI, createObjectValidator as eJ, type ValidationResult as eK, validateAttribute as eL, validateObject as eM, validateObjectOrThrow as eN, createDraftValidator as eO, validateDraft as eP, validateDraftOrThrow as eQ, getMissingRequiredAttributes as eR, isRecordComplete as eS, computeRecordStatus as eT, type DatabaseAdapter as eU, ParticipationTokenService as eV, getDefaultTokenService as eW, initializeTokenService as eX, type ParticipationTokenPayload as eY, type TokenGenerationOptions as eZ, type TokenVerificationResult as e_, selectConfigSchema as ea, multiselectConfigSchema as eb, fileConfigSchema as ec, userConfigSchema as ed, relationConfigSchema as ee, ratingConfigSchema as ef, formulaConfigSchema as eg, rollupConfigSchema as eh, attributeConfigSchemas as ei, getAttributeConfigSchema as ej, validateAttributeConfig as ek, parseAttributeConfig as el, safeParseAttributeConfig as em, createTextValidator as en, createNumberValidator as eo, createCheckboxValidator as ep, createDateValidator as eq, createPhoneValidator as er, createCurrencyValidator as es, createStatusValidator as et, createSelectValidator as eu, createMultiselectValidator as ev, createLocationValidator as ew, createFileValidator as ex, createUserValidator as ey, createSingleRelationValidator as ez, type StatusAttribute as f, wait as f$, getDefaultPinCodeService as f0, initializePinCodeService as f1, type PinCodeGenerationOptions as f2, type PinCodeVerificationResult as f3, type CacheKeyType as f4, hashOptions as f5, type CacheAdapter as f6, type CacheOptions as f7, cacheKeys as f8, cacheTtl as f9, getSchemaByNameFromContext as fA, getSchemaContext as fB, getSchemaFromContext as fC, hasSchemaContext as fD, runWithMergedSchemaContext as fE, runWithSchemaContext as fF, type SchemaContext as fG, getContext as fH, getTenantId as fI, getUserId as fJ, hasContext as fK, runWithContext as fL, withTenantContext as fM, type TenantContext as fN, createDefaultExecutorRegistry as fO, getDefaultExecutorRegistry as fP, type ExecutorCompleteResult as fQ, type ExecutorContext as fR, type ExecutorErrorResult as fS, type ExecutorResult as fT, type ExecutorSuccessResult as fU, type ExecutorWaitResult as fV, type NodeExecutor as fW, complete as fX, error as fY, ExecutorRegistry as fZ, success as f_, defaultTtl as fa, NoopCacheAdapter as fb, type FetchResult as fc, type FormattedRecord as fd, type GroupedFetchResult as fe, type InsertOptions as ff, type QueryBuilderState as fg, type RegistryMap as fh, type RegistryObjectNames as fi, type ShortcutOperator as fj, createDefaultState as fk, formatRecord as fl, formatRecords as fm, QueryMultipleResultsError as fn, QueryNoResultError as fo, SHORTCUT_TO_FILTER_OPERATOR as fp, createQueryBuilder as fq, QueryBuilder as fr, type QueryBuilderOptions as fs, type EvaluationResult as ft, type EvaluationTrace as fu, evaluateCondition as fv, evaluate as fw, evaluateWithTrace as fx, TenantContextError as fy, addSchemaToContext as fz, type SelectAttribute as g, TenantAwareRepository as g$, ConditionExecutor as g0, EndExecutor as g1, FormExecutor as g2, StartExecutor as g3, evaluateFormula as g4, evaluateFormulaAttribute as g5, evaluateFormulaAttributeWithRelations as g6, evaluateFormulaWithRelations as g7, evaluateFormulaWithResult as g8, extractFormulaVariables as g9, type HookDefinition as gA, type HookHandler as gB, type HookType as gC, NoopHookRegistry as gD, type HookRegistry as gE, createMockAdapter as gF, defaultPolicyRegistry as gG, PolicyRegistry as gH, notesPolicy as gI, type ObjectsRepository as gJ, type AttributesRepository as gK, type UserProfilesRepository as gL, type FilesRepository as gM, type ObjectRecordsRepository as gN, type ViewsRepository as gO, type WorkflowsRepository as gP, type WorkflowInstancesRepository as gQ, type WorkflowParticipationsRepository as gR, type AuditRepository as gS, type PermissionsRepository as gT, type AIConversationsRepository as gU, type AIUserMemoryRepository as gV, type AIUsageMetricsRepository as gW, BaseService as gX, BaseRepository as gY, type SchemaContextAware as gZ, SchemaContextAwareRepository as g_, extractRelationNames as ga, extractRelationReferences as gb, flattenRelationsForEval as gc, formatFormulaResult as gd, hasRelationReferences as ge, validateFormulaExpression as gf, type FormulaResult as gg, getPathDepth as gh, getRelationPath as gi, getTargetAttributeName as gj, InvalidPathError as gk, MaxDepthExceededError as gl, parsePath as gm, pathHasManyCardinality as gn, validatePath as go, type PathCardinality as gp, type PathSegment as gq, type PathSegmentType as gr, type SchemaResolver as gs, resolveMultiplePaths as gt, resolveSingleValue as gu, traversePath as gv, type TraversalOptions as gw, type TraversalResult as gx, type AttributeChange as gy, type HookContext as gz, type SingleRelationAttribute as h, type UserValidationError as h$, TenantAwareService as h0, type CreateCustomObjectInput as h1, type AddAttributeInput as h2, type UpdateObjectInput as h3, type ObjectSchemaServiceOptions as h4, ObjectSchemaService as h5, type RecordServiceOptions as h6, RecordService as h7, type RecordQueryServiceOptions as h8, type QueryOptions as h9, checkRecordModifyOrThrow as hA, checkRecordDeleteOrThrow as hB, computeLabel as hC, type LabelResolver as hD, enrichWithFormulas as hE, enrichRecordsWithFormulas as hF, createContextForCreate as hG, createContextForUpdate as hH, createContextForDelete as hI, createContextForRestore as hJ, recalculateParentRollups as hK, type RollupCascadeContext as hL, type CreateWorkflowInput as hM, type UpdateWorkflowInput as hN, type WorkflowServiceOptions as hO, WorkflowService as hP, type StartWorkflowInput as hQ, type ResumeWorkflowInput as hR, type WorkflowInstanceServiceOptions as hS, WorkflowInstanceService as hT, type CreateParticipationInput as hU, type CreateParticipationResult as hV, type AuthenticationResult as hW, WorkflowParticipationService as hX, type FieldReadOnlyResult as hY, WorkflowRelationService as hZ, type UserValidationResult as h_, type SearchQueryOptions as ha, type QueryResult as hb, RecordQueryService as hc, type RelationValidationResult as hd, type RelationValidationError as he, type RelationOption as hf, type RelationOptionsResponse as hg, type GetRelationOptionsParams as hh, type RelationServiceOptions as hi, type ResolveIdsBatchRequest as hj, type ResolveIdsBatchResponse as hk, RelationService as hl, RecordResolverService as hm, type ResolvedRelations as hn, type FormulaResolverServiceOptions as ho, FormulaResolverService as hp, type RollupResult as hq, type RollupServiceOptions as hr, RollupService as hs, type RollupSchedulerOptions as ht, RollupScheduler as hu, applyDefaultValues as hv, checkPermission as hw, getPolicy as hx, buildPolicyContext as hy, checkRecordAccess as hz, type MultiRelationAttribute as i, type DBWorkflowParticipation as i$, UserService as i0, type UserProfileServiceOptions as i1, UserProfileService as i2, AuditService as i3, buildAuditChanges as i4, type FileServiceOptions as i5, FileService as i6, GeocodingService as i7, GlobalSearchService as i8, type PermissionServiceOptions as i9, extractRelationIds as iA, type RelationLabelResolver as iB, computeLabelWithRelations as iC, type DBObject as iD, type CreateDBObject as iE, type UpdateDBObject as iF, type UpsertDBObject as iG, type DBAttribute as iH, type CreateDBAttribute as iI, type UpdateDBAttribute as iJ, type UpsertDBAttribute as iK, type CreateObjectRecord as iL, type ListOptions as iM, type SearchOptions as iN, type GlobalSearchOptions as iO, type GlobalSearchResultItem as iP, type FileListOptions as iQ, type DBView as iR, type CreateDBView as iS, type UpdateDBView as iT, type UpsertDBView as iU, type DBWorkflow as iV, type CreateDBWorkflow as iW, type UpdateDBWorkflow as iX, type DBWorkflowInstance as iY, type CreateDBWorkflowInstance as iZ, type UpdateDBWorkflowInstance as i_, PermissionService as ia, type CreateViewInput as ib, type UpdateViewInput as ic, ViewService as id, type FileContent as ie, type StorageUploadInput as ig, type StorageUploadResult as ih, type SignedUrlOptions as ii, type StorageAdapter as ij, type UploadFileInput as ik, type SyncResult as il, type SyncOptions as im, syncNativeObjects as io, verifyNativeObjectsSync as ip, getSyncPreview as iq, type FullSyncResult as ir, type FullSyncOptions as is, syncAll as it, DEFAULT_LABEL_FALLBACK as iu, renderLabelExpression as iv, isLabelExpression as iw, extractAttributeNames as ix, enrichValuesForDisplay as iy, enrichValuesWithSelectLabels as iz, type RelationTarget as j, type CreateDBWorkflowParticipation as j0, type UpdateDBWorkflowParticipation as j1, type OperationResult as j2, type ViewSyncResult as j3, type ViewSyncOptions as j4, syncNativeViews as j5, verifyNativeViewsSync as j6, getViewSyncPreview as j7, type RatingAttribute as k, type FormulaAttribute as l, type FormulaReturnType as m, type RollupAttribute as n, type RollupFunction as o, type AttributeType as p, type ObjectDefinition as q, type Field as r, type AttributeGroupField as s, type TableTab as t, type InverseTableTab as u, type ViewDefinition as v, type InstanceStatus as w, type Tab as x, type FilterState as y, type SortRule as z };