/**
 * Defines the names for all available data semantics.
 * Using a string enum makes it easy to add or remove semantics in a single place.
 */
export var SemanticType;
(function (SemanticType) {
    //
    // Entity-Level Semantics
    //
    /**
     * Designates a Data Entity that represents users of the system.
     */
    SemanticType["User"] = "Semantic#User";
    //
    // Property-Level Semantics
    //
    /**
     * Annotates the field as the user password.
     * The runtime should treat this field with special care,
     * ensuring it is encrypted and not exposed in API responses.
     */
    SemanticType["Password"] = "Semantic#Password";
    /**
     * Annotates the field as the username for user authentication.
     * This identifies which field should be used for login purposes.
     * Can be applied to dedicated username fields or email fields that serve as usernames.
     * The runtime uses this for authentication, password reset, and user lookup operations.
     */
    SemanticType["Username"] = "Semantic#Username";
    /**
     * Designates a Data Property as the `createdAt` timestamp of an entity.
     * This is used to track when the entity was first created.
     */
    SemanticType["CreatedTimestamp"] = "Semantic#CreatedTimestamp";
    /**
     * Designates a Data Property as the `updatedAt` timestamp of an entity.
     * This is used to track when the entity was last modified.
     */
    SemanticType["UpdatedTimestamp"] = "Semantic#UpdatedTimestamp";
    /**
     * Designates a Data Property as the `deletedAt` timestamp of an entity.
     * This is used to track when the entity was soft-deleted.
     * Soft-deletion means the entity is not physically removed from the database,
     * but marked as deleted for logical deletion purposes.
     */
    SemanticType["DeletedTimestamp"] = "Semantic#DeletedTimestamp";
    /**
     * Designates a Data Property as a boolean flag indicating whether the entity is deleted.
     * This is used for soft-deletion, where the entity is not physically removed from the database,
     * but marked as deleted.
     */
    SemanticType["DeletedFlag"] = "Semantic#DeletedFlag";
    /**
     * Designates a Data Property as a public identifier for a resource (the slug).
     * This is often used in URLs to provide a user-friendly way to access the resource.
     * For example, a blog post might have a public unique name like "my-first-post".
     * The runtime automatically generates a URL-safe string from another field (like a title).
     * By default, slugs are generated to be unique, but the configuration allows for duplicates
     * in scenarios where uniqueness is handled by a combination of fields (e.g., year and slug).
     */
    SemanticType["PublicUniqueName"] = "Semantic#PublicUniqueName";
    /**
     * A semantic that describes a title of an article, blog post, and so on. This semantic is used with
     * the `PublicUniqueName` to determine which field is responsible for the slug generation. However,
     * we may add more automation related to the `title` property in the future.
     */
    SemanticType["Title"] = "Semantic#Title";
    /**
     * Designates a Data Property as the `role` of a user within the system.
     * This is used to define the user's permissions and access levels.
     * For example, a user with the role of "admin" would have elevated permissions
     * compared to a user with the role of "guest".
     * Roles are defined on the entity as enums, or as a string property with a controlled vocabulary.
     */
    SemanticType["UserRole"] = "Semantic#UserRole";
    /**
     * A text or enum field to represent the state of a record (e.g., `draft`, `published`, `pending_review`, `archived`).
     *
     * Defined behaviors:
     * - State-Based Filtering: Automatically prevents public users from seeing records in a draft state.
     * - State Transitions: In principle, the runtime should prevent the user from skipping some states.
     * For example, when the record is in the `draft` state, it cannot be moved to the `archived` state without publishing it first. However,
     * we do not have enough customer feedback to design this functionality correctly right now, so
     * it serves as a placeholder semantic annotation.
     */
    SemanticType["Status"] = "Semantic#Status";
    /**
     * Annotates an integer field that automatically increments.
     * The runtime automatically increments this number on every update, providing a simple way
     * to track changes and implement optimistic locking to prevent mid-air collisions.
     */
    SemanticType["Version"] = "Semantic#Version";
    /**
     * Annotates a field that holds a reference to an image data via an URL.
     * The application + runtime should validate that the input is a well-formed URL.
     */
    SemanticType["ImageURL"] = "Semantic#ImageURL";
    /**
     * Annotates a field that holds a reference to a file object via an URL. Ity is distinct from the
     * `ImageURL` semantic as it implicitly states that the target is non-image, binary data (an attachment, for example).
     */
    SemanticType["FileURL"] = "Semantic#FileURL";
    /**
     * Annotates the field as a markdown-interpreted field.
     * When an object is created, the runtime performs additional sanitization to prevent XSS attacks.
     *
     * The annotation describes whether the data should be translated to the HTML output when
     * record is read or the original MD content should be returned.
     */
    SemanticType["Markdown"] = "Semantic#Markdown";
    /**
     * Annotates the field as containing HTML content.
     * The runtime performs sanitization to prevent XSS attacks and validates HTML structure.
     *
     * The annotation describes whether the data should be rendered as HTML output when
     * record is read or the original HTML content should be returned.
     */
    SemanticType["HTML"] = "Semantic#HTML";
    /**
     * Annotates a field that holds geospatial coordinate data (latitude/longitude).
     * The runtime automatically generates API capabilities for location-based queries,
     * such as "find all restaurants within a 5-mile radius."
     *
     * The field should contain coordinate data in a standard format:
     * - "40.7128,-74.0060" (lat,lon)
     * - "POINT(-74.0060 40.7128)" (PostGIS format)
     * - "40.7128°N, 74.0060°W" (degree format)
     *
     * Defined behaviors:
     * - Spatial Indexing: The runtime automatically creates spatial indexes for efficient location-based queries
     * - Distance Queries: Enables API endpoints for finding records within specified distances
     * - Coordinate Validation: Validates that the input follows proper coordinate format
     * - PostGIS Integration: When using PostgreSQL, automatically maps to PostGIS geometry types
     */
    SemanticType["GeospatialCoordinates"] = "Semantic#GeospatialCoordinates";
    /**
     * Annotates a field as an email address with validation and verification options.
     */
    SemanticType["Email"] = "Semantic#Email";
    /**
     * Annotates a field as a phone number with validation and formatting options.
     */
    SemanticType["Phone"] = "Semantic#Phone";
    /**
     * Annotates a field as a monetary value with currency support and precision control.
     * Can store simple decimal amounts or complex objects with amount and currency.
     *
     * As a semantic, it provides flexibility by annotating a base `number` or `string` type,
     * allowing for different storage strategies (e.g., decimal, integer cents, or a JSON object)
     * while maintaining a consistent API for currency operations.
     */
    SemanticType["Currency"] = "Semantic#Currency";
    /**
     * Annotates a field as a URL with validation and allowed protocols.
     */
    SemanticType["URL"] = "Semantic#URL";
    /**
     * Annotates a field as a Stock Keeping Unit (SKU).
     * Enforces uniqueness at the database level, critical for product catalogs.
     * Provides automatic validation and formatting for product identification codes.
     */
    SemanticType["SKU"] = "Semantic#SKU";
    /**
     * Annotates a field as a long-form description.
     */
    SemanticType["Description"] = "Semantic#Description";
    /**
     * Annotates a field as a short summary.
     */
    SemanticType["Summary"] = "Semantic#Summary";
    /**
     * Annotates a field as a calculated value based on a formula.
     */
    SemanticType["Calculated"] = "Semantic#Calculated";
    /**
     * Annotates a field as derived from other fields.
     */
    SemanticType["Derived"] = "Semantic#Derived";
    /**
     * Annotates a field that should automatically receive the client's IP address.
     * The runtime automatically populates this field with the request's IP address
     * when creating or updating records, providing audit trail and geolocation capabilities.
     */
    SemanticType["ClientIPAddress"] = "Semantic#ClientIPAddress";
    //
    // Association-Level Semantics
    //
    /**
     * Designates an association that links a resource to a "User" entity instance.
     * This is used to indicate ownership of the resource for access control purposes.
     * For example, a blog post might have a resource owner identifier that points to the user who created it.
     *
     * Defined behaviors:
     * - Automatic Ownership: When a new record is created, this field is automatically populated with the ID of the authenticated user. It also creates a foreign relationship to the `User` semantic object.
     * - Scoped Access: The runtime automatically filters list and read operations to show only records where the Owner matches the current user. update and delete operations are similarly restricted.
     */
    SemanticType["ResourceOwnerIdentifier"] = "Semantic#ResourceOwnerIdentifier";
    /**
     * Annotates an association as supporting tag functionality.
     * Applied to associations between entities to enable tagging behavior.
     * For example, a Product-Category association with Tags semantic enables product tagging.
     */
    SemanticType["Tags"] = "Semantic#Tags";
    /**
     * Annotates an association as supporting category functionality.
     * Applied to associations between entities to enable categorization behavior.
     * For example, a Product-Category association with Categories semantic enables product categorization.
     */
    SemanticType["Categories"] = "Semantic#Categories";
})(SemanticType || (SemanticType = {}));
/**
 * Defines the scope at which a semantic can be applied.
 */
