openapi: "3.0.0"
info:
  description: "Cube.js Swagger Schema"
  version: "1.0.0"
  title: "Cube.js"
paths:
  "/v1/meta":
    get:
      summary: "Load Metadata"
      # TODO: Doesn't work in rust code-gen
      # parameters:
      #   - in: query
      #     name: extended
      #     required: false
      #     schema:
      #       type: boolean
      #     description: You will receive extended response if this parameter is present (presence-only, value is ignored)
      #   - in: query
      #     name: onlyViews
      #     required: false
      #     schema:
      #       type: boolean
      #       default: false
      #     description: When set to "true", only views (entries with type="view") and their viewGroups are returned, excluding cubes
      description: ""
      operationId: "metaV1"
      responses:
        "200":
          description: "successful operation"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1MetaResponse"
        "4XX":
          description: "Request could not be completed"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1Error"
        "5XX":
          description: "Internal Server Error"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1Error"
  "/v1/load":
    post:
      summary: "Load data via Cube JSON Query"
      operationId: "loadV1"
      requestBody:
        content:
          'application/json':
            schema:
              $ref: '#/components/schemas/V1LoadRequest'
      responses:
        "200":
          description: "successful operation"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1LoadResponse"
        "4XX":
          description: "Request could not be completed"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1Error"
        "5XX":
          description: "Internal Server Error"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V1Error"
