openapi: 3.0.1
info:
  title: jsr API
  version: "1.1.0"

servers:
  - url: https://api.jsr.io

security:
  - bearerAuth: []

paths:
  /scopes:
    post:
      summary: Create a new scope
      description: Creates a new scope
      operationId: createScope
      requestBody:
        description: Scope properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateScopeRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Scope"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}:
    get:
      summary: Get scope details
      description: Returns details of a scope. Returns full scope information (including quotas and settings) if the user is a scope member.
      operationId: getScope
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/Scope"
                  - $ref: "#/components/schemas/FullScope"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    patch:
      summary: Update scope
      description: Updates the details of a scope
      operationId: updateScope
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      requestBody:
        description: Scope properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateScopeRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Scope"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    delete:
      summary: Delete scope
      description: Deletes a scope if the scope has no packages
      operationId: deleteScope
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request / Scope has packages
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/members:
    get:
      summary: List scope members
      description: Returns a list of members of a scope
      operationId: listScopeMembers
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScopeMember"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    post:
      summary: Add scope member
      description: Invites a user to a scope
      operationId: addScopeMember
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      requestBody:
        description: Scope member properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AddScopeMemberRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScopeInvite"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/members/{userId}:
    patch:
      summary: Update scope member
      description: Updates the roles of a scope member
      operationId: updateScopeMember
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: userId
          in: path
          description: The ID of the user
          required: true
          schema:
            $ref: "#/components/schemas/UserId"
      requestBody:
        description: Scope member properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateScopeMemberRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScopeMember"
        "400":
          description: Invalid request / Can not remove last scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope or scope member not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    delete:
      summary: Remove scope member
      description: Removes a member from a scope
      operationId: removeScopeMember
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: userId
          in: path
          description: The ID of the user
          required: true
          schema:
            $ref: "#/components/schemas/UserId"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request / Can not remove last scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope or scope member not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/invites:
    get:
      summary: List scope invites
      description: Returns a list of invites to a scope
      operationId: listScopeInvites
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScopeInvite"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/invites/{userId}:
    delete:
      summary: Delete scope invite
      description: Deletes an invite to a scope
      operationId: deleteScopeInvite
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: userId
          in: path
          description: The ID of the user
          required: true
          schema:
            $ref: "#/components/schemas/UserId"
      responses:
        "204":
          description: OK, no content
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope or scope invite not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /packages:
    get:
      summary: List packages
      description: Returns a list of packages
      operationId: listPackages
      parameters:
        - name: limit
          in: query
          description: The maximum number of packages to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: page
          in: query
          description: The page number of packages to return
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: query
          in: query
          required: false
          description: The search query
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Package"
                  total:
                    type: integer
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages:
    get:
      summary: List scope packages
      description: Returns a list of packages in a scope
      operationId: listScopePackages
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: limit
          in: query
          description: The maximum number of packages to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: page
          in: query
          description: The page number of packages to return
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Package"
                  total:
                    type: integer
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    post:
      summary: Create a new package
      description: Creates a new package in a scope
      operationId: createPackage
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      requestBody:
        description: Package properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreatePackageRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Package"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}:
    get:
      summary: Get package details
      description: Returns details of a package
      operationId: getPackage
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Package"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    patch:
      summary: Update package
      description: Updates the details of a package
      operationId: updatePackage
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      requestBody:
        description: Package properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePackageRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Package"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope member / User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    delete:
      summary: Delete package
      description: Deletes a package if the package has no versions
      operationId: deletePackage
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request / Package has versions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/dependents:
    get:
      summary: List package dependents
      description: Returns a list of packages that depend on a package
      operationId: listPackageDependents
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: limit
          in: query
          description: The maximum number of dependents to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: page
          in: query
          description: The page number of dependents to return
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: versions_per_package_limit
          in: query
          description: The maximum number of versions per package to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 10
            default: 10
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Dependent"
                  total:
                    type: integer
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /scopes/{scope}/packages/{package}/score:
    get:
      summary: Get package score
      description: Returns the package score details
      operationId: getPackageScore
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageScore"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /scopes/{scope}/packages/{package}/versions:
    get:
      summary: List package versions
      description: Returns a list of versions of a package
      operationId: listPackageVersions
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PackageVersionWithUser"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /scopes/{scope}/packages/{package}/versions/{version}:
    get:
      summary: Get package version details
      description: Returns details of a package version
      operationId: getPackageVersion
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageVersion"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    post:
      summary: Create a new package version
      description: Creates a new version of a package
      operationId: createPackageVersion
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
        - name: config
          in: query
          description: The path to the config file
          required: true
          schema:
            type: string
      requestBody:
        description: A gzipped tarball containing all files in the package version
        required: true
        content:
          application/octet-stream: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublishingTask"
        "400":
          description: Invalid request / Package version already exists
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized / User is not a scope member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    patch:
      summary: Update package version
      description: Updates the details of a package version (e.g., yank/unyank)
      operationId: updatePackageVersion
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      requestBody:
        description: Package version properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePackageVersionRequest"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    delete:
      summary: Delete package version
      description: Deletes a package version. Only allowed for versions published in the last 24 hours with no dependents.
      operationId: deletePackageVersion
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request / Version has dependents / Version too old
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not a scope admin
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/dependencies:
    get:
      summary: List the dependencies of a package version
      description: Returns a list of dependencies of a package
      operationId: listDependencies
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Dependency"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/dependencies/graph:
    get:
      summary: Get the dependency graph of a package version
      description: Returns the full dependency graph of a package version
      operationId: getDependencyGraph
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DependencyGraphItem"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/downloads:
    get:
      summary: Get package downloads
      description: Returns download statistics for a package over the last 90 days
      operationId: getPackageDownloads
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageDownloads"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/source:
    get:
      summary: Get package version source
      description: Returns the rendered source code of a file or a directory listing for a package version
      operationId: getPackageVersionSource
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package (or "latest")
          required: true
          schema:
            type: string
        - name: path
          in: query
          description: The file path to retrieve. Defaults to "/" (root directory listing).
          required: false
          schema:
            type: string
            default: /
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageVersionSource"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version or path not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/docs:
    get:
      summary: Get package version documentation
      description: Returns the generated documentation for a package version
      operationId: getPackageVersionDocs
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package (or "latest")
          required: true
          schema:
            type: string
        - name: all_symbols
          in: query
          description: If present, returns documentation for all symbols
          required: false
          schema:
            type: boolean
        - name: entrypoint
          in: query
          description: The entrypoint to get documentation for
          required: false
          schema:
            type: string
        - name: symbol
          in: query
          description: The symbol to get documentation for
          required: false
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageVersionDocs"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version or symbol not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/docs/search:
    get:
      summary: Get package version documentation search index
      description: Returns the search index for a package version's documentation
      operationId: getPackageVersionDocsSearch
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package (or "latest")
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                description: Search index for documentation
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/docs/search_structured:
    get:
      summary: Get structured documentation search index
      description: Returns the structured search index (all symbols) for a package version's documentation. This is a SymbolContentCtx from deno_doc.
      operationId: getPackageVersionDocsSearchStructured
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package (or "latest")
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                description: Structured symbol content for all symbols in the package version
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Package version not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/publishing_tasks:
    get:
      summary: List package publishing tasks
      description: Returns a list of publishing tasks for a package. Requires write access to the scope.
      operationId: listPackagePublishingTasks
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PublishingTask"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User does not have write access to the scope
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /scopes/{scope}/packages/{package}/versions/{version}/provenance:
    post:
      summary: Upload provenance statement
      description: Uploads a provenance statement for a package version
      operationId: uploadProvenance
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
        - name: package
          in: path
          description: The name of the package
          required: true
          schema:
            $ref: "#/components/schemas/PackageName"
        - name: version
          in: path
          description: The version of the package
          required: true
          schema:
            $ref: "#/components/schemas/Version"
      requestBody:
        description: Provenance bundle
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProvenanceStatementRequest"
      responses:
        "204":
          description: OK, no content
        "400":
          description: Invalid request / Invalid provenance
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: User is not authorized to publish
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user:
    get:
      summary: Get authenticated user's details
      description: Returns details of the authenticated user
      operationId: getSelfUser
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FullUser"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/scopes:
    get:
      summary: List authenticated user's scopes
      description: Returns a list of scopes that the authenticated user is a member of
      operationId: listSelfUserScopes
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Scope"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/member/{scope}:
    get:
      summary: Get authenticated user's scope member details
      description: Returns details of the authenticated user's membership of a scope
      operationId: getSelfUserScopeMember
      parameters:
        - name: scope
          in: path
          description: The name of the scope
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScopeMember"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/invites:
    get:
      summary: List authenticated user's scope invites
      description: Returns a list of invites to scopes that the authenticated user has received
      operationId: listSelfUserInvites
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScopeInvite"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/invites/{scope}:
    post:
      summary: Accept scope invite
      description: Accepts an invite to a scope
      operationId: acceptScopeInvite
      parameters:
        - name: scope
          in: path
          description: The name of the scope to accept the invite for
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScopeMember"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope invite not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    delete:
      summary: Decline scope invite
      description: Declines an invite to a scope
      operationId: declineScopeInvite
      parameters:
        - name: scope
          in: path
          description: The name of the scope to decline the invite for
          required: true
          schema:
            $ref: "#/components/schemas/ScopeName"
      responses:
        "204":
          description: OK, no content
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Scope invite not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /users/{id}:
    get:
      summary: Get user details
      description: Returns details of a user
      operationId: getUser
      parameters:
        - name: id
          in: path
          description: The ID of the user
          required: true
          schema:
            $ref: "#/components/schemas/UserId"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          description: User not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /users/{id}/scopes:
    get:
      summary: List user's scopes
      description: Returns a list of scopes that a user is a member of
      operationId: listUserScopes
      parameters:
        - name: id
          in: path
          description: The ID of the user
          required: true
          schema:
            $ref: "#/components/schemas/UserId"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Scope"
        "404":
          description: User not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/tokens:
    get:
      summary: List personal access tokens
      description: Returns a list of tokens for the authenticated user
      operationId: listTokens
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Token"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Create personal access token
      description: Creates a new personal access token for the authenticated user
      operationId: createToken
      requestBody:
        description: Token properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTokenRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatedToken"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: Token type does not allow creating tokens
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/tokens/{id}:
    delete:
      summary: Delete personal access token
      description: Deletes a personal access token
      operationId: deleteToken
      parameters:
        - name: id
          in: path
          description: The ID of the token
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: OK, no content
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: Token type does not allow deleting tokens
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Token not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /user/tickets:
    get:
      summary: List authenticated user's tickets
      description: Returns a list of support tickets created by the authenticated user
      operationId: listSelfUserTickets
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Ticket"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /tickets:
    post:
      summary: Create support ticket
      description: Creates a new support ticket
      operationId: createTicket
      requestBody:
        description: Ticket properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTicketRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Ticket"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /tickets/{id}:
    get:
      summary: Get ticket details
      description: Returns details of a support ticket
      operationId: getTicket
      parameters:
        - name: id
          in: path
          description: The ID of the ticket
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TicketOverview"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Ticket not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Add message to ticket
      description: Adds a message to a support ticket
      operationId: addTicketMessage
      parameters:
        - name: id
          in: path
          description: The ID of the ticket
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Message content
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTicketMessageRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TicketMessage"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Ticket not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /authorizations:
    post:
      summary: Create authorization
      description: Starts an authorization flow
      operationId: createAuthorization
      requestBody:
        description: Authorization properties
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateAuthorizationRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateAuthorizationResponse"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /authorizations/details/{code}:
    get:
      summary: Get authorization details
      description: Returns details of an authorization
      operationId: getAuthorizationDetails
      parameters:
        - name: code
          in: path
          description: The code of the authorization
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Authorization"
        "404":
          description: Authorization not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /authorizations/approve/{code}:
    post:
      summary: Approve authorization
      description: Approves an authorization
      operationId: approveAuthorization
      parameters:
        - name: code
          in: path
          description: The code of the authorization
          required: true
          schema:
            type: string
      responses:
        "204":
          description: OK, no content
        "404":
          description: Authorization not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /authorizations/deny/{code}:
    post:
      summary: Deny authorization
      description: Denies an authorization
      operationId: denyAuthorization
      parameters:
        - name: code
          in: path
          description: The code of the authorization
          required: true
          schema:
            type: string
      responses:
        "204":
          description: OK, no content
        "404":
          description: Authorization not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /authorizations/exchange:
    post:
      summary: Exchange authorization code for access token
      description: Exchanges an authorization code for an access token
      operationId: exchangeAuthorizationCode
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthorizationExchangeRequest"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthorizationExchangeResponse"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /publishing_tasks/{id}:
    get:
      summary: Get publishing task details
      description: Returns details of a publishing task
      operationId: getPublishingTask
      parameters:
        - name: id
          in: path
          description: The ID of the publishing task
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublishingTask"
        "404":
          description: Publishing task not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /stats:
    get:
      summary: Get stats
      description: Returns stats about the registry
      operationId: getStats
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Stats"

  /metrics:
    get:
      summary: Get metrics
      description: Returns metrics about the registry (package counts, user counts, etc.)
      operationId: getMetrics
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Metrics"

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        The request is authorized by a bearer issued to the user. The token
        is sent in a header that looks like this:
        `Authorization: Bearer {token}`, for example: `Authorization: Bearer
        jsrw_AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRr`.

  schemas:
    Error:
      type: object
      properties:
        code:
          type: string
          description: The error code.
        message:
          type: string
          description: The error message.
      required:
        - code
        - message

    ScopeName:
      type: string
      pattern: ^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$
      description: The name of a scope. This must not be @ prefixed.
      example: denoland

    Scope:
      type: object
      description: Partial scope information.
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        description:
          type: string
          description: The description of the scope.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the scope was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the scope was last updated.
      required:
        - scope
        - description
        - createdAt
        - updatedAt

    FullScope:
      type: object
      description: Full scope information (includes quotas and settings).
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        description:
          type: string
          description: The description of the scope.
        creator:
          $ref: "#/components/schemas/User"
        quotas:
          type: object
          properties:
            packageUsage:
              type: integer
              description: The number of packages in the scope.
              example: 3
            packageLimit:
              type: integer
              description: The maximum number of packages allowed in the scope.
              example: 10
            newPackagePerWeekUsage:
              type: integer
              description: The number of new packages created in the scope in the last week.
              example: 1
            newPackagePerWeekLimit:
              type: integer
              description: The maximum number of new packages allowed to be created in the scope in a week.
              example: 5
            publishAttemptsPerWeekUsage:
              type: integer
              description: The number of times packages in the scope have been published in the last week.
              example: 1
            publishAttemptsPerWeekLimit:
              type: integer
              description: The maximum number of times packages in the scope can be published in a week.
              example: 5
        ghActionsVerifyActor:
          type: boolean
          description: Whether to verify the actor of a GitHub Actions run when authenticating publishing with a GitHub Actions OIDC token.
        requirePublishingFromCI:
          type: boolean
          description: Whether to require publishing from a CI environment. This disables publishing from a local environment.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the scope was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the scope was last updated.
      required:
        - scope
        - description
        - creator
        - quotas
        - ghActionsVerifyActor
        - requirePublishingFromCI
        - createdAt
        - updatedAt

    CreateScopeRequest:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        description:
          type: string
          description: The description of the scope.
      required:
        - scope
        - description

    UpdateScopeRequest:
      oneOf:
        - type: object
          properties:
            ghActionsVerifyActor:
              type: boolean
              description: Whether to verify the actor of a GitHub Actions run when authenticating publishing with a GitHub Actions OIDC token.
          required:
            - ghActionsVerifyActor
        - type: object
          properties:
            requirePublishingFromCI:
              type: boolean
              description: Whether to require publishing from a CI environment. This disables publishing from a local environment.
          required:
            - requirePublishingFromCI
        - type: object
          properties:
            description:
              type: string
              nullable: true
              description: The description of the scope.
          required:
            - description

    ScopeMember:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        user:
          $ref: "#/components/schemas/User"
        isAdmin:
          type: boolean
          description: Whether the user is an admin of the scope.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the user was added to the scope.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the scope member roles were last updated.
      required:
        - scope
        - user
        - isAdmin
        - createdAt
        - updatedAt

    ScopeInvite:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        targetUser:
          allOf:
            - $ref: "#/components/schemas/User"
            - description: The user that the invite is for.
        requestingUser:
          allOf:
            - $ref: "#/components/schemas/User"
            - description: The user that sent the invite.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the invite was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the invite was last updated.
      required:
        - scope
        - targetUser
        - requestingUser
        - createdAt
        - updatedAt

    UserId:
      type: string
      format: uuid
      description: The ID of a user.

    User:
      type: object
      description: Public user information.
      properties:
        id:
          $ref: "#/components/schemas/UserId"
        name:
          type: string
          description: The user's display name.
          example: Ryan Dahl
        avatarUrl:
          type: string
          description: The URL to the user's avatar.
          example: https://avatars.githubusercontent.com/u/80?v=4
        githubId:
          type: integer
          nullable: true
          description: The user's GitHub ID.
          example: 80
        createdAt:
          type: string
          format: date-time
          description: The date and time when the user profile was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the user profile was last updated.
      required:
        - id
        - name
        - avatarUrl
        - createdAt
        - updatedAt

    FullUser:
      type: object
      description: Full user information (only available to the authenticated user).
      properties:
        id:
          $ref: "#/components/schemas/UserId"
        name:
          type: string
          description: The user's display name.
          example: Ryan Dahl
        email:
          type: string
          nullable: true
          description: The user's email address.
          example: ry@example.com
        avatarUrl:
          type: string
          description: The URL to the user's avatar.
          example: https://avatars.githubusercontent.com/u/80?v=4
        githubId:
          type: integer
          nullable: true
          description: The user's GitHub ID.
          example: 80
        isBlocked:
          type: boolean
          description: Whether the user is blocked from using the registry.
        isStaff:
          type: boolean
          description: Whether the user is a staff member.
        scopeUsage:
          type: integer
          description: The number of scopes the user created.
          example: 3
        scopeLimit:
          type: integer
          description: The maximum number of scopes the user can create.
          example: 10
        inviteCount:
          type: integer
          description: The number of invites pending for the user.
          example: 3
        newerTicketMessagesCount:
          type: integer
          description: The number of unread ticket messages.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the user profile was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the user profile was last updated.
      required:
        - id
        - name
        - avatarUrl
        - isBlocked
        - isStaff
        - scopeUsage
        - scopeLimit
        - inviteCount
        - newerTicketMessagesCount
        - createdAt
        - updatedAt

    AddScopeMemberRequest:
      oneOf:
        - type: object
          properties:
            githubLogin:
              type: string
              description: The GitHub login of the user to add to the scope.
              example: ry
          required:
            - githubLogin
        - type: object
          properties:
            id:
              type: string
              format: uuid
              description: The ID of the user to add to the scope.
          required:
            - id

    UpdateScopeMemberRequest:
      type: object
      properties:
        isAdmin:
          type: boolean
          description: Whether the user should be an admin of the scope.
      required:
        - isAdmin

    GitHubRepository:
      type: object
      properties:
        id:
          type: integer
          description: The GitHub repository ID.
        owner:
          type: string
          description: The GitHub user / organization of the repository.
          example: denoland
        name:
          type: string
          description: The GitHub repository name.
          example: deno
        createdAt:
          type: string
          format: date-time
          description: The date and time when the GitHub repository link was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the GitHub repository link was last updated.
      required:
        - id
        - owner
        - name
        - createdAt
        - updatedAt

    PackageName:
      type: string
      pattern: ^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$
      description: The name of a package.
      example: fmt

    Package:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        name:
          $ref: "#/components/schemas/PackageName"
        description:
          type: string
          description: The description of the package.
          example: A module for formatting strings.
        runtimeCompat:
          $ref: "#/components/schemas/RuntimeCompat"
        createdAt:
          type: string
          format: date-time
          description: The date and time when the package was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the package was last updated.
        githubRepository:
          $ref: "#/components/schemas/GitHubRepository"
        score:
          type: integer
          nullable: true
          description: The package score percentage (0-100).
        versionCount:
          type: integer
          description: The number of versions of the package.
        dependencyCount:
          type: integer
          description: The number of dependencies of the package.
        dependentCount:
          type: integer
          description: The number of packages that depend on this package.
        latestVersion:
          type: string
          nullable: true
          description: The latest version of the package.
        whenFeatured:
          type: string
          format: date-time
          nullable: true
          description: The date and time when the package was featured.
        isArchived:
          type: boolean
          description: Whether the package is archived.
        readmeSource:
          type: string
          enum: ["readme", "jsdoc"]
          description: The source of the package readme.
      required:
        - scope
        - name
        - description
        - createdAt
        - updatedAt
        - versionCount
        - dependencyCount
        - dependentCount
        - isArchived
        - readmeSource

    CreatePackageRequest:
      type: object
      properties:
        package:
          $ref: "#/components/schemas/PackageName"
      required:
        - package

    UpdatePackageRequest:
      oneOf:
        - type: object
          properties:
            description:
              type: string
              pattern: "^.{0,250}$"
              description: The description of the package.
          required:
            - description
        - type: object
          properties:
            githubRepository:
              type: object
              nullable: true
              properties:
                owner:
                  type: string
                  description: The GitHub user / organization of the repository.
                  example: denoland
                name:
                  type: string
                  description: The GitHub repository name.
                  example: deno
              required:
                - owner
                - name
          required:
            - githubRepository
        - type: object
          properties:
            runtimeCompat:
              $ref: "#/components/schemas/RuntimeCompat"
          required:
            - runtimeCompat
        - type: object
          properties:
            isArchived:
              type: boolean
              description: Whether this package should be archived or not.
          required:
            - isArchived
        - type: object
          properties:
            isFeatured:
              type: boolean
              description: Whether this package should be featured or not (staff only).
          required:
            - isFeatured
        - type: object
          properties:
            readmeSource:
              type: string
              enum: ["readme", "jsdoc"]
              description: The source of the package readme.
          required:
            - readmeSource

    RuntimeCompat:
      type: object
      properties:
        browser:
          type: boolean
          nullable: true
          description: Whether the package is compatible with web browsers.
        deno:
          type: boolean
          nullable: true
          description: Whether the package is compatible with Deno.
        node:
          type: boolean
          nullable: true
          description: Whether the package is compatible with Node.js.
        workerd:
          type: boolean
          nullable: true
          description: Whether the package is compatible with workerd.
        bun:
          type: boolean
          nullable: true
          description: Whether the package is compatible with Bun.

    Version:
      type: string
      description: A semantic version.
      example: 1.2.3

    Dependent:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        package:
          $ref: "#/components/schemas/PackageName"
        versions:
          type: array
          items:
            $ref: "#/components/schemas/Version"
        totalVersions:
          type: integer
          description: The total number of versions of the package.
      required:
        - scope
        - package
        - versions
        - totalVersions

    PackageVersion:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        package:
          $ref: "#/components/schemas/PackageName"
        version:
          $ref: "#/components/schemas/Version"
        yanked:
          type: boolean
          description: Whether the version has been yanked.
        usesNpm:
          type: boolean
          description: Whether the version uses npm dependencies.
        newerVersionsCount:
          type: integer
          description: The number of newer versions.
        lifetimeDownloadCount:
          type: integer
          description: The total number of downloads for this version.
        rekorLogId:
          type: string
          nullable: true
          description: Rekor log ID for the published package version.
        license:
          type: string
          nullable: true
          description: The license of the package version.
        readmePath:
          type: string
          nullable: true
          description: The path to the readme file in the package.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the package version was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the package version was last updated.
      required:
        - scope
        - package
        - version
        - yanked
        - usesNpm
        - newerVersionsCount
        - lifetimeDownloadCount
        - createdAt
        - updatedAt

    UpdatePackageVersionRequest:
      type: object
      properties:
        yanked:
          type: boolean
          description: Whether the version is yanked or not.
      required:
        - yanked

    PackageVersionWithUser:
      type: object
      properties:
        scope:
          $ref: "#/components/schemas/ScopeName"
        package:
          $ref: "#/components/schemas/PackageName"
        version:
          $ref: "#/components/schemas/Version"
        user:
          allOf:
            - $ref: "#/components/schemas/User"
          description: The user who published this version. May be null if the user has been deleted.
        yanked:
          type: boolean
          description: Whether the version has been yanked.
        usesNpm:
          type: boolean
          description: Whether the version uses npm dependencies.
        newerVersionsCount:
          type: integer
          description: The number of newer versions.
        lifetimeDownloadCount:
          type: integer
          description: The total number of downloads for this version.
        rekorLogId:
          type: string
          nullable: true
          description: Rekor log ID for the published package version.
        readmePath:
          type: string
          nullable: true
          description: The path to the readme file in the package.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the package version was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the package version was last updated.
      required:
        - scope
        - package
        - version
        - yanked
        - usesNpm
        - newerVersionsCount
        - lifetimeDownloadCount
        - createdAt
        - updatedAt

    PublishingTask:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the publishing task.
        status:
          type: string
          description: The status of the publishing task.
          enum: ["pending", "processing", "processed", "success", "failure"]
        error:
          type: object
          nullable: true
          properties:
            code:
              type: string
              description: The error code.
            message:
              type: string
              description: The error message.
        user:
          allOf:
            - $ref: "#/components/schemas/User"
          description: The user who initiated the publishing task. May be null if the user has been deleted.
        packageScope:
          $ref: "#/components/schemas/ScopeName"
        packageName:
          $ref: "#/components/schemas/PackageName"
        packageVersion:
          $ref: "#/components/schemas/Version"
        createdAt:
          type: string
          format: date-time
          description: The date and time when the publishing task was created.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the publishing task was last updated.
      required:
        - id
        - status
        - packageScope
        - packageName
        - packageVersion
        - createdAt
        - updatedAt

    Dependency:
      type: object
      properties:
        kind:
          type: string
          description: The kind of dependency.
          enum: ["jsr", "npm"]
        name:
          type: string
          description: The fully qualified name of the dependency.
          example: "@std/fs"
        constraint:
          type: string
          description: The semver constraint of the dependency.
          example: "^0.50.0"
        path:
          type: string
          description: The path being imported from the dependency. This may be the empty string if the "default entrypoint" is being imported.
          example: "/exists"
      required:
        - kind
        - name
        - constraint
        - path

    Authorization:
      type: object
      properties:
        code:
          type: string
          description: The authorization code.
        permissions:
          type: array
          nullable: true
          description: The permissions that the token will have.
          items:
            $ref: "#/components/schemas/Permission"
        expiresAt:
          type: string
          format: date-time
          description: The date and time until which the authorization can be approved / exchanged.
      required:
        - code
        - expiresAt

    Permission:
      oneOf:
        - type: object
          properties:
            permission:
              type: string
              description: The permission name.
              enum: ["package/publish"]
            scope:
              $ref: "#/components/schemas/ScopeName"
          required:
            - permission
            - scope
        - type: object
          properties:
            permission:
              type: string
              description: The permission name.
              enum: ["package/publish"]
            scope:
              $ref: "#/components/schemas/ScopeName"
            package:
              $ref: "#/components/schemas/PackageName"
          required:
            - permission
            - scope
            - package
        - type: object
          properties:
            permission:
              type: string
              description: The permission name.
              enum: ["package/publish"]
            scope:
              $ref: "#/components/schemas/ScopeName"
            package:
              $ref: "#/components/schemas/PackageName"
            version:
              $ref: "#/components/schemas/Version"
            tarballHash:
              type: string
              description: The SHA256 hash of the tarball.
          required:
            - permission
            - scope
            - package
            - version
            - tarballHash

    CreateAuthorizationRequest:
      type: object
      properties:
        challenge:
          type: string
          description: The challenge that will later be needed to retrieve the token after authorization.
          example: 1234567890abcdef
        permissions:
          type: array
          description: The permissions that the token will have.
          items:
            $ref: "#/components/schemas/Permission"
      required:
        - challenge

    CreateAuthorizationResponse:
      type: object
      properties:
        verificationUrl:
          type: string
          description: The URL that the user should visit to approve the authorization.
        code:
          type: string
          description: The authorization code that the user can manually enter if they can not directly visit the link.
        exchangeToken:
          type: string
          description: The token that can be used to exchange for a device token after the authorization has been approved.
        pollInterval:
          type: integer
          description: The number of seconds that should be waited between polling the status of the authorization.
        expiresAt:
          type: string
          format: date-time
          description: The date and time until which the authorization can be approved / exchanged.
      required:
        - verificationUrl
        - code
        - exchangeToken
        - pollInterval
        - expiresAt

    AuthorizationExchangeRequest:
      type: object
      properties:
        exchangeToken:
          type: string
          description: The token that can be used to exchange for a device token after the authorization has been approved.
        verifier:
          type: string
          description: The verifier that was used to generate the challenge.
      required:
        - exchangeToken
        - verifier

    AuthorizationExchangeResponse:
      type: object
      properties:
        token:
          type: string
          description: The device token that can be used to authenticate requests.
        user:
          allOf:
            - $ref: "#/components/schemas/User"
            - description: The user that the token is for.
      required:
        - token
        - user

    Stats:
      type: object
      properties:
        newest:
          type: array
          description: The newest packages.
          items:
            $ref: "#/components/schemas/StatsPackage"
        updated:
          type: array
          description: The recently uploaded package versions.
          items:
            $ref: "#/components/schemas/StatsPackageVersion"
        featured:
          type: array
          description: The featured packages
          items:
            $ref: "#/components/schemas/StatsPackage"
      required:
        - newest
        - updated
        - featured

    StatsPackage:
      type: object
      properties:
        scope:
          type: string
          description: The scope of the package.
        name:
          type: string
          description: The name of the package.
      required:
        - scope
        - name

    StatsPackageVersion:
      type: object
      properties:
        scope:
          type: string
          description: The scope of the package.
        package:
          type: string
          description: The name of the package.
        version:
          type: string
          description: The version string.
      required:
        - scope
        - package
        - version

    PackageScore:
      type: object
      properties:
        hasReadme:
          type: boolean
        hasReadmeExamples:
          type: boolean
        allEntrypointsDocs:
          type: boolean
        percentageDocumentedSymbols:
          type: number
        allFastCheck:
          type: boolean
        hasProvenance:
          type: boolean
        hasDescription:
          type: boolean
        atLeastOneRuntimeCompatible:
          type: boolean
        multipleRuntimesCompatible:
          type: boolean
        total:
          type: integer
      required:
        - hasReadme
        - hasReadmeExamples
        - allEntrypointsDocs
        - percentageDocumentedSymbols
        - allFastCheck
        - hasProvenance
        - hasDescription
        - atLeastOneRuntimeCompatible
        - multipleRuntimesCompatible
        - total

    TokenType:
      type: string
      enum: ["web", "device", "personal"]
      description: The type of token.

    Token:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the token.
        description:
          type: string
          nullable: true
          description: The description of the token.
        userId:
          $ref: "#/components/schemas/UserId"
        type:
          $ref: "#/components/schemas/TokenType"
        expiresAt:
          type: string
          format: date-time
          nullable: true
          description: The date and time when the token expires.
        permissions:
          type: array
          nullable: true
          items:
            $ref: "#/components/schemas/Permission"
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the token was last updated.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the token was created.
      required:
        - id
        - userId
        - type
        - updatedAt
        - createdAt

    CreateTokenRequest:
      type: object
      properties:
        description:
          type: string
          description: The description of the token.
        expiresAt:
          type: string
          format: date-time
          nullable: true
          description: The date and time when the token expires.
        permissions:
          type: array
          nullable: true
          description: The permissions that the token will have. Must contain exactly one element if provided.
          items:
            $ref: "#/components/schemas/Permission"
      required:
        - description

    CreatedToken:
      type: object
      properties:
        secret:
          type: string
          description: The secret value of the token. This is only returned once when the token is created.
        token:
          $ref: "#/components/schemas/Token"
      required:
        - secret
        - token

    TicketKind:
      type: string
      enum: [
        "user_scope_quota_increase",
        "scope_package_quota_increase",
        "other",
      ]
      description: The kind of support ticket.

    Ticket:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the ticket.
        kind:
          $ref: "#/components/schemas/TicketKind"
        creator:
          $ref: "#/components/schemas/User"
        meta:
          type: object
          description: Additional metadata for the ticket.
        closed:
          type: boolean
          description: Whether the ticket is closed.
        messages:
          type: array
          items:
            $ref: "#/components/schemas/TicketMessage"
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the ticket was last updated.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the ticket was created.
      required:
        - id
        - kind
        - creator
        - meta
        - closed
        - messages
        - updatedAt
        - createdAt

    TicketOverview:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The ID of the ticket.
        kind:
          $ref: "#/components/schemas/TicketKind"
        creator:
          $ref: "#/components/schemas/User"
        meta:
          type: object
          description: Additional metadata for the ticket.
        closed:
          type: boolean
          description: Whether the ticket is closed.
        events:
          type: array
          items:
            $ref: "#/components/schemas/TicketEvent"
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the ticket was last updated.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the ticket was created.
      required:
        - id
        - kind
        - creator
        - meta
        - closed
        - events
        - updatedAt
        - createdAt

    TicketEvent:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum: ["message"]
            message:
              type: object
              properties:
                message:
                  type: string
                createdAt:
                  type: string
                  format: date-time
                updatedAt:
                  type: string
                  format: date-time
            user:
              $ref: "#/components/schemas/User"
          required:
            - kind
            - message
            - user
        - type: object
          properties:
            kind:
              type: string
              enum: ["auditLog"]
            auditLog:
              type: object
              properties:
                action:
                  type: string
                isSudo:
                  type: boolean
                meta:
                  type: object
                createdAt:
                  type: string
                  format: date-time
            user:
              $ref: "#/components/schemas/User"
          required:
            - kind
            - auditLog
            - user

    TicketMessage:
      type: object
      properties:
        author:
          $ref: "#/components/schemas/User"
        message:
          type: string
          description: The message content.
        updatedAt:
          type: string
          format: date-time
          description: The date and time when the message was last updated.
        createdAt:
          type: string
          format: date-time
          description: The date and time when the message was created.
      required:
        - author
        - message
        - updatedAt
        - createdAt

    CreateTicketRequest:
      type: object
      properties:
        kind:
          $ref: "#/components/schemas/TicketKind"
        meta:
          type: object
          description: Additional metadata for the ticket.
        message:
          type: string
          description: The initial message for the ticket.
      required:
        - kind
        - meta
        - message

    CreateTicketMessageRequest:
      type: object
      properties:
        message:
          type: string
          description: The message content.
      required:
        - message

    DependencyGraphItem:
      type: object
      properties:
        id:
          type: integer
          description: The unique identifier for this item in the graph.
        dependency:
          type: object
          description: The dependency information.
        children:
          type: array
          items:
            type: integer
          description: IDs of child dependencies.
        size:
          type: integer
          nullable: true
          description: Size in bytes of the dependency.
        mediaType:
          type: string
          nullable: true
          description: The media type of the file.
      required:
        - id
        - dependency
        - children

    DownloadKind:
      type: string
      enum: ["jsr_meta", "npm_tarball"]
      description: The type of download.

    DownloadDataPoint:
      type: object
      properties:
        timeBucket:
          type: string
          format: date-time
          description: The time bucket for this data point.
        kind:
          $ref: "#/components/schemas/DownloadKind"
        count:
          type: integer
          description: The number of downloads in this time bucket.
      required:
        - timeBucket
        - kind
        - count

    PackageDownloads:
      type: object
      properties:
        total:
          type: array
          items:
            $ref: "#/components/schemas/DownloadDataPoint"
          description: Total download data points for the package.
        recentVersions:
          type: array
          items:
            type: object
            properties:
              version:
                $ref: "#/components/schemas/Version"
              downloads:
                type: array
                items:
                  $ref: "#/components/schemas/DownloadDataPoint"
            required:
              - version
              - downloads
          description: Download data points for recent versions.
      required:
        - total
        - recentVersions

    PackageVersionDocs:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum: ["content"]
            version:
              $ref: "#/components/schemas/PackageVersion"
            css:
              type: string
              description: CSS for styling the documentation.
            comrakCss:
              type: string
              description: CSS for comrak markdown rendering.
            script:
              type: string
              description: JavaScript for the documentation.
            breadcrumbs:
              type: object
              nullable: true
              description: Breadcrumb navigation context. Structure defined by deno_doc's BreadcrumbsCtx.
            toc:
              type: object
              nullable: true
              description: Table of contents context. Structure defined by deno_doc's ToCCtx.
            main:
              type: object
              description: >-
                The main documentation content. A tagged union with "kind" and "value" fields.
                Kind is one of "allSymbols", "file", "index", or "symbol".
                Structure defined by deno_doc types.
          required:
            - kind
            - version
            - css
            - comrakCss
            - script
            - main
        - type: object
          properties:
            kind:
              type: string
              enum: ["redirect"]
            symbol:
              type: string
              description: The symbol to redirect to.
          required:
            - kind
            - symbol

    PackageVersionSource:
      type: object
      properties:
        version:
          $ref: "#/components/schemas/PackageVersion"
        css:
          type: string
          description: CSS for styling the source view.
        comrakCss:
          type: string
          description: CSS for comrak markdown rendering.
        script:
          type: string
          description: JavaScript for the source view.
        source:
          $ref: "#/components/schemas/Source"
      required:
        - version
        - css
        - comrakCss
        - script
        - source

    Source:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum: ["dir"]
            entries:
              type: array
              items:
                $ref: "#/components/schemas/SourceDirEntry"
          required:
            - kind
            - entries
        - type: object
          properties:
            kind:
              type: string
              enum: ["file"]
            size:
              type: integer
              description: Size of the file in bytes.
            view:
              type: string
              nullable: true
              description: HTML-rendered source code view. Null for binary files.
          required:
            - kind
            - size

    SourceDirEntry:
      type: object
      properties:
        name:
          type: string
          description: The name of the file or directory.
        size:
          type: integer
          description: Size in bytes.
        kind:
          type: string
          enum: ["dir", "file"]
          description: Whether this entry is a directory or file.
      required:
        - name
        - size
        - kind

    ProvenanceStatementRequest:
      type: object
      properties:
        bundle:
          type: object
          description: The SLSA provenance bundle.
      required:
        - bundle

    Metrics:
      type: object
      properties:
        packages:
          type: integer
          description: Total number of packages.
        packages1d:
          type: integer
          description: Number of packages created in the last day.
        packages7d:
          type: integer
          description: Number of packages created in the last 7 days.
        packages30d:
          type: integer
          description: Number of packages created in the last 30 days.
        users:
          type: integer
          description: Total number of users.
        users1d:
          type: integer
          description: Number of users created in the last day.
        users7d:
          type: integer
          description: Number of users created in the last 7 days.
        users30d:
          type: integer
          description: Number of users created in the last 30 days.
        packageVersions:
          type: integer
          description: Total number of package versions.
        packageVersions1d:
          type: integer
          description: Number of package versions created in the last day.
        packageVersions7d:
          type: integer
          description: Number of package versions created in the last 7 days.
        packageVersions30d:
          type: integer
          description: Number of package versions created in the last 30 days.
      required:
        - packages
        - packages1d
        - packages7d
        - packages30d
        - users
        - users1d
        - users7d
        - users30d
        - packageVersions
        - packageVersions1d
        - packageVersions7d
        - packageVersions30d