export var SemanticScope;
(function (SemanticScope) {
    /**
     * The semantic applies to an entire Data Entity.
     * This is used for semantics that provide context or constraints at the entity level.
     */
    SemanticScope["Entity"] = "Entity";
    /**
     * The semantic applies to a single Data Property.
     * This is used for semantics that provide context or constraints at the property level.
     */
    SemanticScope["Property"] = "Property";
    /**
     * The semantic applies to an Association between Data Entities.
     * This is used for semantics that provide context or constraints at the association level.
     */
    SemanticScope["Association"] = "Association";
})(SemanticScope || (SemanticScope = {}));
/**
 * Defines categories for organizing semantics in the UI.
 */
export var SemanticCategory;
(function (SemanticCategory) {
    /**
     * User management, authentication, and access control
     */
    SemanticCategory["Identity"] = "Identity & Authentication";
    /**
     * Timestamps, versioning, and record lifecycle
     */
    SemanticCategory["Lifecycle"] = "Timestamps & Versioning";
    /**
     * Text content, media, and rich content types
     */
    SemanticCategory["Content"] = "Content & Media";
    /**
     * Business-specific data like pricing, inventory, status
     */
    SemanticCategory["Business"] = "Business Data";
    /**
     * Contact information and communication
     */
    SemanticCategory["Contact"] = "Contact Information";
    /**
     * Organization, categorization, and tagging
     */
    SemanticCategory["Organization"] = "Classification & Organization";
    /**
     * Location and geographical data
     */
    SemanticCategory["Location"] = "Location & Geography";
    /**
     * Calculated and derived values
     */
    SemanticCategory["Computed"] = "Computed Values";
})(SemanticCategory || (SemanticCategory = {}));
/**
 * Defines when a semantic should execute in relation to database operations.
 */