security:
  - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    V1CubeMetaJoin:
      type: "object"
      required:
        - name
        - relationship
      properties:
        name:
          type: "string"
        relationship:
          type: "string"
    V1CubeMetaSegment:
      type: "object"
      required:
        - name
        - title
        - shortTitle
      properties:
        name:
          type: "string"
        title:
          type: "string"
        description:
          type: "string"
        shortTitle:
          type: "string"
        meta:
          type: "object"
    V1CubeMetaDimensionGranularity:
      type: "object"
      required:
        - name
        - title
      properties:
        name:
          type: "string"
        title:
          type: "string"
        interval:
          type: "string"
        sql:
          type: "string"
        offset:
          type: "string"
        origin:
          type: "string"
    V1CubeMetaDimension:
      type: "object"
      required:
        - name
        - type
      properties:
        name:
          type: "string"
        title:
          type: "string"
        shortTitle:
          type: "string"
        description:
          type: "string"
        type:
          type: "string"
        aliasMember:
          description: "When dimension is defined in View, it keeps the original path: Cube.dimension"
          type: "string"
        granularities:
          type: array
          items:
            $ref: "#/components/schemas/V1CubeMetaDimensionGranularity"
        meta:
          type: "object"
        format:
          $ref: "#/components/schemas/V1CubeMetaFormat"
        formatDescription:
          $ref: "#/components/schemas/V1CubeMetaFormatDescription"
        currency:
          type: "string"
          description: "ISO 4217 currency code in uppercase (3 characters, e.g. USD, EUR)"
        order:
          $ref: "#/components/schemas/V1CubeMetaDimensionOrder"
        key:
          type: "string"
          description: "Key reference for the dimension"
    V1CubeMetaDimensionOrder:
      type: "string"
      enum:
        - "asc"
        - "desc"
    V1CubeMetaMeasure:
      type: "object"
      required:
        - name
        - type
      properties:
        name:
          type: "string"
        title:
          type: "string"
        shortTitle:
          type: "string"
        description:
          type: "string"
        type:
          type: "string"
        aggType:
          type: "string"
        meta:
          type: "object"
        format:
          $ref: "#/components/schemas/V1CubeMetaFormat"
        formatDescription:
          $ref: "#/components/schemas/V1CubeMetaFormatDescription"
        currency:
          type: "string"
          description: "ISO 4217 currency code in uppercase (3 characters, e.g. USD, EUR)"
        aliasMember:
          description: "When measure is defined in View, it keeps the original path: Cube.measure"
          type: "string"
    V1CubeMetaFolder:
      type: "object"
      required:
        - name
        - members
      properties:
        name:
          type: "string"
        members:
          type: array
          items:
            type: "string"
    V1CubeMetaNestedFolder:
      type: "object"
      required:
        - name
        - members
      properties:
        name:
          type: "string"
        members:
          type: array
          items:
            type: "string"
            oneOf:
              - type: string
              - $ref: "#/components/schemas/V1CubeMetaNestedFolder"
    V1CubeMetaHierarchy:
      type: "object"
      required:
        - name
        - levels
      properties:
        name:
          type: "string"
        aliasMember:
          description: "When hierarchy is defined in Cube, it keeps the original path: Cube.hierarchy"
          type: "string"
        title:
          type: "string"
        levels:
          type: "array"
          items:
            type: "string"
    V1CubeMeta:
      type: "object"
      required:
        - name
        - type
        - measures
        - dimensions
        - segments
      properties:
        name:
          type: "string"
        title:
          type: "string"
        type:
          $ref: "#/components/schemas/V1CubeMetaType"
        meta:
          type: "object"
        description:
          type: "string"
        measures:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaMeasure"
        dimensions:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaDimension"
        segments:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaSegment"
        joins:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaJoin"
        folders:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaFolder"
        nestedFolders:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaNestedFolder"
        hierarchies:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMetaHierarchy"
    V1CubeMetaType:
      type: "string"
      description: Type of cube
      enum:
        - "cube"
        - "view"
    V1CubeMetaSimpleFormat:
      type: "string"
      description: Simple format
      enum:
        - "percent"
        - "currency"
        - "number"
        - "imageUrl"
        - "id"
        - "link"
    V1CubeMetaLinkFormat:
      type: "object"
      description: Link format with label and type
      properties:
        label:
          type: "string"
          description: Label for the link
        type:
          type: "string"
          enum: ["link"]
          description: Type of the format (must be 'link')
      required:
        - label
        - type
    V1CubeMetaCustomTimeFormat:
      type: "object"
      description: Custom time format for time dimensions
      properties:
        type:
          type: "string"
          enum: ["custom-time"]
          description: Type of the format (must be 'custom-time')
        value:
          type: "string"
          description: "POSIX strftime format string (IEEE Std 1003.1 / POSIX.1) with d3-time-format extensions (e.g., '%Y-%m-%d', '%d/%m/%Y %H:%M:%S'). See https://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html and https://d3js.org/d3-time-format"
      required:
        - type
        - value
    V1CubeMetaCustomNumericFormat:
      type: "object"
      description: Custom numeric format for numeric measures and dimensions
      properties:
        type:
          type: "string"
          enum: ["custom-numeric"]
          description: Type of the format (must be 'custom-numeric')
        value:
          type: "string"
          description: "d3-format specifier string (e.g., '.2f', ',.0f', '$,.2f', '.0%', '.2s'). See https://d3js.org/d3-format"
        alias:
          type: "string"
          description: "Name of the predefined format (e.g., 'percent_2', 'currency_1'). Present only when a named format was used."
      required:
        - type
        - value
    V1CubeMetaFormat:
      oneOf:
        - $ref: "#/components/schemas/V1CubeMetaSimpleFormat"
        - $ref: "#/components/schemas/V1CubeMetaLinkFormat"
        - $ref: "#/components/schemas/V1CubeMetaCustomTimeFormat"
        - $ref: "#/components/schemas/V1CubeMetaCustomNumericFormat"
      description: Format of measure or dimension - can be a simple string format, a link configuration, a custom time format, or a custom numeric format
    V1CubeMetaFormatDescription:
      type: "object"
      description: Resolved format description with the predefined name and d3-format specifier
      required:
        - name
        - specifier
      properties:
        name:
          type: "string"
          description: "Predefined format name (e.g., 'percent_2', 'currency_1') or a base name like 'number', or 'custom' for ad-hoc specifiers"
        specifier:
          type: "string"
          description: "d3-format specifier string (e.g., '.2f', ',.0f', '$,.2f'). See https://d3js.org/d3-format"
        currency:
          type: "string"
          description: "ISO 4217 currency code in uppercase (e.g. USD, EUR). Present when a currency format is used."
    V1MetaResponse:
      type: "object"
      properties:
        cubes:
          type: "array"
          items:
            $ref: "#/components/schemas/V1CubeMeta"
        compilerId:
          type: "string"
    V1LoadResultAnnotation:
      type: "object"
      required:
        - measures
        - dimensions
        - segments
        - timeDimensions
      properties:
        measures:
          type: "object"
        dimensions:
          type: "object"
        segments:
          type: "object"
        timeDimensions:
          type: "object"
    V1LoadResultDataRow:
      type: "array"
      description: "Row-oriented (default) data format - an array of rows, each row is an object keyed by member name."
      items:
        type: "object"
    V1LoadResultDataCompact:
      type: "object"
      description: "Compact data format - a single object with the members list and a dataset of primitive arrays. Returned when `responseFormat=compact` is requested."
      required:
        - members
        - dataset
      properties:
        members:
          type: "array"
          description: "Ordered list of member names that correspond to each cell position in `dataset` rows."
          items:
            type: "string"
        dataset:
          type: "array"
          description: "Array of rows, where each row is an array of primitive values (null, boolean, number, string) aligned with `members`."
          items:
            type: "array"
            items: {}
    V1LoadResultDataColumnar:
      type: "object"
      description: "Columnar data format - members list paired with one primitive array per column. Returned when `responseFormat=columnar` is requested."
      required:
        - members
        - columns
      properties:
        members:
          type: "array"
          description: "Ordered list of member names. Element `i` of `columns` holds the values for `members[i]` across all rows."
          items:
            type: "string"
        columns:
          type: "array"
          description: "One array per member, in the same order as `members`. Each inner array contains the primitive value of that member for every row (null, boolean, number, string)."
          items:
            type: "array"
            items: {}
    V1LoadResultData:
      description: "Result `data` payload. Either an array of objects keyed by member name (default); a compact `{ members, dataset }` object when `responseFormat=compact`; or a columnar `{ members, columns }` object when `responseFormat=columnar`."
      oneOf:
        - $ref: "#/components/schemas/V1LoadResultDataRow"
        - $ref: "#/components/schemas/V1LoadResultDataCompact"
        - $ref: "#/components/schemas/V1LoadResultDataColumnar"
    V1LoadResult:
      type: "object"
      required:
        - annotation
        - data
      properties:
        dataSource:
          type: "string"
        annotation:
          $ref: "#/components/schemas/V1LoadResultAnnotation"
        data:
          $ref: "#/components/schemas/V1LoadResultData"
        refreshKeyValues:
          type: "array"
          items:
            type: "object"
        lastRefreshTime:
          type: "string"
        external:
          type: "boolean"
          description: "`true` when the result was served from an external (CubeStore) pre-aggregation."
        usedPreAggregations:
          type: "object"
          description: "Pre-aggregations this result was served from, keyed by pre-aggregation table name. Each entry carries `preAggregationId`, `lastUpdatedAt` and `type`. Absent when the query hit no pre-aggregation. In dev mode and for the Playground the entries also carry `targetTableName` and `refreshKeyValues`."
          additionalProperties:
            type: "object"
            properties:
              preAggregationId:
                type: "string"
              lastUpdatedAt:
                type: "integer"
              type:
                type: "string"
    V1Error:
      type: "object"
      required:
        - "error"
      properties:
        error:
          type: "string"
    V1LoadResponse:
      type: "object"
      required:
        - results
      properties:
        pivotQuery:
          type: "object"
        slowQuery:
          type: "boolean"
        queryType:
          type: "string"
        results:
          type: "array"
          items:
            $ref: "#/components/schemas/V1LoadResult"
    V1LoadRequestQueryFilterLogicalAnd:
      type: "object"
      properties:
        and:
          type: "array"
          items:
            type: "object"
    V1LoadRequestQueryFilterLogicalOr:
      type: "object"
      properties:
        or:
          type: "array"
          items:
            type: "object"
    V1LoadRequestQueryFilterBase:
      type: "object"
      properties:
        member:
          type: "string"
        operator:
          type: "string"
        values:
          type: "array"
          items:
            type: "string"
    V1LoadRequestQueryTimeDimension:
      type: "object"
      required:
        - "dimension"
      properties:
        dimension:
          type: "string"
        granularity:
          type: "string"
        dateRange:
          type: "object"
          # Don't work in rust code-gen
          # oneOf:
          #   - type: "string"
          #   - type: "array"
          #     items:
          #       type: "string"
    V1LoadRequestQueryFilterItem:
      oneOf:
        - $ref: "#/components/schemas/V1LoadRequestQueryFilterBase"
        - $ref: "#/components/schemas/V1LoadRequestQueryFilterLogicalOr"
        - $ref: "#/components/schemas/V1LoadRequestQueryFilterLogicalAnd"
    V1LoadRequestQueryJoinSubquery:
      type: "object"
      properties:
        sql:
          type: "string"
        # TODO This is _always_ a member expression, maybe pass as parsed, without intermediate string?
        "on":
          type: "string"
        # TODO why string? it's enum
        joinType:
          type: "string"
        alias:
          type: "string"
      required:
        - sql
        - "on"
        - joinType
        - alias
    V1LoadRequestJoinHint:
      type: "array"
      items:
        type: "string"
    V1LoadRequestQuery:
      type: "object"
      properties:
        measures:
          type: "array"
          items:
            type: "string"
        dimensions:
          type: "array"
          items:
            type: "string"
        segments:
          type: "array"
          items:
            type: "string"
        timeDimensions:
          type: "array"
          items:
            $ref: "#/components/schemas/V1LoadRequestQueryTimeDimension"
        order:
          type: "array"
          items:
            type: "array"
            items:
              type: "string"
        limit:
          type: "integer"
          format: "int32"
        offset:
          type: "integer"
          format: "int32"
        filters:
          type: "array"
          items:
            $ref: "#/components/schemas/V1LoadRequestQueryFilterItem"
        ungrouped:
          type: "boolean"
        # vector of (subquery sql: string, join condition: member expression, join type: enum)
        # they will be added to end of joinQuery in BaseQuery, in same order as here
        subqueryJoins:
          type: "array"
          items:
            $ref: "#/components/schemas/V1LoadRequestQueryJoinSubquery"
        joinHints:
          type: "array"
          items:
            $ref: "#/components/schemas/V1LoadRequestJoinHint"
        timezone:
          type: "string"
        responseFormat:
          type: "string"
          description: "Output format of the result `data` payload. `default` returns row-oriented data (`V1LoadResultDataRow`); `compact` returns a `{ members, dataset }` object with rows of primitive arrays (`V1LoadResultDataCompact`); `columnar` returns a `{ members, columns }` object with one primitive array per member (`V1LoadResultDataColumnar`)."
          enum:
            - default
            - compact
            - columnar
    V1LoadRequest:
      type: "object"
      properties:
        queryType:
          type: "string"
        cache:
          type: "string"
          enum:
            - stale-if-slow
            - stale-while-revalidate
            - must-revalidate
            - no-cache
        query:
          type: "object"
          $ref: "#/components/schemas/V1LoadRequestQuery"
