{"version":3,"sources":["../../src/core/definitions.ts"],"sourcesContent":["import ErrorCodes       from '../errors/io-error-codes';\r\nimport ValidationError  from '../errors/io-validation-error';\r\nimport TokenNode        from '../parser/nodes/tokens';\r\nimport TokenType        from '../parser/tokenizer/token-types';\r\nimport Schema           from '../schema/schema';\r\n\r\n/**\r\n * Represents a stored definition value with metadata.\r\n */\r\ntype IODefinitionValue = {\r\n  /** True if this is a schema definition (key starts with $) */\r\n  isSchema: boolean;\r\n  /** True if this is a variable definition (key starts with @) */\r\n  isVariable: boolean;\r\n  /** The actual definition value */\r\n  value: any;\r\n};\r\n\r\n/**\r\n * IODefinitions manages schema definitions, variables, and metadata for Internet Object documents.\r\n *\r\n * Key Types:\r\n * - Schema definitions: Keys starting with `$` (e.g., `$person`, `$schema`)\r\n * - Variables: Keys starting with `@` (e.g., `@yes`, `@baseUrl`)\r\n * - Metadata: Regular keys (e.g., `version`, `page`)\r\n *\r\n * Features:\r\n * - Preserves insertion order (definitions can reference earlier definitions)\r\n * - O(1) key-based access\r\n * - Forward reference validation (throws for undefined variables/schemas)\r\n * - Merge support for document composition\r\n * - Iterable for processing all definitions\r\n *\r\n * Definition Order Rules (per Internet Object spec):\r\n * - Variables and schemas defined earlier can be used in later definitions\r\n * - Forward references (using definitions not yet defined) throw errors\r\n *\r\n * @example\r\n * ```typescript\r\n * const defs = new IODefinitions();\r\n * defs.set('@baseUrl', 'https://api.example.com');\r\n * defs.set('$person', personSchema);\r\n * defs.set('$schema', mainSchema);\r\n *\r\n * // Variables are accessed via getV()\r\n * const url = defs.getV('@baseUrl'); // 'https://api.example.com'\r\n *\r\n * // Schemas are accessed via get()\r\n * const schema = defs.get('$person'); // Schema instance\r\n * ```\r\n */\r\nclass IODefinitions {\r\n  /**\r\n   * The default schema, if defined. Reset when $schema is deleted or updated.\r\n   */\r\n  private _defaultSchema: Schema | null = null;\r\n\r\n  /**\r\n   * Internal storage for definitions. Order is preserved as per insertion sequence.\r\n   */\r\n  private _definitions: { [key: string]: IODefinitionValue } = {};\r\n\r\n  /**\r\n   * Returns the number of definitions in the collection.\r\n   * @returns Number of definitions.\r\n   */\r\n  public get length(): number {\r\n    return Object.keys(this._definitions).length;\r\n  }\r\n\r\n  /**\r\n   * Returns an array of definition keys, in insertion order.\r\n   * @returns Array of keys.\r\n   */\r\n  public get keys(): string[] {\r\n    return Object.keys(this._definitions);\r\n  }\r\n\r\n  /**\r\n   * Returns the key-value pair at the specified index, preserving definition order.\r\n   * @param index Index of the definition.\r\n   * @returns Object with key and value.\r\n   */\r\n  public at(index: number): { key: string, value: IODefinitionValue } {\r\n    const key = this.keys[index];\r\n    return { key, value: this._definitions[key] };\r\n  }\r\n\r\n  /**\r\n   * Returns the default schema, if defined.\r\n   * Resolves schema variable references (e.g., $schema: $otherSchema).\r\n   * @returns The default Schema instance or null.\r\n   */\r\n  public get defaultSchema(): Schema | null {\r\n    if (this._defaultSchema) {\r\n      return this._defaultSchema;\r\n    }\r\n\r\n    // Use getV to resolve any nested references (e.g., $schema: $otherSchema)\r\n    const schemaValue = this._definitions[\"$schema\"]?.value;\r\n    if (!schemaValue) {\r\n      return null;\r\n    }\r\n\r\n    // If it's already a Schema, return it\r\n    if (schemaValue instanceof Schema) {\r\n      return schemaValue;\r\n    }\r\n\r\n    // If it's a TokenNode reference, resolve it\r\n    if (schemaValue instanceof TokenNode) {\r\n      try {\r\n        const resolved = this.getV(schemaValue);\r\n        if (resolved instanceof Schema) {\r\n          // Cache the resolved schema\r\n          this._definitions[\"$schema\"].value = resolved;\r\n          return resolved;\r\n        }\r\n      } catch (e) {\r\n        // If resolution fails, return null\r\n        return null;\r\n      }\r\n    }\r\n\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Checks if there are any definitions beyond just the default $schema.\r\n   * Used to determine serialization format:\r\n   * - false: Output bare schema line (schema-only mode)\r\n   * - true: Output ~ definitions format (has variables, metadata, or multiple schemas)\r\n   * @returns True if there are any definitions other than a single $schema, false otherwise\r\n   */\r\n  public get defaultSchemaOnly(): boolean {\r\n    const keys = Object.keys(this._definitions);\r\n\r\n    return keys.length === 1 && keys[0] === \"$schema\"\r\n  }\r\n\r\n  /**\r\n   * Gets a definition value by key, regardless of whether it's a variable, schema, or regular definition.\r\n   * @param key The definition key\r\n   * @returns The value associated with the key, or undefined if not found\r\n   */\r\n  public get(key: string): any {\r\n    return this._definitions[key]?.value;\r\n  }\r\n\r\n  /**\r\n   * Gets the variable value. This function is intended to be used internally\r\n   * for quickly fetching the variable value, hence it accepts any key to keep the\r\n   * consumer code free from type checking. The function validates the key and\r\n   * returns the associated value, if available. Otherwise returns undefined.\r\n   * @param key {any} The variable key starting with $\r\n   * @returns The value associated with the variable\r\n   */\r\n  public getV(k: any): any {\r\n    let key: string = \"\";\r\n\r\n    // Check if k is a TokenNode (can have lowercase 'string' or uppercase 'STRING' type)\r\n    if ((k || {}).type === TokenType.STRING || (k || {}).type === 'string') {\r\n      key = k.value;\r\n    } else if (typeof k === 'string') {\r\n      key = k;\r\n    } else {\r\n      return;\r\n    }\r\n\r\n    const def = this._definitions[key];\r\n    if (!def) {\r\n      // Only throw errors for variables and schemas\r\n      if (key.startsWith(\"$\") || key.startsWith(\"@\")) {\r\n        const positionParam = (typeof k === 'string') ? undefined : k;\r\n        if (key.startsWith(\"$\")) {\r\n          throw new ValidationError(ErrorCodes.schemaNotDefined, `Schema ${key} is not defined.`, positionParam);\r\n        }\r\n        throw new ValidationError(ErrorCodes.variableNotDefined, `Variable ${key} is not defined.`, positionParam);\r\n      }\r\n      return undefined;\r\n    }\r\n\r\n    if (def.isVariable) {\r\n      return def.value;\r\n    }\r\n\r\n    // Check nested references. If yes, then resolve them and set in the\r\n    // place of the variable.\r\n    if (def.value instanceof TokenNode) {\r\n      const schema = this.getV(def.value);\r\n      if (schema instanceof Schema) {\r\n        this.set(key, schema);\r\n        return schema;\r\n      }\r\n    }\r\n\r\n    return def.value;\r\n  }\r\n\r\n  public set(k: string, v: any) {\r\n    const dv = {\r\n      isSchema: k.startsWith(\"$\"),\r\n      isVariable: k.startsWith(\"@\"),\r\n      value: v\r\n    };\r\n    this._definitions[k] = dv;\r\n    this._defaultSchema = null;\r\n  }\r\n\r\n  /**\r\n   * Removes a definition by key.\r\n   * @param key The key of the definition to remove\r\n   * @returns True if the key existed and was deleted, false otherwise\r\n   */\r\n  public delete(key: string): boolean {\r\n    if (key in this._definitions) {\r\n      delete this._definitions[key];\r\n      // If the deleted key was $schema, reset _defaultSchema\r\n      if (key === \"$schema\") {\r\n        this._defaultSchema = null;\r\n      }\r\n      return true;\r\n    }\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * Pushes a new definition to the definitions list.\r\n   * @param key The key of the definition\r\n   * @param value The value of the definition\r\n   */\r\n  public push(key: string, value: any, isSchema: boolean = false, isVariable: boolean = false) {\r\n    this._definitions[key] = { isSchema, isVariable, value };\r\n    if (key === \"$schema\") {\r\n      this._defaultSchema = value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Merges the definitions with the other definitions.\r\n   * @param other     The other definitions to merge with\r\n   * @param override  If true, the other definitions will override the current\r\n   *                  definitions\r\n   */\r\n  public merge(other: IODefinitions, override: boolean = false) {\r\n    for (let i = 0; i < other.length; i++) {\r\n      const { key, value } = other.at(i);\r\n      if (override || !this._definitions[key]) {\r\n        this.push(key, value.value, value.isSchema, value.isVariable);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Return a clean object for nodejs console logging.\r\n   */\r\n  [Symbol.for('nodejs.util.inspect.custom')]() {\r\n    const obj: any = {};\r\n    for (const key of this.keys) {\r\n      const def = this._definitions[key];\r\n      obj[key] = def.value;\r\n    }\r\n    return obj;\r\n  }\r\n\r\n  public toObject() {\r\n    const obj: any = {};\r\n    let keysCount = 0;\r\n    for (let i = 0; i < this.length; i++) {\r\n      const def = this.at(i);\r\n\r\n      // Skip schema and variable definitions\r\n      if (def.value.isSchema || def.value.isVariable) {\r\n        continue;\r\n      }\r\n\r\n      keysCount++;\r\n      obj[def.key] = def.value.value?.toObject ? def.value.value.toObject() : def.value.value;\r\n    }\r\n\r\n    if (keysCount) {\r\n      return obj;\r\n    }\r\n\r\n    return null;\r\n  }\r\n\r\n  public toJSON() {\r\n    return this.toObject();\r\n  }\r\n\r\n  /**\r\n   * Returns an iterator of definition keys.\r\n   */\r\n  /**\r\n   * Returns an iterator of definition keys (useful for for...of).\r\n   */\r\n  *keyIterator(): IterableIterator<string> {\r\n    for (const key of Object.keys(this._definitions)) {\r\n      yield key;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns an iterator of [key, value] pairs.\r\n   */\r\n  *entries(): IterableIterator<[string, IODefinitionValue]> {\r\n    for (const key of this.keyIterator()) {\r\n      yield [key, this._definitions[key]];\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Default iterator for [key, value] pairs.\r\n   */\r\n  *[Symbol.iterator](): IterableIterator<[string, IODefinitionValue]> {\r\n    yield* this.entries();\r\n  }\r\n}\r\n\r\nexport default IODefinitions;\r\n"],"mappings":"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","names":["Schema","TokenNode","TokenType","ValidationError","ErrorCodes"]}