export var SemanticTiming;
(function (SemanticTiming) {
    /**
     * Execute before the database operation (validation, preprocessing)
     */
    SemanticTiming["Before"] = "Before";
    /**
     * Execute after the database operation (cleanup, notifications, derived values)
     */
    SemanticTiming["After"] = "After";
    /**
     * Execute both before and after the operation
     */
    SemanticTiming["Both"] = "Both";
    /**
     * No automatic execution (manual/on-demand only)
     */
    SemanticTiming["None"] = "None";
})(SemanticTiming || (SemanticTiming = {}));
/**
 * Defines which database operations can trigger a semantic.
 */
export var SemanticOperation;
(function (SemanticOperation) {
    SemanticOperation["Create"] = "Create";
    SemanticOperation["Read"] = "Read";
    SemanticOperation["Update"] = "Update";
    SemanticOperation["Delete"] = "Delete";
    /**
     * Special operation for list/query operations
     */
    SemanticOperation["List"] = "List";
})(SemanticOperation || (SemanticOperation = {}));
/**
 * Defines the execution mode for a semantic.
 */
export var SemanticExecutionMode;
(function (SemanticExecutionMode) {
    /**
     * Execute synchronously as part of the main operation
     */
    SemanticExecutionMode["Synchronous"] = "Synchronous";
    /**
     * Execute asynchronously after the main operation
     */
    SemanticExecutionMode["Asynchronous"] = "Asynchronous";
    /**
     * Execute in background/queue (fire and forget)
     */
    SemanticExecutionMode["Background"] = "Background";
})(SemanticExecutionMode || (SemanticExecutionMode = {}));
/**
 * Defines validation strategies for semantics.
 */
export var SemanticValidationStrategy;
(function (SemanticValidationStrategy) {
    /**
     * Fail the operation if semantic validation fails
     */
    SemanticValidationStrategy["Strict"] = "Strict";
    /**
     * Log warnings but continue operation
     */
    SemanticValidationStrategy["Warning"] = "Warning";
    /**
     * Skip validation entirely
     */
    SemanticValidationStrategy["Skip"] = "Skip";
})(SemanticValidationStrategy || (SemanticValidationStrategy = {}));
/**
 * Defines caching strategies for computed semantics.
 */
export var SemanticCacheStrategy;
(function (SemanticCacheStrategy) {
    /**
     * No caching - always compute
     */
    SemanticCacheStrategy["None"] = "None";
    /**
     * Cache until dependent fields change
     */
    SemanticCacheStrategy["Dependency"] = "Dependency";
    /**
     * Cache with TTL expiration
     */
    SemanticCacheStrategy["TimeToLive"] = "TimeToLive";
    /**
     * Cache until manually invalidated
     */
    SemanticCacheStrategy["Manual"] = "Manual";
})(SemanticCacheStrategy || (SemanticCacheStrategy = {}));
/**
 * A type guard to check if a semantic is an EntitySemantic.
 */
export const isEntitySemantic = (semantic) => semantic.scope === SemanticScope.Entity;
/**
 * A type guard to check if a semantic is a PropertySemantic.
 */
export const isPropertySemantic = (semantic) => semantic.scope === SemanticScope.Property;
/**
 * A type guard to check if a semantic is a AssociationSemantic.
 */
export const isAssociationSemantic = (semantic) => semantic.scope === SemanticScope.Association;
/**
 * A map to store the definitions of all available data semantics.
 * This acts as a central registry for the application.
 */
export const DataSemantics = {
    //
    // Identity & Authentication
    //
    [SemanticType.User]: {
        id: SemanticType.User,
        displayName: 'User Entity',
        scope: SemanticScope.Entity,
        description: 'System users and accounts',
        category: SemanticCategory.Identity,
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.None,
            operations: [],
        },
    },
    [SemanticType.Password]: {
        id: SemanticType.Password,
        displayName: 'User Password',
        scope: SemanticScope.Property,
        description: 'Secure password field',
        category: SemanticCategory.Identity,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 10, // High priority for security
            canDisable: false, // Security semantics cannot be disabled
            timeoutMs: 2000, // Allow time for hashing
            conditions: [
                {
                    expression: 'entity[semantics.Password] != null && entity[semantics.Password].length > 0',
                    description: 'Only process when password field has a value',
                },
            ],
        },
    },
    [SemanticType.Username]: {
        id: SemanticType.Username,
        displayName: 'Username',
        scope: SemanticScope.Property,
        description: 'User authentication identifier',
        category: SemanticCategory.Identity,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read],
            priority: 15, // High priority for authentication
            canDisable: false, // Security semantics cannot be disabled
            timeoutMs: 100, // Fast operation
        },
    },
    [SemanticType.UserRole]: {
        id: SemanticType.UserRole,
        displayName: 'User Role Field',
        scope: SemanticScope.Property,
        description: 'User permissions and access level',
        category: SemanticCategory.Identity,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [
                SemanticOperation.Create,
                SemanticOperation.Read,
                SemanticOperation.Update,
                SemanticOperation.Delete,
                SemanticOperation.List,
            ],
            priority: 20,
        },
    },
    [SemanticType.ResourceOwnerIdentifier]: {
        id: SemanticType.ResourceOwnerIdentifier,
        displayName: 'Resource Owner Identifier',
        scope: SemanticScope.Association,
        description: 'Links record to owner user',
        category: SemanticCategory.Identity,
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [
                SemanticOperation.Create,
                SemanticOperation.Read,
                SemanticOperation.Update,
                SemanticOperation.Delete,
                SemanticOperation.List,
            ],
            priority: 5, // Very high priority for access control
            canDisable: false,
        },
    },
    //
    // Timestamps & Versioning
    //
    [SemanticType.CreatedTimestamp]: {
        id: SemanticType.CreatedTimestamp,
        displayName: 'Creation Timestamp',
        scope: SemanticScope.Property,
        description: 'When record was created',
        category: SemanticCategory.Lifecycle,
        applicableDataTypes: ['datetime'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create],
            priority: 90,
            timeoutMs: 100, // Very fast operation
            conditions: [
                {
                    expression: 'entity[semantics.CreatedTimestamp] == null',
                    description: 'Only set timestamp if not already provided',
                },
            ],
        },
    },
    [SemanticType.UpdatedTimestamp]: {
        id: SemanticType.UpdatedTimestamp,
        displayName: 'Update Timestamp',
        scope: SemanticScope.Property,
        description: 'When record was last modified',
        category: SemanticCategory.Lifecycle,
        applicableDataTypes: ['datetime'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Update],
            priority: 90,
        },
    },
    [SemanticType.DeletedTimestamp]: {
        id: SemanticType.DeletedTimestamp,
        displayName: 'Soft Delete Timestamp',
        scope: SemanticScope.Property,
        description: 'When record was marked deleted',
        category: SemanticCategory.Lifecycle,
        applicableDataTypes: ['datetime'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Delete],
            priority: 80,
        },
    },
    [SemanticType.DeletedFlag]: {
        id: SemanticType.DeletedFlag,
        displayName: 'Soft Delete Flag',
        scope: SemanticScope.Property,
        description: 'Mark record as deleted',
        category: SemanticCategory.Lifecycle,
        applicableDataTypes: ['boolean'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Delete, SemanticOperation.Read, SemanticOperation.List],
            priority: 80,
        },
    },
    [SemanticType.Version]: {
        id: SemanticType.Version,
        displayName: 'Version Number',
        scope: SemanticScope.Property,
        description: 'Auto-incrementing version counter',
        category: SemanticCategory.Lifecycle,
        applicableDataTypes: ['number'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Update],
            priority: 85,
        },
    },
    //
    // Content & Media
    //
    [SemanticType.Title]: {
        id: SemanticType.Title,
        displayName: 'Record Title',
        scope: SemanticScope.Property,
        description: 'Main title or heading',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.None,
            operations: [],
        },
    },
    [SemanticType.Description]: {
        id: SemanticType.Description,
        displayName: 'Description',
        scope: SemanticScope.Property,
        description: 'Detailed description text',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.None,
            operations: [],
        },
    },
    [SemanticType.Summary]: {
        id: SemanticType.Summary,
        displayName: 'Summary',
        scope: SemanticScope.Property,
        description: 'Brief summary text',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.None,
            operations: [],
        },
    },
    [SemanticType.Markdown]: {
        id: SemanticType.Markdown,
        displayName: 'Markdown Content',
        scope: SemanticScope.Property,
        description: 'Formatted text content',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 50, // Process before storage
        },
    },
    [SemanticType.HTML]: {
        id: SemanticType.HTML,
        displayName: 'HTML Content',
        scope: SemanticScope.Property,
        description: 'Rich HTML content',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 50, // Process before storage for sanitization
        },
    },
    [SemanticType.ImageURL]: {
        id: SemanticType.ImageURL,
        displayName: 'Image URL',
        scope: SemanticScope.Property,
        description: 'Link to image file',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 60, // Validate URLs before storage
        },
    },
    [SemanticType.FileURL]: {
        id: SemanticType.FileURL,
        displayName: 'File URL',
        scope: SemanticScope.Property,
        description: 'Link to file attachment',
        category: SemanticCategory.Content,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 60, // Validate URLs before storage
        },
    },
    //
    // Business Data
    //
    [SemanticType.Status]: {
        id: SemanticType.Status,
        displayName: 'Record Status',
        scope: SemanticScope.Property,
        description: 'Current state of record',
        category: SemanticCategory.Business,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Both,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read, SemanticOperation.List],
            priority: 30, // Validate state transitions before, filter by state after
        },
    },
    [SemanticType.Currency]: {
        id: SemanticType.Currency,
        displayName: 'Currency',
        scope: SemanticScope.Property,
        description: 'Monetary value with currency',
        category: SemanticCategory.Business,
        applicableDataTypes: ['number', 'string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 70, // Validate currency format and precision
        },
    },
    [SemanticType.SKU]: {
        id: SemanticType.SKU,
        displayName: 'SKU',
        scope: SemanticScope.Property,
        description: 'Product identification code',
        category: SemanticCategory.Business,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 25, // High priority for uniqueness validation
        },
    },
    //
    // Contact Information
    //
    [SemanticType.Email]: {
        id: SemanticType.Email,
        displayName: 'Email',
        scope: SemanticScope.Property,
        description: 'Email address',
        category: SemanticCategory.Contact,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 40, // Validate email format
        },
    },
    [SemanticType.Phone]: {
        id: SemanticType.Phone,
        displayName: 'Phone',
        scope: SemanticScope.Property,
        description: 'Phone number',
        category: SemanticCategory.Contact,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 40, // Validate phone format
        },
    },
    [SemanticType.URL]: {
        id: SemanticType.URL,
        displayName: 'URL',
        scope: SemanticScope.Property,
        description: 'Web address or link',
        category: SemanticCategory.Contact,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 40, // Validate URL format
        },
    },
    [SemanticType.ClientIPAddress]: {
        id: SemanticType.ClientIPAddress,
        displayName: 'Client IP Address',
        scope: SemanticScope.Property,
        description: 'Automatically populated client IP address',
        category: SemanticCategory.Contact,
        applicableDataTypes: ['string'],
        hasConfig: false,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 95, // Low priority, populate after other validations
            timeoutMs: 100, // Very fast operation
            conditions: [
                {
                    expression: 'entity[semantics.ClientIPAddress] == null',
                    description: 'Only set IP address if not already provided',
                },
            ],
        },
    },
    //
    // Classification & Organization
    //
    [SemanticType.PublicUniqueName]: {
        id: SemanticType.PublicUniqueName,
        displayName: 'Public Unique Name (Slug)',
        scope: SemanticScope.Property,
        description: 'URL-friendly unique identifier',
        category: SemanticCategory.Organization,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Before,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 30, // Generate slug from title, validate uniqueness
            timeoutMs: 1000,
            conditions: [
                {
                    expression: 'entity[semantics.PublicUniqueName] == null || entity[semantics.PublicUniqueName].length == 0',
                    description: 'Only generate slug if not already provided',
                },
                // Let's not guess which field is marked as slug source in the `PublicUniqueName` configuration.
                // {
                //   expression: 'entity[semantics.Title] != null && entity[semantics.Title].length > 0',
                //   description: 'Only generate slug if title field exists and has content',
                // },
            ],
        },
    },
    [SemanticType.Tags]: {
        id: SemanticType.Tags,
        displayName: 'Tags',
        scope: SemanticScope.Association,
        description: 'Enable tagging functionality',
        category: SemanticCategory.Organization,
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.After,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Delete],
            priority: 200, // Process after main operation
        },
    },
    [SemanticType.Categories]: {
        id: SemanticType.Categories,
        displayName: 'Categories',
        scope: SemanticScope.Association,
        description: 'Enable categorization functionality',
        category: SemanticCategory.Organization,
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.After,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Delete],
            priority: 200, // Process after main operation
        },
    },
    //
    // Location & Geography
    //
    [SemanticType.GeospatialCoordinates]: {
        id: SemanticType.GeospatialCoordinates,
        displayName: 'Geospatial Coordinates',
        scope: SemanticScope.Property,
        description: 'Location coordinates',
        category: SemanticCategory.Location,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Both,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read, SemanticOperation.List],
            priority: 60, // Validate coordinates before, enable spatial queries after
        },
    },
    //
    // Computed Values
    //
    // Calculated field can be added to any data type as we can compute any value.
    [SemanticType.Calculated]: {
        id: SemanticType.Calculated,
        displayName: 'Calculated',
        scope: SemanticScope.Property,
        description: 'Auto-calculated field value',
        category: SemanticCategory.Computed,
        applicableDataTypes: ['string', 'number', 'boolean', 'date', 'datetime', 'time', 'binary'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.Both,
            operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read],
            priority: 150, // Calculate after other validations, recalculate on read if needed
        },
    },
    [SemanticType.Derived]: {
        id: SemanticType.Derived,
        displayName: 'Derived',
        scope: SemanticScope.Property,
        description: 'Value derived from other fields',
        category: SemanticCategory.Computed,
        applicableDataTypes: ['string'],
        hasConfig: true,
        runtime: {
            timing: SemanticTiming.After,
            operations: [SemanticOperation.Create, SemanticOperation.Update],
            priority: 180, // Derive after all other processing
        },
    },
};
/**
 * Get all semantics that should run for a specific operation and timing
 */
export function getSemanticsForOperation(semantics, operation, timing) {
    return semantics
        .filter((semantic) => {
        const definition = DataSemantics[semantic.id];
        if (!definition?.runtime) {
            return false;
        }
        const { timing: semanticTiming, operations } = definition.runtime;
        // Check if timing matches
        const timingMatches = semanticTiming === timing || semanticTiming === SemanticTiming.Both;
        // Check if operation is included
        const operationMatches = operations.includes(operation);
        return timingMatches && operationMatches;
    })
        .sort((a, b) => {
        // Sort by priority (lower number = higher priority)
        const priorityA = DataSemantics[a.id]?.runtime?.priority ?? 100;
        const priorityB = DataSemantics[b.id]?.runtime?.priority ?? 100;
        return priorityA - priorityB;
    });
}
/**
 * Check if a specific semantic can be disabled at runtime
 */
export function canSemanticBeDisabled(semanticType) {
    const definition = DataSemantics[semanticType];
    return definition?.runtime?.canDisable !== false; // Default to true if not specified
}
/**
 * Helper function to get all semantics grouped by category.
 * Useful for organizing semantics in UI dropdowns and forms.
 *
 * @param scope Optional scope to filter semantics by (Entity, Property, Association)
 */
export function getSemanticsByCategory(scope) {
    const result = {
        [SemanticCategory.Identity]: [],
        [SemanticCategory.Lifecycle]: [],
        [SemanticCategory.Content]: [],
        [SemanticCategory.Business]: [],
        [SemanticCategory.Contact]: [],
        [SemanticCategory.Organization]: [],
        [SemanticCategory.Location]: [],
        [SemanticCategory.Computed]: [],
    };
    Object.values(DataSemantics).forEach((semantic) => {
        // If a scope is provided, filter semantics by that scope
        if (scope && semantic.scope !== scope) {
            return;
        }
        result[semantic.category].push(semantic);
    });
    return result;
}
/**
 * Helper function to get semantics for a specific category.
 * @param category The category to filter by
 * @returns Array of semantics in the specified category
 */
export const getSemanticsByCategoryType = (category) => {
    return Object.values(DataSemantics).filter((semantic) => semantic.category === category);
};
//# sourceMappingURL=Semantics.js.map