{"version":3,"sources":["../../../src/lib/client.ts","../../../src/lib/api/core/BaseHttpRequest.ts","../../../src/lib/api/core/request.ts","../../../src/lib/isomorphic.ts","../../../src/lib/api/core/ApiError.ts","../../../src/lib/api/core/CancelablePromise.ts","../../../src/lib/api/core/AxiosHttpRequest.ts","../../../src/lib/api/services/AuthorizationService.ts","../../../src/lib/api/services/CircuitsService.ts","../../../src/lib/api/services/InternalService.ts","../../../src/lib/api/services/ProofsService.ts","../../../src/lib/api/services/TokenService.ts","../../../src/lib/api/ApiClient.ts","../../../src/lib/config.ts","../../../src/lib/logging.ts","../../../src/lib/utils.ts","../../../src/lib/index.ts"],"names":["readFile","stat","path","gzip","walk","tar","Tar","BaseHttpRequest","config","axios","AxiosError","pRetry","File","FormData","ApiError","request","response","message","CancelError","CancelablePromise","#isResolved","#isRejected","#isCancelled","#cancelHandlers","#promise","#resolve","#reject","executor","resolve","reject","onResolve","value","onReject","reason","onCancel","cancelHandler","onFulfilled","onRejected","onFinally","error","isDefined","isString","isStringWithValue","isBlob","isFormData","isSuccess","status","base64","str","getQueryString","params","qs","append","key","process","v","k","getUrl","options","encoder","substring","group","url","getFormData","formData","_","resolver","getHeaders","token","username","password","additionalHeaders","formHeaders","headers","credentials","getRequestBody","shouldRetry","sendRequest","body","axiosClient","source","requestConfig","axiosError","getResponseHeader","responseHeader","content","getResponseBody","catchErrorCodes","result","errorStatus","errorStatusText","errorBody","startTime","getElapsedTime","ellapsedMilliseconds","ellapsedSeconds","ellapsedMinutes","logPrefix","responseBody","responseMessage","errorMessage","AxiosHttpRequest","AuthorizationService","httpRequest","requestBody","sindriTeamId","name","apikeyId","CircuitsService","circuitId","includeVerificationKey","InternalService","limit","offset","projectId","projectName","proofId","teamSlug","ProofsService","includeProof","includePublic","includeSmartContractCalldata","TokenService","ApiClient","HttpRequest","envPaths","z","ConfigSchema","defaultConfig","pino","createLogger","level","logger","cachedDefaultMeta","getDefaultMeta","cache","raiseExceptions","SINDRI_META","validationFilter","validateMetaAndMergeWithDefaults","meta","defaultMeta","validationError","validateMetaEntry","keyRegex","SindriClient","_SindriClient","authOptions","retryOptions","versionTag","project","tags","tag","projectStats","tarballFilename","tarballContent","sindriJsonPath","sindriJsonContent","sindriJson","circuitName","files","file","sindriJsonFilename","a","b","tarStream","code","sindriJsonFile","tarball","gzippedTarball","tarFile","proofInput","verify","lib_default"],"mappings":"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","sourcesContent":["import { readFile, stat } from \"fs/promises\";\nimport path from \"path\";\nimport type { Readable } from \"stream\";\n\nimport gzip from \"gzip-js\";\nimport walk from \"ignore-walk\";\nimport type { WrapOptions as RetryOptions } from \"retry\";\nimport tar from \"tar\";\nimport Tar from \"tar-js\";\n\nimport { ApiClient, CircuitType, JobStatus, OpenAPIConfig } from \"lib/api\";\nimport type {\n  BoojumCircuitInfoResponse,\n  CircomCircuitInfoResponse,\n  CircuitStatusResponse,\n  GnarkCircuitInfoResponse,\n  HermezCircuitInfoResponse,\n  Halo2CircuitInfoResponse,\n  JoltCircuitInfoResponse,\n  NoirCircuitInfoResponse,\n  OpenvmCircuitInfoResponse,\n  Plonky2CircuitInfoResponse,\n  ProofInfoResponse,\n  ProofStatusResponse,\n  SnarkvmCircuitInfoResponse,\n  Sp1CircuitInfoResponse,\n} from \"lib/api\";\nimport { Config } from \"lib/config\";\nimport { createLogger, type Logger, type LogLevel } from \"lib/logging\";\nimport { File, FormData } from \"lib/isomorphic\";\nimport type {\n  BrowserFile,\n  BrowserFormData,\n  NodeFile,\n  NodeFormData,\n} from \"lib/isomorphic\";\nimport { type Meta, validateMetaAndMergeWithDefaults } from \"lib/utils\";\n\n// Re-export types from the API.\nexport type {\n  BoojumCircuitInfoResponse,\n  CircomCircuitInfoResponse,\n  CircuitType,\n  GnarkCircuitInfoResponse,\n  Halo2CircuitInfoResponse,\n  HermezCircuitInfoResponse,\n  JoltCircuitInfoResponse,\n  JobStatus,\n  NoirCircuitInfoResponse,\n  OpenvmCircuitInfoResponse,\n  Plonky2CircuitInfoResponse,\n  ProofInfoResponse,\n  SnarkvmCircuitInfoResponse,\n  Sp1CircuitInfoResponse,\n};\nexport type CircuitInfoResponse =\n  | BoojumCircuitInfoResponse\n  | CircomCircuitInfoResponse\n  | Halo2CircuitInfoResponse\n  | HermezCircuitInfoResponse\n  | JoltCircuitInfoResponse\n  | GnarkCircuitInfoResponse\n  | NoirCircuitInfoResponse\n  | OpenvmCircuitInfoResponse\n  | Plonky2CircuitInfoResponse\n  | SnarkvmCircuitInfoResponse\n  | Sp1CircuitInfoResponse;\n\n// Re-export other internal types.\nexport type { Logger, LogLevel, Meta, RetryOptions };\n\n/**\n * The options for authenticating with the API.\n */\nexport interface AuthOptions {\n  /**\n   * The API key to use for authentication.\n   */\n  apiKey?: string;\n  /**\n   * The base URL for the API.\n   */\n  baseUrl?: string;\n}\n\n/**\n * Represents the primary client for interacting with the Sindri ZKP service API. This class serves\n * as the central entry point for the SDK, facilitating various operations such as compiling ZKP\n * circuits and generating proofs.\n *\n * The {@link SindriClient} class encapsulates all the necessary methods and properties required to\n * communicate effectively with the Sindri ZKP service, handling tasks like authentication, request\n * management, and response processing.\n *\n * Usage of this class typically involves instantiating it with appropriate authentication options\n * and then utilizing its methods to interact with the service.\n *\n * @example\n * // Create an instance of the `SindriClient` class.\n * const client = new SindriClient({ apiKey: 'your-api-key' });\n *\n * // Use the client to interact with the Sindri ZKP service...\n */\nexport class SindriClient {\n  /** @hidden */\n  readonly _client: ApiClient;\n  /** @hidden */\n  readonly _clientConfig: OpenAPIConfig;\n  /** @hidden */\n  readonly _config: Config | undefined;\n\n  readonly logger: Logger;\n\n  /**\n   * Represents the polling interval in milliseconds used for querying the status of an endpoint.\n   * This value determines the frequency at which the SDK polls an endpoint to check for any changes\n   * in status.\n   *\n   * The choice of polling interval is critical for balancing responsiveness against resource\n   * consumption.  A shorter interval leads to more frequent updates, beneficial for\n   * rapidly-changing statuses, but at the expense of higher network and computational load. In\n   * contrast, a longer interval reduces resource usage but may delay the detection of status\n   * changes.\n   *\n   * For more complex ZKP circuits, which may take longer to compile, considering a larger polling\n   * interval could be advantageous. This approach minimizes unnecessary network traffic and\n   * computational effort while awaiting the completion of these time-intensive operations.\n   *\n   * The default value is set to 1000 milliseconds (1 second), offering a general balance. However,\n   * it can and should be adjusted based on the expected complexity and compilation time of the\n   * circuits being processed.\n   */\n  public pollingInterval: number = 1000;\n\n  /**\n   * Represents the options for retrying requests to the Sindri ZKP service.\n   *\n   * See the [`retry` package](https://www.npmjs.com/package/retry#retrytimeoutsoptions)\n   * documentation for more information on the available options. The values here are the defaults,\n   * but they can be replaced with custom values in the constructor.\n   */\n  public retryOptions: RetryOptions = {\n    minTimeout: 1000,\n    retries: 6,\n  };\n\n  /**\n   * Constructs a new instance of the {@link SindriClient} class for interacting with the Sindri ZKP\n   * service.  This constructor initializes the client with the necessary authentication options.\n   *\n   * The provided `authOptions` parameter allows for specifying authentication credentials and\n   * configurations required for the client to communicate securely with the service.  See\n   * {@link SindriClient.authorize} for more details about how authentication credentials are sourced.\n   *\n   * @param authOptions - The authentication options for the client, including\n   * credentials like API keys or tokens. Defaults to an empty object if not provided.\n   *\n   * @example\n   * // Instantiating the SindriClient with authentication options\n   * const client = new SindriClient({ apiKey: 'sindri-...-fskd' });\n   *\n   * @see {@link SindriClient.authorize} for information on retrieving this value.\n   */\n  constructor(\n    authOptions: AuthOptions = {},\n    { retryOptions }: { retryOptions?: RetryOptions } = {},\n  ) {\n    // Initialize the client and store a reference to its config.\n    this._client = new ApiClient();\n    this._clientConfig = this._client.request.config;\n\n    // Set the `Sindri-Client` header.\n    const versionTag = process.env.VERSION\n      ? `v${process.env.VERSION}`\n      : \"unknown\";\n    this._clientConfig.HEADERS = {\n      ...this._clientConfig.HEADERS,\n      \"Sindri-Client\": `sindri-js-sdk/${versionTag}`,\n    };\n\n    // Create a local logger instance.\n    this.logger = createLogger();\n    if (!process.env.BROWSER_BUILD) {\n      this._config = new Config(this.logger);\n    }\n    this._clientConfig.sindri = this;\n\n    // Authorize the client.\n    this.authorize(authOptions);\n\n    // Store the retry options.\n    if (retryOptions) {\n      this.retryOptions = structuredClone(retryOptions);\n    }\n  }\n\n  /**\n   * Retrieves the current value of the client's API key used for authenticating with the Sindri ZKP\n   * service.  This property is crucial for ensuring secure communication with the API and is\n   * typically set during client initialization.\n   *\n   * If the API key is not set or is in an invalid format (not a string), this getter returns\n   * `null`.  Proper management of the API key is essential for the security and proper functioning\n   * of the SDK.\n   *\n   * @returns The current API key if set and valid, otherwise `null`.\n   *\n   * @example\n   * const currentApiKey = client.apiKey;\n   * if (currentApiKey) {\n   *   console.log('API Key is set.');\n   * } else {\n   *   console.log('API Key is not set or is invalid.');\n   * }\n   */\n  get apiKey(): string | null {\n    if (\n      this._clientConfig.TOKEN &&\n      typeof this._clientConfig.TOKEN !== \"string\"\n    ) {\n      return null;\n    }\n    return this._clientConfig.TOKEN || null;\n  }\n\n  /**\n   * Retrieves the current base URL of the Sindri ZKP service that the client is configured to\n   * interact with.  This URL forms the foundation of all API requests made by the client and is\n   * typically set during client initialization. Anyone other than employees at Sindri can typically\n   * ignore this and use the default value of `https://sindri.app`.\n   *\n   * @returns The current base URL of the Sindri ZKP service.\n   *\n   * @example\n   * console.log(`Current base URL: ${client.baseUrl}`);\n   */\n  get baseUrl(): string {\n    return this._clientConfig.BASE;\n  }\n\n  /** Retrieves the current log level of the client. The log level determines the verbosity of logs\n   * produced by the client which can be crucial for debugging and monitoring the client's\n   * interactions with the Sindri ZKP service.\n   *\n   * @returns The current log level of the client.\n   *\n   * @example\n   * console.log(`Current log level: ${client.logLevel}`);\n   */\n  get logLevel(): LogLevel {\n    // We don't specify any custom log levels, so we can narrow the type to exclude strings.\n    return this.logger.level as LogLevel;\n  }\n\n  /**\n   * Sets the client's log level. This level determines the verbosity of logs produced by the\n   * client, allowing for flexible control over the amount of information logged during operation.\n   *\n   * @param level - The new log level to set for the client.\n   *\n   * @example\n   * // Set log level to debug.\n   * client.logLevel = \"debug\";\n   */\n  set logLevel(level: LogLevel) {\n    this.logger.level = level;\n    this.logger.debug(`Set log level to \"${this.logger.level}\".`);\n  }\n\n  /**\n   * Authorizes the client with the Sindri ZKP service using the provided authentication options.\n   * This method is called automatically after initializing a client, but you may call it again if\n   * you would like to change the credentials. The logic around how credentials is as follows:\n   *\n   * 1. Any explicitly specified options in `authOptions` are always used if provided.\n   * 2. The `SINDRI_API_KEY` and `SINDRI_BASE_URL` environment variables are checked next.\n   * 3. The settings in `sindri.conf.json` (produced by running `sindri login` on the command-line) will be checked after that.\n   * 4. Finally, the default value of `https://sindri.app` will be used for the base URL (this is\n   * typically what you want unless you're an employee at Sindri). The API key will remain unset and\n   * you will only be able to make requests that allow anonymous access.\n   *\n   *\n   * @param authOptions - The authentication details required to authorize the client.\n   * @returns True if authorization is successful, false otherwise.\n   *\n   * @example\n   * const authOptions = { apiKey: 'sindri-...-jskd' };\n   * const isAuthorized = client.authorize(authOptions);\n   * if (isAuthorized) {\n   *   console.log('Client is fully authorized.');\n   * } else {\n   *   console.log('Client is not authorized.');\n   * }\n   */\n  authorize(authOptions: AuthOptions): boolean {\n    if (process.env.BROWSER_BUILD) {\n      this._clientConfig.BASE = authOptions.baseUrl || \"https://sindri.app\";\n      this._clientConfig.TOKEN = authOptions.apiKey;\n    } else {\n      this._config!.reload();\n      this._clientConfig.BASE =\n        authOptions.baseUrl ||\n        process.env.SINDRI_BASE_URL ||\n        this._config!.auth?.baseUrl ||\n        this._clientConfig.BASE ||\n        \"https://sindri.app\";\n      this._clientConfig.TOKEN =\n        authOptions.apiKey ||\n        process.env.SINDRI_API_KEY ||\n        this._config!.auth?.apiKey;\n    }\n    return !!(this._clientConfig.BASE && this._clientConfig.TOKEN);\n  }\n\n  /**\n   * Creates a new {@link SindriClient} client instance. The class itself is not exported, so use\n   * this method on the exported (or any other) client instance to create a new instance. The new\n   * instance can be configured and used completely independently from any other instances. For\n   * example it can use different credentials or a different log level.\n   *\n   * @param authOptions - The authentication options for the client, including\n   * credentials like API keys or tokens. Defaults to an empty object if not provided.\n   * @param options - Additional options for configuring the client.\n   * @param options.retryOptions - The options related to retrying a request.\n   *\n   * @example\n   * import sindri from 'sindri';\n   *\n   * // Equivalent to: const myClient = new SindriClient({ ... });\n   * const myClient = sindri.create({ apiKey: 'sindri-mykey-1234'});\n   *\n   * @returns The new client instance.\n   */\n  create(\n    authOptions: AuthOptions | undefined,\n    options:\n      | {\n          retryOptions?: RetryOptions;\n        }\n      | undefined,\n  ): SindriClient {\n    return new SindriClient(authOptions, options);\n  }\n\n  /**\n   * Asynchronously creates and deploys a new circuit, initiating its compilation process.  This\n   * method is essential for submitting new versions of circuits to the Sindri ZKP service for\n   * compilation. Upon deployment, it continuously polls the service to track the compilation status\n   * until the process either completes successfully or fails.\n   *\n   * The method accepts two parameters: `project` and `tags`. The `project` parameter can be either\n   * a string representing the path to the project or an array of files (browser or Node.js file\n   * objects) constituting the circuit. The `tags` parameter is used to assign tags to the deployed\n   * circuit, facilitating versioning and identification. By default, the circuit is tagged as\n   * \"latest\".\n   *\n   * After successful deployment and compilation, the method returns a `CircuitInfoResponse` object,\n   * which includes details about the compiled circuit, such as its identifier and status.\n   *\n   * @param project - In Node.js, this can either be a path to the root\n   * directory of a Sindri project, the path to a gzipped tarball containing the project, or an\n   * array of `buffer.File` objects. In a web browser, it can only be an array of `File` objects.\n   * @param tags - The list of tags, or singular tag if a string is passed, that\n   * should be associated with the deployed circuit. Defaults to `[\"latest\"]`. Specify an empty\n   * array to indicate that you don't care about the compilation outputs and just want to see if it\n   * the circuit will compile.\n   * @param meta - An object containing metadata to associate with the circuit build. This will be\n   * merged into any metadata specified in the `SINDRI_META` environment variable. This variable can\n   * be a JSON object (*e.g.* `{\"key\": \"value\"}`) or a colon-delimited set of assignments (*e.g.*\n   * `key1=value1:key2=value2`).\n   * @returns A promise which resolves to the details of the deployed circuit.\n   *\n   * @example\n   * // Deploy a circuit with a project identifier and default `latest` tag.\n   * const circuit = await client.createCircuit(\"/path/to/circuit-directory/\");\n   * console.log(\"Did circuit compilation succeed?\", circuit.status);\n   *\n   * @example\n   * // Deploy a circuit with files and custom tags.\n   * await client.createCircuit([file1, file2], ['v1.0', 'experimental']);\n   */\n  async createCircuit(\n    project: string | Array<BrowserFile | NodeFile>,\n    tags: string | string[] | null = [\"latest\"],\n    meta: Meta = {},\n  ): Promise<CircuitInfoResponse> {\n    const formData = new FormData();\n\n    // First, validate the tags and them to the form data.\n    tags = typeof tags === \"string\" ? [tags] : tags ?? [];\n    for (const tag of tags) {\n      if (!/^[-a-zA-Z0-9_.]+$/.test(tag)) {\n        throw new Error(\n          `\"${tag}\" is not a valid tag. Tags may only contain alphanumeric characters, ` +\n            \"underscores, hyphens, and periods.\",\n        );\n      }\n      formData.append(\"tags\", tag);\n    }\n    if (tags.length === 0) {\n      formData.append(\"tags\", \"\");\n    }\n\n    // Validate and add the metadata.\n    formData.append(\n      \"meta\",\n      JSON.stringify(validateMetaAndMergeWithDefaults(meta)),\n    );\n\n    // Handle `project` being a file or directory path.\n    if (typeof project === \"string\") {\n      if (process.env.BROWSER_BUILD) {\n        throw new Error(\n          \"Specifying `project` as a path is not allowed in the browser build.\",\n        );\n      }\n\n      let projectStats;\n      try {\n        projectStats = await stat(project);\n      } catch {\n        throw new Error(\n          `The \"${project}\" path does not exist or you do not have permission to access it.`,\n        );\n      }\n\n      // If `project` is a path, then it's a prepackaged tarball.\n      if (projectStats.isFile()) {\n        if (!/\\.(zip|tar|tar\\.gz|tgz)$/i.test(project)) {\n          throw new Error(\"Only gzipped tarballs or zip files are supported.\");\n        }\n        const tarballFilename = path.basename(project);\n        const tarballContent = await readFile(project);\n        (formData as NodeFormData).append(\n          \"files\",\n          new File([tarballContent], tarballFilename),\n        );\n\n        // If `project` is a directory, then we need to bundle it.\n      } else if (projectStats.isDirectory()) {\n        const sindriJsonPath = path.join(project, \"sindri.json\");\n        let sindriJsonContent;\n        try {\n          sindriJsonContent = await readFile(sindriJsonPath, {\n            encoding: \"utf-8\",\n          });\n        } catch {\n          throw new Error(\n            `Expected Sindri manifest file at \"${sindriJsonPath}\" does not exist.`,\n          );\n        }\n        let sindriJson;\n        try {\n          sindriJson = JSON.parse(sindriJsonContent) as { name: string };\n        } catch {\n          throw new Error(\n            `Could not parse \"${sindriJsonPath}\", is it valid JSON?`,\n          );\n        }\n        const circuitName = sindriJson?.name;\n        if (!circuitName) {\n          throw new Error(\n            `No circuit \"name\" field was found in \"${sindriJsonPath}\", the manifest is invalid.`,\n          );\n        }\n\n        // Create a tarball with all the files that should be included from the project.\n        const files = walk\n          .sync({\n            follow: true,\n            ignoreFiles: [\".sindriignore\"],\n            path: project,\n          })\n          .filter(\n            (file) =>\n              // Always exclude `.git` subdirectories.\n              !/(^|\\/)\\.git(\\/|$)/.test(file),\n          );\n        // Always include the `sindri.json` file.\n        const sindriJsonFilename = path.basename(sindriJsonPath);\n        if (!files.includes(sindriJsonFilename)) {\n          files.push(sindriJsonFilename);\n        }\n        const tarballFilename = `${circuitName}.tar.gz`;\n        files.sort((a, b) => a.localeCompare(b)); // Deterministic for tests.\n        const tarStream = tar.c(\n          {\n            cwd: project,\n            gzip: true,\n            onwarn: (code: string, message: string) => {\n              this.logger.warn(`While creating tarball: ${code} - ${message}`);\n            },\n            prefix: `${circuitName}/`,\n            sync: true,\n          },\n          files,\n          // This works around a bug in the typing of `tar` when using `sync`.\n        ) as unknown as Readable;\n\n        // Add the tarball to the form data.\n        (formData as NodeFormData).append(\n          \"files\",\n          new File([tarStream.read()], tarballFilename),\n        );\n      } else {\n        throw new Error(`The \"${project}\" path is not a file or directory.`);\n      }\n\n      // Handle an array of files.\n    } else if (Array.isArray(project)) {\n      // Validate the file array.\n      if (!project.every((file) => file instanceof File)) {\n        throw new Error(\"All entries in `project` must be `File` instances.\");\n      }\n      const sindriJsonFile = project.find(\n        (file) => file.name === \"sindri.json\",\n      );\n      if (!sindriJsonFile) {\n        throw new Error(\n          \"The `project` array must include a `sindri.json` file.\",\n        );\n      }\n      let sindriJson;\n      try {\n        sindriJson = JSON.parse(await sindriJsonFile.text()) as {\n          name: string;\n        };\n      } catch {\n        throw new Error(`Could not parse \"sindri.json\", is it valid JSON?`);\n      }\n      const circuitName = sindriJson?.name;\n      if (!circuitName) {\n        throw new Error(\n          `No circuit \"name\" field was found in \"sindri.json\", the manifest is invalid.`,\n        );\n      }\n\n      // Create the gzipped tarball.\n      const tarball = new Tar();\n      project.sort((a, b) => a.name.localeCompare(b.name)); // Deterministic for tests.\n      for (const file of project) {\n        const content = new Uint8Array(await file.arrayBuffer());\n        await new Promise((resolve) =>\n          tarball.append(`${circuitName}/${file.name}`, content, resolve),\n        );\n      }\n      const gzippedTarball = new Uint8Array(gzip.zip(tarball.out));\n      const tarFile = new File([gzippedTarball], `${circuitName}.tar.gz`);\n\n      // Append the tarball to the form data.\n      // These lines are functionally identical, but we want to typecheck node and browser.\n      if (process.env.BROWSER_BUILD) {\n        (formData as BrowserFormData).append(\"files\", tarFile as BrowserFile);\n      } else {\n        (formData as NodeFormData).append(\"files\", tarFile as NodeFile);\n      }\n    }\n\n    const createResponse = await this._client.circuits.circuitCreate(\n      formData as NodeFormData,\n    );\n    const circuitId = createResponse.circuit_id;\n\n    while (true) {\n      const response: CircuitStatusResponse =\n        await this._client.internal.circuitStatus(circuitId);\n      if (response.status === \"Ready\" || response.status === \"Failed\") {\n        break;\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, this.pollingInterval));\n    }\n    return this._client.circuits.circuitDetail(circuitId, false);\n  }\n\n  /**\n   * Retrieves all proofs associated with a specified circuit.  This method is essential for\n   * obtaining a comprehensive list of proofs generated for a given circuit, identified by its\n   * unique circuit ID. It returns an array of `ProofInfoResponse` objects, each representing a\n   * proof associated with the circuit.\n   *\n   * The method is particularly useful in scenarios where tracking or auditing all proofs of a\n   * circuit is necessary. This could include verifying the integrity of proofs, understanding their\n   * usage, or simply enumerating them for record-keeping.\n   *\n   * The `circuitId` parameter is a string that uniquely identifies the circuit in question. It's\n   * crucial to provide the correct circuit ID to retrieve the corresponding proofs accurately.\n   *\n   * @param circuitId - The unique identifier of the circuit for which proofs are to be retrieved.\n   * @returns A promise that resolves to an array of details for each associated proof.\n   *\n   * @example\n   * const proofs = await client.getAllCircuitProofs(circuitId);\n   * console.log(\"Proofs:', proofs);\n   */\n  async getAllCircuitProofs(circuitId: string): Promise<ProofInfoResponse[]> {\n    return await this._client.circuits.circuitProofs(circuitId);\n  }\n\n  /**\n   * Retrieves all circuits associated with the team.  This method fetches a list of all circuits\n   * that have been created or accessed by the currently authenticated team. It's a key method for\n   * managing and monitoring circuit usage within a team, offering insights into the variety and\n   * scope of circuits in use.\n   *\n   * @returns A promise that resolves to an array of circuit information responses.\n   *\n   * @example\n   * const circuits = await = client.getAllCircuits();\n   * console.log(\"Circuits:\", circuits);\n   */\n  async getAllCircuits(): Promise<CircuitInfoResponse[]> {\n    return await this._client.circuits.circuitList();\n  }\n\n  /**\n   * Retrieves a specific circuit using its unique circuit ID.  This method is crucial for obtaining\n   * detailed information about a particular circuit,  identified by the provided `circuitId`. It's\n   * especially useful when detailed insights  or operations on a single circuit are required, rather\n   * than handling multiple circuits.\n   *\n   * *Note:* In case the provided `circuitId` is invalid or does not correspond to an existing circuit,\n   * the promise may reject, indicating an error. Proper error handling is therefore essential when using this method.\n   *\n   * @param circuitId - The unique identifier of the circuit to retrieve.\n   * @returns A promise that resolves to the information about the specified circuit.\n   *\n   * @example\n   * const circuit = await client.getCircuit(circuitId);\n   * console.log('Circuit details:', circuit);\n   */\n  async getCircuit(circuitId: string): Promise<CircuitInfoResponse> {\n    return await this._client.circuits.circuitDetail(circuitId);\n  }\n\n  /**\n   * Retrieves detailed information about a specific proof, identified by its unique proof ID.  This\n   * method is vital for obtaining individual proof details, facilitating in-depth analysis or\n   * verification of a particular proof within the system.\n   *\n   * The `proofId` parameter is the key identifier for the proof, and it should be provided to fetch\n   * the corresponding information. The method returns a promise that resolves to a\n   * {@link ProofInfoResponse}, containing all relevant details of the proof.\n   *\n   * @param proofId - The unique identifier of the proof to retrieve.\n   * @returns A promise that resolves to the data about the specified proof.\n   *\n   * @example\n   * const proof = await client.getProof(proofId);\n   * console.log(\"Proof details:\", proof);\n   */\n  async getProof(proofId: string): Promise<ProofInfoResponse> {\n    return await this._client.proofs.proofDetail(proofId);\n  }\n\n  /**\n   * Generates a proof for a specified circuit.  This method is critical for creating a new proof\n   * based on a given circuit, identified by `circuitId`, and the provided `proofInput`. It's\n   * primarily used to validate or verify certain conditions or properties of the circuit without\n   * revealing underlying data or specifics. The method continuously polls the service to track the\n   * compilation status until the process either completes successfully or fails.\n   *\n   * The `circuitId` parameter specifies the unique identifier of the circuit for which the proof is\n   * to be generated.  The `proofInput` is a string that represents the necessary input data or\n   * parameters required for generating the proof.\n   *\n   * @param circuitId - The unique identifier of the circuit for which the proof is being generated.\n   * @param proofInput - The input data required for generating the proof. This should be a string\n   * containing either JSON data or TOML data (in the case of Noir).\n   * @param verify - A boolean indicating whether to perform a verification check of the generated\n   * proof.\n   * @param includeSmartContractCalldata - A boolean indicating whether to include calldata for the\n   * proof that can be passed into a smart contract for verification. Note that not all frameworks\n   * support this.\n   * @param meta - An object containing metadata to associate with the proof. This will be merged\n   * into any metadata specified in the `SINDRI_META` environment variable. This variable can be a\n   * JSON object (*e.g.* `{\"key\": \"value\"}`) or a colon-delimited set of assignments (*e.g.*\n   * `key1=value1:key2=value2`).\n   * @returns A promise that resolves to the information of the generated proof.\n   *\n   * @example\n   * const proof = await client.proveCircuit(circuitId, '{\"X\": 23, \"Y\": 52}');\n   * console.log(\"Generated proof:\", proof);\n   */\n  async proveCircuit(\n    circuitId: string,\n    proofInput: string,\n    verify: boolean = false,\n    includeSmartContractCalldata: boolean = false,\n    meta: Meta = {},\n  ): Promise<ProofInfoResponse> {\n    const createResponse = await this._client.circuits.proofCreate(circuitId, {\n      meta: validateMetaAndMergeWithDefaults(meta), // This will raise an error if it's invalid.\n      perform_verify: verify,\n      proof_input: proofInput,\n    });\n    const proofId: string = createResponse.proof_id;\n    while (true) {\n      const response: ProofStatusResponse =\n        await this._client.internal.proofStatus(proofId);\n      if (response.status === \"Ready\" || response.status === \"Failed\") {\n        break;\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, this.pollingInterval));\n    }\n    return this._client.proofs.proofDetail(\n      proofId,\n      true, // includeProof\n      true, // includePublic\n      includeSmartContractCalldata, // includeSmartContractCalldata\n      true, // includeVerificationKey\n    );\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { CancelablePromise } from \"./CancelablePromise\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\n\nexport abstract class BaseHttpRequest {\n  constructor(public readonly config: OpenAPIConfig) {}\n\n  public abstract request<T>(options: ApiRequestOptions): CancelablePromise<T>;\n}\n","/* This file was originally generated by `openapi-typescript-codegen`, but we've customized it and\n * it is no longer regenerated. The key changes:\n *\n *   * Support pre-constructed `FormData` instances, and make `FormData` isomorphic.\n *   * Add request/response logging for all API requests in `request()`.\n */\n\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport axios from \"axios\";\nimport type { AxiosRequestConfig, AxiosResponse, AxiosInstance } from \"axios\";\nimport { AxiosError } from \"axios\";\nimport pRetry from \"@fullstax/p-retry\";\n\n// Manual edit to use our isomorphic `FormData`.\nimport { FormData } from \"lib/isomorphic\";\n\nimport { ApiError } from \"./ApiError\";\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { ApiResult } from \"./ApiResult\";\nimport { CancelablePromise } from \"./CancelablePromise\";\nimport type { OnCancel } from \"./CancelablePromise\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\n\nexport const isDefined = <T>(\n  value: T | null | undefined,\n): value is Exclude<T, null | undefined> => {\n  return value !== undefined && value !== null;\n};\n\nexport const isString = (value: any): value is string => {\n  return typeof value === \"string\";\n};\n\nexport const isStringWithValue = (value: any): value is string => {\n  return isString(value) && value !== \"\";\n};\n\nexport const isBlob = (value: any): value is Blob => {\n  return (\n    typeof value === \"object\" &&\n    typeof value.type === \"string\" &&\n    typeof value.stream === \"function\" &&\n    typeof value.arrayBuffer === \"function\" &&\n    typeof value.constructor === \"function\" &&\n    typeof value.constructor.name === \"string\" &&\n    /^(Blob|File)$/.test(value.constructor.name) &&\n    /^(Blob|File)$/.test(value[Symbol.toStringTag])\n  );\n};\n\nexport const isFormData = (value: any): value is FormData => {\n  return value instanceof FormData;\n};\n\nexport const isSuccess = (status: number): boolean => {\n  return status >= 200 && status < 300;\n};\n\nexport const base64 = (str: string): string => {\n  try {\n    return btoa(str);\n  } catch (err) {\n    // @ts-ignore\n    return Buffer.from(str).toString(\"base64\");\n  }\n};\n\nexport const getQueryString = (params: Record<string, any>): string => {\n  const qs: string[] = [];\n\n  const append = (key: string, value: any) => {\n    qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n  };\n\n  const process = (key: string, value: any) => {\n    if (isDefined(value)) {\n      if (Array.isArray(value)) {\n        value.forEach((v) => {\n          process(key, v);\n        });\n      } else if (typeof value === \"object\") {\n        Object.entries(value).forEach(([k, v]) => {\n          process(`${key}[${k}]`, v);\n        });\n      } else {\n        append(key, value);\n      }\n    }\n  };\n\n  Object.entries(params).forEach(([key, value]) => {\n    process(key, value);\n  });\n\n  if (qs.length > 0) {\n    return `?${qs.join(\"&\")}`;\n  }\n\n  return \"\";\n};\n\nconst getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {\n  const encoder = config.ENCODE_PATH || encodeURI;\n\n  const path = options.url\n    .replace(\"{api-version}\", config.VERSION)\n    .replace(/{(.*?)}/g, (substring: string, group: string) => {\n      if (options.path?.hasOwnProperty(group)) {\n        return encoder(String(options.path[group]));\n      }\n      return substring;\n    });\n\n  const url = `${config.BASE}${path}`;\n  if (options.query) {\n    return `${url}${getQueryString(options.query)}`;\n  }\n  return url;\n};\n\nexport const getFormData = (\n  options: ApiRequestOptions,\n): FormData | undefined => {\n  if (options.formData) {\n    // This is a manual edit to allow `FormData` to be passed in directly.\n    if (options.formData instanceof FormData) {\n      return options.formData;\n    }\n\n    const formData = new FormData();\n\n    const process = (key: string, value: any) => {\n      if (isString(value) || isBlob(value)) {\n        formData.append(key, value);\n      } else {\n        formData.append(key, JSON.stringify(value));\n      }\n    };\n\n    Object.entries(options.formData)\n      .filter(([_, value]) => isDefined(value))\n      .forEach(([key, value]) => {\n        if (Array.isArray(value)) {\n          value.forEach((v) => process(key, v));\n        } else {\n          process(key, value);\n        }\n      });\n\n    return formData;\n  }\n  return undefined;\n};\n\ntype Resolver<T> = (options: ApiRequestOptions) => Promise<T>;\n\nexport const resolve = async <T>(\n  options: ApiRequestOptions,\n  resolver?: T | Resolver<T>,\n): Promise<T | undefined> => {\n  if (typeof resolver === \"function\") {\n    return (resolver as Resolver<T>)(options);\n  }\n  return resolver;\n};\n\nexport const getHeaders = async (\n  config: OpenAPIConfig,\n  options: ApiRequestOptions,\n  formData?: FormData,\n): Promise<Record<string, string>> => {\n  const token = await resolve(options, config.TOKEN);\n  const username = await resolve(options, config.USERNAME);\n  const password = await resolve(options, config.PASSWORD);\n  const additionalHeaders = await resolve(options, config.HEADERS);\n  // Manual edit to support `FormData` implementations that don't include `getHeaders()`.\n  const formHeaders =\n    (formData &&\n      \"getHeaders\" in formData &&\n      typeof formData?.getHeaders === \"function\" &&\n      formData?.getHeaders()) ||\n    {};\n\n  const headers = Object.entries({\n    Accept: \"application/json\",\n    ...additionalHeaders,\n    ...options.headers,\n    ...formHeaders,\n  })\n    .filter(([_, value]) => isDefined(value))\n    .reduce(\n      (headers, [key, value]) => ({\n        ...headers,\n        [key]: String(value),\n      }),\n      {} as Record<string, string>,\n    );\n\n  if (isStringWithValue(token)) {\n    headers[\"Authorization\"] = `Bearer ${token}`;\n  }\n\n  if (isStringWithValue(username) && isStringWithValue(password)) {\n    const credentials = base64(`${username}:${password}`);\n    headers[\"Authorization\"] = `Basic ${credentials}`;\n  }\n\n  if (options.body) {\n    if (options.mediaType) {\n      headers[\"Content-Type\"] = options.mediaType;\n    } else if (isBlob(options.body)) {\n      headers[\"Content-Type\"] = options.body.type || \"application/octet-stream\";\n    } else if (isString(options.body)) {\n      headers[\"Content-Type\"] = \"text/plain\";\n    } else if (!isFormData(options.body)) {\n      headers[\"Content-Type\"] = \"application/json\";\n    }\n  }\n\n  return headers;\n};\n\nexport const getRequestBody = (options: ApiRequestOptions): any => {\n  if (options.body) {\n    return options.body;\n  }\n  return undefined;\n};\n\nconst shouldRetry = (error: Error): boolean =>\n  !!(\n    axios.isAxiosError(error) &&\n    ((error.response?.status &&\n      [502, 503, 504].includes(error.response.status)) ||\n      (error.code &&\n        [\n          // Some of these codes aren't on `AxiosError` for some reason, see:\n          //   * https://github.com/axios/axios/issues/4894#issuecomment-2062064639\n          \"ECONNREFUSED\",\n          \"ECONNRESET\",\n          \"ENOTFOUND\",\n          \"ENETUNREACH\",\n          AxiosError.ECONNABORTED,\n          AxiosError.ERR_NETWORK,\n        ].includes(error.code)))\n  );\n\nexport const sendRequest = async <T>(\n  config: OpenAPIConfig,\n  options: ApiRequestOptions,\n  url: string,\n  body: any,\n  formData: FormData | undefined,\n  headers: Record<string, string>,\n  onCancel: OnCancel,\n  axiosClient: AxiosInstance,\n): Promise<AxiosResponse<T>> => {\n  const source = axios.CancelToken.source();\n\n  const requestConfig: AxiosRequestConfig = {\n    url,\n    headers,\n    data: body ?? formData,\n    method: options.method,\n    withCredentials: config.WITH_CREDENTIALS,\n    cancelToken: source.token,\n    responseType: options.responseType,\n  };\n\n  onCancel(() => source.cancel(\"The user aborted a request.\"));\n\n  try {\n    if (!config.sindri) {\n      return await axiosClient.request(requestConfig);\n    }\n    return await pRetry(() => axiosClient.request(requestConfig), {\n      ...config.sindri.retryOptions,\n      onFailedAttempt: (error) => {\n        // Don't log anything if we're not going to retry the request, the error will get logged\n        // further up the stack in that case.\n        if (!shouldRetry(error)) return;\n\n        config.sindri!.logger.debug(\n          {\n            attemptNumber: error.attemptNumber,\n            error: error.message,\n            retriesLeft: error.retriesLeft,\n          },\n          `${options.method} ${url} - Request failed, ` +\n            `${error.retriesLeft > 0 ? \"retrying\" : \"aborting...\"}...`,\n        );\n      },\n      shouldRetry,\n    });\n  } catch (error) {\n    const axiosError = error as AxiosError<T>;\n    if (axiosError.response) {\n      return axiosError.response;\n    }\n    throw error;\n  }\n};\n\nexport const getResponseHeader = (\n  response: AxiosResponse<any>,\n  responseHeader?: string,\n): string | undefined => {\n  if (responseHeader) {\n    const content = response.headers[responseHeader];\n    if (isString(content)) {\n      return content;\n    }\n  }\n  return undefined;\n};\n\nexport const getResponseBody = (response: AxiosResponse<any>): any => {\n  if (response.status !== 204) {\n    return response.data;\n  }\n  return undefined;\n};\n\nexport const catchErrorCodes = (\n  options: ApiRequestOptions,\n  result: ApiResult,\n): void => {\n  const errors: Record<number, string> = {\n    400: \"Bad Request\",\n    401: \"Unauthorized\",\n    403: \"Forbidden\",\n    404: \"Not Found\",\n    500: \"Internal Server Error\",\n    502: \"Bad Gateway\",\n    503: \"Service Unavailable\",\n    ...options.errors,\n  };\n\n  const error = errors[result.status];\n  if (error) {\n    throw new ApiError(options, result, error);\n  }\n\n  if (!result.ok) {\n    const errorStatus = result.status ?? \"unknown\";\n    const errorStatusText = result.statusText ?? \"unknown\";\n    const errorBody = (() => {\n      try {\n        return JSON.stringify(result.body, null, 2);\n      } catch (e) {\n        return undefined;\n      }\n    })();\n\n    throw new ApiError(\n      options,\n      result,\n      `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`,\n    );\n  }\n};\n\n/**\n * Request method\n * @param config The OpenAPI configuration object\n * @param options The request options from the service\n * @param axiosClient The axios client instance to use\n * @returns CancelablePromise<T>\n * @throws ApiError\n */\nexport const request = <T>(\n  config: OpenAPIConfig,\n  options: ApiRequestOptions,\n  axiosClient: AxiosInstance = axios,\n): CancelablePromise<T> => {\n  return new CancelablePromise(async (resolve, reject, onCancel) => {\n    // Get a nicely formatted timedelta to display after requests.\n    const startTime = Date.now();\n    const getElapsedTime = (): string => {\n      const ellapsedMilliseconds = Date.now() - startTime;\n      if (ellapsedMilliseconds < 1000) {\n        return `${ellapsedMilliseconds} ms`;\n      }\n      const ellapsedSeconds = ellapsedMilliseconds / 1000;\n      if (ellapsedSeconds < 60) {\n        return `${ellapsedSeconds.toFixed(2)} s`;\n      }\n      const ellapsedMinutes = ellapsedSeconds / 60;\n      if (ellapsedMinutes < 60) {\n        return `${ellapsedMinutes.toFixed(2)} m`;\n      }\n      const ellapsedHours = ellapsedMinutes / 60;\n      return `${ellapsedHours.toFixed(2)} h`;\n    };\n\n    const url = getUrl(config, options);\n    const logPrefix = `${options.method} ${url}`;\n    try {\n      const formData = getFormData(options);\n      const body = getRequestBody(options);\n      const headers = await getHeaders(config, options, formData);\n\n      if (!onCancel.isCancelled) {\n        config.sindri?.logger.debug(`${logPrefix} requested`);\n        const response = await sendRequest<T>(\n          config,\n          options,\n          url,\n          body,\n          formData,\n          headers,\n          onCancel,\n          axiosClient,\n        );\n        const responseBody = getResponseBody(response);\n        const responseHeader = getResponseHeader(\n          response,\n          options.responseHeader,\n        );\n\n        const result: ApiResult = {\n          url,\n          ok: isSuccess(response.status),\n          status: response.status,\n          statusText: response.statusText,\n          body: responseHeader ?? responseBody,\n        };\n        const responseMessage = `${logPrefix} ${response.status} ${\n          response.statusText\n        } (${getElapsedTime()})`;\n        if (!result.body || typeof result.body === \"string\") {\n          config.sindri?.logger.debug(\n            `${responseMessage} - ${result.body || \"<empty-body>\"}`,\n          );\n        } else if (options.responseType === \"stream\") {\n          config.sindri?.logger.debug(\n            `${responseMessage} - <streaming-response>`,\n          );\n        } else if (options.responseType === \"blob\") {\n          config.sindri?.logger.debug(`${responseMessage} - <blob-response>`);\n        } else {\n          config.sindri?.logger.debug(result.body, responseMessage);\n        }\n\n        catchErrorCodes(options, result);\n\n        resolve(result.body);\n      }\n    } catch (error) {\n      const errorMessage =\n        error instanceof Error ? error.message : \"Unknown error\";\n      config.sindri?.logger.debug(\n        `${logPrefix} ERROR (${getElapsedTime()}) - ${errorMessage}`,\n      );\n      reject(error);\n    }\n  });\n};\n","import { File as NodeFile } from \"buffer\";\n\nimport { FormData as NodeFormData } from \"formdata-node\";\n\nexport function assertType<T>(value: unknown) {\n  function isType<T>(value: unknown): value is T {\n    return true || value;\n  }\n  if (!isType<T>(value)) throw new Error(\"Impossible.\");\n}\n\nexport type { NodeFile, NodeFormData };\nexport type BrowserFile = File;\nexport type BrowserFormData = FormData;\n\nexport const File = process.env.BROWSER_BUILD ? window.File : NodeFile;\nexport const FormData = process.env.BROWSER_BUILD\n  ? window.FormData\n  : NodeFormData;\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { ApiResult } from \"./ApiResult\";\n\nexport class ApiError extends Error {\n  public readonly url: string;\n  public readonly status: number;\n  public readonly statusText: string;\n  public readonly body: any;\n  public readonly request: ApiRequestOptions;\n\n  constructor(\n    request: ApiRequestOptions,\n    response: ApiResult,\n    message: string,\n  ) {\n    super(message);\n\n    this.name = \"ApiError\";\n    this.url = response.url;\n    this.status = response.status;\n    this.statusText = response.statusText;\n    this.body = response.body;\n    this.request = request;\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nexport class CancelError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = \"CancelError\";\n  }\n\n  public get isCancelled(): boolean {\n    return true;\n  }\n}\n\nexport interface OnCancel {\n  readonly isResolved: boolean;\n  readonly isRejected: boolean;\n  readonly isCancelled: boolean;\n\n  (cancelHandler: () => void): void;\n}\n\nexport class CancelablePromise<T> implements Promise<T> {\n  #isResolved: boolean;\n  #isRejected: boolean;\n  #isCancelled: boolean;\n  readonly #cancelHandlers: (() => void)[];\n  readonly #promise: Promise<T>;\n  #resolve?: (value: T | PromiseLike<T>) => void;\n  #reject?: (reason?: any) => void;\n\n  constructor(\n    executor: (\n      resolve: (value: T | PromiseLike<T>) => void,\n      reject: (reason?: any) => void,\n      onCancel: OnCancel,\n    ) => void,\n  ) {\n    this.#isResolved = false;\n    this.#isRejected = false;\n    this.#isCancelled = false;\n    this.#cancelHandlers = [];\n    this.#promise = new Promise<T>((resolve, reject) => {\n      this.#resolve = resolve;\n      this.#reject = reject;\n\n      const onResolve = (value: T | PromiseLike<T>): void => {\n        if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n          return;\n        }\n        this.#isResolved = true;\n        this.#resolve?.(value);\n      };\n\n      const onReject = (reason?: any): void => {\n        if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n          return;\n        }\n        this.#isRejected = true;\n        this.#reject?.(reason);\n      };\n\n      const onCancel = (cancelHandler: () => void): void => {\n        if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n          return;\n        }\n        this.#cancelHandlers.push(cancelHandler);\n      };\n\n      Object.defineProperty(onCancel, \"isResolved\", {\n        get: (): boolean => this.#isResolved,\n      });\n\n      Object.defineProperty(onCancel, \"isRejected\", {\n        get: (): boolean => this.#isRejected,\n      });\n\n      Object.defineProperty(onCancel, \"isCancelled\", {\n        get: (): boolean => this.#isCancelled,\n      });\n\n      return executor(onResolve, onReject, onCancel as OnCancel);\n    });\n  }\n\n  get [Symbol.toStringTag]() {\n    return \"Cancellable Promise\";\n  }\n\n  public then<TResult1 = T, TResult2 = never>(\n    onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n    onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n  ): Promise<TResult1 | TResult2> {\n    return this.#promise.then(onFulfilled, onRejected);\n  }\n\n  public catch<TResult = never>(\n    onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n  ): Promise<T | TResult> {\n    return this.#promise.catch(onRejected);\n  }\n\n  public finally(onFinally?: (() => void) | null): Promise<T> {\n    return this.#promise.finally(onFinally);\n  }\n\n  public cancel(): void {\n    if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n      return;\n    }\n    this.#isCancelled = true;\n    if (this.#cancelHandlers.length) {\n      try {\n        for (const cancelHandler of this.#cancelHandlers) {\n          cancelHandler();\n        }\n      } catch (error) {\n        console.warn(\"Cancellation threw an error\", error);\n        return;\n      }\n    }\n    this.#cancelHandlers.length = 0;\n    this.#reject?.(new CancelError(\"Request aborted\"));\n  }\n\n  public get isCancelled(): boolean {\n    return this.#isCancelled;\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport { BaseHttpRequest } from \"./BaseHttpRequest\";\nimport type { CancelablePromise } from \"./CancelablePromise\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\nimport { request as __request } from \"./request\";\n\nexport class AxiosHttpRequest extends BaseHttpRequest {\n  constructor(config: OpenAPIConfig) {\n    super(config);\n  }\n\n  /**\n   * Request method\n   * @param options The request options from the service\n   * @returns CancelablePromise<T>\n   * @throws ApiError\n   */\n  public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {\n    return __request(this.config, options);\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ActionResponse } from \"../models/ActionResponse\";\nimport type { APIKeyResponse } from \"../models/APIKeyResponse\";\nimport type { ObtainApikeyInput } from \"../models/ObtainApikeyInput\";\n\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\n\nexport class AuthorizationService {\n  constructor(public readonly httpRequest: BaseHttpRequest) {}\n\n  /**\n   * Generate API Key\n   * Generates a long-term API Key from your account's username and password.\n   * @param requestBody\n   * @param sindriTeamId Optional. Team ID for the API key.\n   * @returns APIKeyResponse OK\n   * @throws ApiError\n   */\n  public apikeyGenerate(\n    requestBody: ObtainApikeyInput,\n    sindriTeamId?: string | null,\n  ): CancelablePromise<APIKeyResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/apikey/generate\",\n      headers: {\n        \"Sindri-Team-Id\": sindriTeamId,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        400: `Bad Request`,\n        401: `Unauthorized`,\n        403: `Forbidden`,\n      },\n    });\n  }\n\n  /**\n   * API Key Generate\n   * Generate an API key for the requesting team.\n   * @param name An optional name or tag to assign to the generated API Key.\n   * @returns APIKeyResponse Created\n   * @throws ApiError\n   */\n  public apikeyGenerateWithAuth(\n    name?: string,\n  ): CancelablePromise<APIKeyResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/apikey/generate\",\n      query: {\n        name: name,\n      },\n      errors: {\n        400: `Bad Request`,\n      },\n    });\n  }\n\n  /**\n   * API Key List\n   * List API keys for the requesting team.\n   * @returns APIKeyResponse OK\n   * @throws ApiError\n   */\n  public apikeyList(): CancelablePromise<Array<APIKeyResponse>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/apikey/list\",\n      errors: {\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * API Key Delete\n   * Delete a specific API key.\n   * @param apikeyId The UUID4 identifier associated with this API Key.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public apikeyDelete(apikeyId: string): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"DELETE\",\n      url: \"/api/v1/apikey/{apikey_id}/delete\",\n      path: {\n        apikey_id: apikeyId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ActionResponse } from \"../models/ActionResponse\";\nimport type { CircuitInfoResponse } from \"../models/CircuitInfoResponse\";\nimport type { CircuitProveInput } from \"../models/CircuitProveInput\";\nimport type { ProofInfoResponse } from \"../models/ProofInfoResponse\";\n\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\n\nexport class CircuitsService {\n  constructor(public readonly httpRequest: BaseHttpRequest) {}\n\n  /**\n   * Create Circuit\n   * Create a circuit.\n   * @param formData\n   * @returns CircuitInfoResponse Created\n   * @throws ApiError\n   */\n  public circuitCreate(\n    formData: // This is a manual edit to allow `FormData` to be passed in directly:\n    | FormData // DO NOT REMOVE THIS!\n      | {\n          files: Array<Blob>;\n          /**\n           * An arbitrary mapping of metadata keys to string values. This can be used to track additional information about the circuit such as an ID from an external system.\n           */\n          meta?: Record<string, string>;\n          /**\n           * Tags for a circuit.\n           */\n          tags?: Array<string>;\n        },\n  ): CancelablePromise<CircuitInfoResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/circuit/create\",\n      formData: formData,\n      mediaType: \"multipart/form-data\",\n      errors: {\n        400: `Bad Request`,\n        422: `Unprocessable Entity`,\n        500: `Internal Server Error`,\n        501: `Not Implemented`,\n      },\n    });\n  }\n\n  /**\n   * Circuit List\n   * List all circuits owned by team.\n   * @returns CircuitInfoResponse OK\n   * @throws ApiError\n   */\n  public circuitList(): CancelablePromise<Array<CircuitInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/list\",\n      errors: {\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Circuit Detail\n   * Get info for an existing circuit.\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @param includeVerificationKey Indicates whether to include the verification key in the response.\n   * @returns CircuitInfoResponse OK\n   * @throws ApiError\n   */\n  public circuitDetail(\n    circuitId: string,\n    includeVerificationKey: boolean = true,\n  ): CancelablePromise<CircuitInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/detail\",\n      path: {\n        circuit_id: circuitId,\n      },\n      query: {\n        include_verification_key: includeVerificationKey,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Delete Circuit\n   * Delete a circuit.\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public circuitDelete(circuitId: string): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"DELETE\",\n      url: \"/api/v1/circuit/{circuit_id}/delete\",\n      path: {\n        circuit_id: circuitId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Circuit Proofs\n   * List all proofs for a circuit.\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @returns ProofInfoResponse OK\n   * @throws ApiError\n   */\n  public circuitProofs(\n    circuitId: string,\n  ): CancelablePromise<Array<ProofInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/proofs\",\n      path: {\n        circuit_id: circuitId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Create Proof for Circuit\n   * Prove a circuit with specific inputs.\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @param requestBody\n   * @returns ProofInfoResponse Created\n   * @throws ApiError\n   */\n  public proofCreate(\n    circuitId: string,\n    requestBody: CircuitProveInput,\n  ): CancelablePromise<ProofInfoResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/circuit/{circuit_id}/prove\",\n      path: {\n        circuit_id: circuitId,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        400: `Bad Request`,\n        404: `Not Found`,\n        409: `Conflict`,\n        501: `Not Implemented`,\n      },\n    });\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ActionResponse } from \"../models/ActionResponse\";\nimport type { CircuitInfoResponse } from \"../models/CircuitInfoResponse\";\nimport type { CircuitStatusResponse } from \"../models/CircuitStatusResponse\";\nimport type { PagedCircuitInfoResponse } from \"../models/PagedCircuitInfoResponse\";\nimport type { PagedProjectInfoResponse } from \"../models/PagedProjectInfoResponse\";\nimport type { PagedProofInfoResponse } from \"../models/PagedProofInfoResponse\";\nimport type { PasswordChangeInput } from \"../models/PasswordChangeInput\";\nimport type { ProjectInfoResponse } from \"../models/ProjectInfoResponse\";\nimport type { ProjectListInput } from \"../models/ProjectListInput\";\nimport type { ProjectSettingsInput } from \"../models/ProjectSettingsInput\";\nimport type { ProofHistogramInput } from \"../models/ProofHistogramInput\";\nimport type { ProofHistogramResponse } from \"../models/ProofHistogramResponse\";\nimport type { ProofInfoResponse } from \"../models/ProofInfoResponse\";\nimport type { ProofListInput } from \"../models/ProofListInput\";\nimport type { ProofStatusResponse } from \"../models/ProofStatusResponse\";\nimport type { SmartContractVerifierResponse } from \"../models/SmartContractVerifierResponse\";\nimport type { TeamCreateInput } from \"../models/TeamCreateInput\";\nimport type { TeamDetail } from \"../models/TeamDetail\";\nimport type { TeamInviteInput } from \"../models/TeamInviteInput\";\nimport type { TeamMembersResponse } from \"../models/TeamMembersResponse\";\nimport type { TeamMeResponse } from \"../models/TeamMeResponse\";\nimport type { TeamRemoveMemberInput } from \"../models/TeamRemoveMemberInput\";\nimport type { TeamSettingsInput } from \"../models/TeamSettingsInput\";\nimport type { UserLoginInput } from \"../models/UserLoginInput\";\nimport type { UserMeResponse } from \"../models/UserMeResponse\";\n\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\n\n// DO NOT REMOVE\ntype BinaryResponseType = typeof globalThis extends { ReadableStream: unknown }\n  ? Blob\n  : NodeJS.ReadableStream;\n\nexport class InternalService {\n  constructor(public readonly httpRequest: BaseHttpRequest) {}\n\n  /**\n   * Circuit File Download\n   * Obtain circuit file(s).\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @param path The optional file path within the circuit package to download.\n   * @returns any OK\n   * @throws ApiError\n   */\n  public circuitDownload(\n    circuitId: string,\n    path?: string,\n    // DO NOT REMOVE\n  ): CancelablePromise<BinaryResponseType> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/download\",\n      path: {\n        circuit_id: circuitId,\n      },\n      query: {\n        path: path,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n\n      responseType: process.env.BROWSER_BUILD ? \"blob\" : \"stream\", // DO NOT REMOVE\n    });\n  }\n\n  /**\n   * Circuit Proofs\n   * List all proofs for a circuit.\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @param limit The number of proofs to return.\n   * @param offset The number of proofs to skip.\n   * @returns PagedProofInfoResponse OK\n   * @throws ApiError\n   */\n  public circuitProofsPaginated(\n    circuitId: string,\n    limit: number = 100,\n    offset?: number,\n  ): CancelablePromise<PagedProofInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/proofs/paginated\",\n      path: {\n        circuit_id: circuitId,\n      },\n      query: {\n        limit: limit,\n        offset: offset,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project Circuits\n   * List all circuits for a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @returns CircuitInfoResponse OK\n   * @throws ApiError\n   */\n  public projectCircuits(\n    projectId: string,\n  ): CancelablePromise<Array<CircuitInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/project/{project_id}/circuits\",\n      path: {\n        project_id: projectId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project Circuits\n   * List all circuits for a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @param limit The number of circuits to return.\n   * @param offset The number of circuits to skip.\n   * @returns PagedCircuitInfoResponse OK\n   * @throws ApiError\n   */\n  public projectCircuitsPaginated(\n    projectId: string,\n    limit: number = 100,\n    offset?: number,\n  ): CancelablePromise<PagedCircuitInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/project/{project_id}/circuits/paginated\",\n      path: {\n        project_id: projectId,\n      },\n      query: {\n        limit: limit,\n        offset: offset,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Delete Project\n   * Delete a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public projectDelete(projectId: string): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"DELETE\",\n      url: \"/api/v1/project/{project_id}/delete\",\n      path: {\n        project_id: projectId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project Detail\n   * Get info for a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @returns ProjectInfoResponse OK\n   * @throws ApiError\n   */\n  public projectDetail(\n    projectId: string,\n  ): CancelablePromise<ProjectInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/project/{project_id}/detail\",\n      path: {\n        project_id: projectId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project List\n   * List all projects meeting filter criteria.\n   * @param requestBody\n   * @returns ProjectInfoResponse OK\n   * @throws ApiError\n   */\n  public projectList(\n    requestBody: ProjectListInput,\n  ): CancelablePromise<Array<ProjectInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/project/list\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project List\n   * List all projects meeting filter criteria.\n   * @param requestBody\n   * @param limit The number of projects to return.\n   * @param offset The number of projects to skip.\n   * @returns PagedProjectInfoResponse OK\n   * @throws ApiError\n   */\n  public projectListPaginated(\n    requestBody: ProjectListInput,\n    limit: number = 100,\n    offset?: number,\n  ): CancelablePromise<PagedProjectInfoResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/project/list/paginated\",\n      query: {\n        limit: limit,\n        offset: offset,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project Proofs\n   * Get all proofs for a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @returns ProofInfoResponse OK\n   * @throws ApiError\n   */\n  public projectProofs(\n    projectId: string,\n  ): CancelablePromise<Array<ProofInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/project/{project_id}/proofs\",\n      path: {\n        project_id: projectId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Project Proofs\n   * Get all proofs for a project.\n   * @param projectId The project identifer of the project.\n   * This can take one of the following forms:\n   *\n   * 1. `<PROJECT_ID>` - The unique UUID4 ID for a project.\n   * 2. `<TEAM_NAME>/<PROJECT_NAME>` - The name of a project owned by the specified team.\n   * @param limit The number of proofs to return.\n   * @param offset The number of proofs to skip.\n   * @returns PagedProofInfoResponse OK\n   * @throws ApiError\n   */\n  public projectProofsPaginated(\n    projectId: string,\n    limit: number = 100,\n    offset?: number,\n  ): CancelablePromise<PagedProofInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/project/{project_id}/proofs/paginated\",\n      path: {\n        project_id: projectId,\n      },\n      query: {\n        limit: limit,\n        offset: offset,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Update Project Settings\n   * Update project settings.\n   * @param projectName The name of a project associated with the team.\n   * @param requestBody\n   * @returns ProjectInfoResponse OK\n   * @throws ApiError\n   */\n  public projectSettings(\n    projectName: string,\n    requestBody: ProjectSettingsInput,\n  ): CancelablePromise<ProjectInfoResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/project/{project_name}/settings\",\n      path: {\n        project_name: projectName,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        404: `Not Found`,\n        422: `Unprocessable Entity`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Circuit Smart Contract Verifier\n   * Get smart contract verifier for existing circuit\n   * @param circuitId The circuit identifer of the circuit.\n   * This can take one of the following forms:\n   *\n   * 1. `<CIRCUIT_ID>` - The unique UUID4 ID for an exact version of a compiled circuit.\n   * 2. `<CIRCUIT_NAME>` - The name of a circuit owned by the authenticated team. This will default to\n   * the most recent version of the circuit tagged as `latest`.\n   * 3. `<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by the authenticated team and an explicit\n   * tag. This corresponds to the most recent compilation of the circuit with the specified tag.\n   * 4. `<TEAM_NAME>/<CIRCUIT_NAME>` - The name of a circuit owned by the specified team.  This will\n   * default to the most recent version of the circuit tagged as `latest`.\n   * 5. `<TEAM_NAME>/<CIRCUIT_NAME>:<TAG>` - The name of a circuit owned by a specified team and an\n   * explicit tag. This corresponds to the most recent compilation of the team's circuit with the\n   * specified tag.\n   * @returns SmartContractVerifierResponse OK\n   * @throws ApiError\n   */\n  public circuitSmartContractVerifier(\n    circuitId: string,\n  ): CancelablePromise<SmartContractVerifierResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/smart_contract_verifier\",\n      path: {\n        circuit_id: circuitId,\n      },\n      errors: {\n        404: `Not Found`,\n        409: `Conflict`,\n        500: `Internal Server Error`,\n        501: `Not Implemented`,\n      },\n    });\n  }\n\n  /**\n   * Circuit Status\n   * Get status for a specific circuit.\n   * @param circuitId The UUID4 identifier associated with this circuit.\n   * @returns CircuitStatusResponse OK\n   * @throws ApiError\n   */\n  public circuitStatus(\n    circuitId: string,\n  ): CancelablePromise<CircuitStatusResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/circuit/{circuit_id}/status\",\n      path: {\n        circuit_id: circuitId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Change Password\n   * Change user password. Requires user authentication.\n   * @param requestBody\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public passwordChangeWithJwtAuth(\n    requestBody: PasswordChangeInput,\n  ): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/password/change\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        422: `Unprocessable Entity`,\n      },\n    });\n  }\n\n  /**\n   * Proof Histogram\n   * Get histogram data for a team's proofs.\n   * @param requestBody\n   * @returns ProofHistogramResponse OK\n   * @throws ApiError\n   */\n  public proofHistogram(\n    requestBody: ProofHistogramInput,\n  ): CancelablePromise<ProofHistogramResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/proof/histogram\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Proof List\n   * List proofs for the requesting team.\n   * @param requestBody\n   * @returns ProofInfoResponse OK\n   * @throws ApiError\n   */\n  public proofList(\n    requestBody: ProofListInput,\n  ): CancelablePromise<Array<ProofInfoResponse>> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/proof/list\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Proof List\n   * List proofs for the requesting team.\n   * @param requestBody\n   * @param limit The number of proofs to return.\n   * @param offset The number of proofs to skip.\n   * @returns PagedProofInfoResponse OK\n   * @throws ApiError\n   */\n  public proofListPaginated(\n    requestBody: ProofListInput,\n    limit: number = 100,\n    offset?: number,\n  ): CancelablePromise<PagedProofInfoResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/proof/list/paginated\",\n      query: {\n        limit: limit,\n        offset: offset,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Proof Status\n   * Get status for a specific proof.\n   * @param proofId The UUID4 identifier associated with this proof.\n   * @returns ProofStatusResponse OK\n   * @throws ApiError\n   */\n  public proofStatus(proofId: string): CancelablePromise<ProofStatusResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/proof/{proof_id}/status\",\n      path: {\n        proof_id: proofId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Sindri Manifest Schema\n   * Return Sindri manifest schema as JSON.\n   * @returns any OK\n   * @throws ApiError\n   */\n  public sindriManifestSchema(): CancelablePromise<Record<string, any>> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/sindri-manifest-schema.json\",\n    });\n  }\n\n  /**\n   * Avatar Upload\n   * Upload avatar for the team\n   * @param formData\n   * @returns TeamMeResponse Created\n   * @throws ApiError\n   */\n  public teamAvatarUpload(formData: {\n    files: Array<Blob>;\n  }): CancelablePromise<TeamMeResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/team/avatar/upload\",\n      formData: formData,\n      mediaType: \"multipart/form-data\",\n      errors: {\n        400: `Bad Request`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Create Team\n   * Create a new team\n   * @param requestBody\n   * @param sindriTeamId Required for Sindri JWT authentication.\n   * @returns TeamDetail Created\n   * @throws ApiError\n   */\n  public teamCreate(\n    requestBody: TeamCreateInput,\n    sindriTeamId?: string | null,\n  ): CancelablePromise<TeamDetail> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/team/create\",\n      headers: {\n        \"Sindri-Team-Id\": sindriTeamId,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        400: `Bad Request`,\n        409: `Conflict`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Team Detail\n   * Return details for the specified team\n   * @param teamSlug\n   * @returns TeamDetail OK\n   * @throws ApiError\n   */\n  public teamDetail(teamSlug: string): CancelablePromise<TeamDetail> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/team/{team_slug}/detail\",\n      path: {\n        team_slug: teamSlug,\n      },\n      errors: {\n        404: `Not Found`,\n      },\n    });\n  }\n\n  /**\n   * Team Invite\n   * Invite an email address to join the specified team\n   * @param requestBody\n   * @param sindriTeamId Required for Sindri JWT authentication.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public teamInvite(\n    requestBody: TeamInviteInput,\n    sindriTeamId?: string | null,\n  ): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/team/invite\",\n      headers: {\n        \"Sindri-Team-Id\": sindriTeamId,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n    });\n  }\n\n  /**\n   * Team Me\n   * Obtain team details for the currently authenticated team\n   * @returns TeamMeResponse OK\n   * @throws ApiError\n   */\n  public teamMe(): CancelablePromise<TeamMeResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/team/me\",\n    });\n  }\n\n  /**\n   * Team Members\n   * Return member list for the specified team\n   * @param teamSlug\n   * @param sindriTeamId Required for Sindri JWT authentication.\n   * @returns TeamMembersResponse OK\n   * @throws ApiError\n   */\n  public teamMembers(\n    teamSlug: string,\n    sindriTeamId?: string | null,\n  ): CancelablePromise<TeamMembersResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/team/{team_slug}/members\",\n      path: {\n        team_slug: teamSlug,\n      },\n      headers: {\n        \"Sindri-Team-Id\": sindriTeamId,\n      },\n      errors: {\n        404: `Not Found`,\n      },\n    });\n  }\n\n  /**\n   * Team Remove Member\n   * Remove a user from the specified team. Revokes all team API keys if the removed user was the last team member.\n   * @param requestBody\n   * @param sindriTeamId Required for Sindri JWT authentication.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public teamRemoveMember(\n    requestBody: TeamRemoveMemberInput,\n    sindriTeamId?: string | null,\n  ): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/team/remove-member\",\n      headers: {\n        \"Sindri-Team-Id\": sindriTeamId,\n      },\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        403: `Forbidden`,\n        404: `Not Found`,\n      },\n    });\n  }\n\n  /**\n   * Update Team Settings\n   * Update team settings.\n   * @param requestBody\n   * @returns TeamDetail OK\n   * @throws ApiError\n   */\n  public teamSettings(\n    requestBody: TeamSettingsInput,\n  ): CancelablePromise<TeamDetail> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/team/settings\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        404: `Not Found`,\n        422: `Unprocessable Entity`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n\n  /**\n   * Login User\n   * Login a user.\n   * @param requestBody\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public userLogin(\n    requestBody: UserLoginInput,\n  ): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/user/login\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        401: `Unauthorized`,\n        403: `Forbidden`,\n      },\n    });\n  }\n\n  /**\n   * Logout User\n   * Logout a user.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public userLogout(): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/v1/user/logout\",\n    });\n  }\n\n  /**\n   * User Me\n   * Obtain user details. Requires user authentication.\n   * @returns UserMeResponse OK\n   * @throws ApiError\n   */\n  public userMe(): CancelablePromise<UserMeResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/user/me\",\n    });\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ActionResponse } from \"../models/ActionResponse\";\nimport type { ProofInfoResponse } from \"../models/ProofInfoResponse\";\n\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\n\nexport class ProofsService {\n  constructor(public readonly httpRequest: BaseHttpRequest) {}\n\n  /**\n   * Proof Detail\n   * Get info for a specific proof.\n   * @param proofId The UUID4 identifier associated with this proof.\n   * @param includeProof Indicates whether to include the proof in the response.\n   * @param includePublic Indicates whether to include public inputs in the response.\n   * @param includeSmartContractCalldata Indicates whether to include the proof and public formatted as smart contract calldata in the response.\n   * @param includeVerificationKey Indicates whether to include the circuit's verification key in the response.\n   * @returns ProofInfoResponse OK\n   * @throws ApiError\n   */\n  public proofDetail(\n    proofId: string,\n    includeProof: boolean = true,\n    includePublic: boolean = true,\n    includeSmartContractCalldata: boolean = true,\n    includeVerificationKey: boolean = true,\n  ): CancelablePromise<ProofInfoResponse> {\n    return this.httpRequest.request({\n      method: \"GET\",\n      url: \"/api/v1/proof/{proof_id}/detail\",\n      path: {\n        proof_id: proofId,\n      },\n      query: {\n        include_proof: includeProof,\n        include_public: includePublic,\n        include_smart_contract_calldata: includeSmartContractCalldata,\n        include_verification_key: includeVerificationKey,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n        501: `Not Implemented`,\n      },\n    });\n  }\n\n  /**\n   * Delete Proof\n   * Delete a specific proof.\n   * @param proofId The UUID4 identifier associated with this proof.\n   * @returns ActionResponse OK\n   * @throws ApiError\n   */\n  public proofDelete(proofId: string): CancelablePromise<ActionResponse> {\n    return this.httpRequest.request({\n      method: \"DELETE\",\n      url: \"/api/v1/proof/{proof_id}/delete\",\n      path: {\n        proof_id: proofId,\n      },\n      errors: {\n        404: `Not Found`,\n        500: `Internal Server Error`,\n      },\n    });\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { Schema } from \"../models/Schema\";\nimport type { TokenObtainPairInputSchema } from \"../models/TokenObtainPairInputSchema\";\nimport type { TokenObtainPairOutputSchema } from \"../models/TokenObtainPairOutputSchema\";\nimport type { TokenRefreshInputSchema } from \"../models/TokenRefreshInputSchema\";\nimport type { TokenRefreshOutputSchema } from \"../models/TokenRefreshOutputSchema\";\nimport type { TokenVerifyInputSchema } from \"../models/TokenVerifyInputSchema\";\n\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\n\nexport class TokenService {\n  constructor(public readonly httpRequest: BaseHttpRequest) {}\n\n  /**\n   * Verify Token\n   * @param requestBody\n   * @returns Schema OK\n   * @throws ApiError\n   */\n  public jwtTokenVerify(\n    requestBody: TokenVerifyInputSchema,\n  ): CancelablePromise<Schema> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/token/verify\",\n      body: requestBody,\n      mediaType: \"application/json\",\n    });\n  }\n\n  /**\n   * Generate JWT Token Pair\n   * Override the ninja_jwt default `obtain_token` method in order to\n   * add email verification check before generating a token.\n   * @param requestBody\n   * @returns TokenObtainPairOutputSchema OK\n   * @throws ApiError\n   */\n  public jwtTokenGenerate(\n    requestBody: TokenObtainPairInputSchema,\n  ): CancelablePromise<TokenObtainPairOutputSchema> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/token/pair\",\n      body: requestBody,\n      mediaType: \"application/json\",\n      errors: {\n        403: `Forbidden`,\n      },\n    });\n  }\n\n  /**\n   * Refresh Token\n   * @param requestBody\n   * @returns TokenRefreshOutputSchema OK\n   * @throws ApiError\n   */\n  public jwtTokenRefresh(\n    requestBody: TokenRefreshInputSchema,\n  ): CancelablePromise<TokenRefreshOutputSchema> {\n    return this.httpRequest.request({\n      method: \"POST\",\n      url: \"/api/token/refresh\",\n      body: requestBody,\n      mediaType: \"application/json\",\n    });\n  }\n}\n","/* generated using openapi-typescript-codegen -- do no edit */\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { BaseHttpRequest } from \"./core/BaseHttpRequest\";\nimport type { OpenAPIConfig } from \"./core/OpenAPI\";\nimport { AxiosHttpRequest } from \"./core/AxiosHttpRequest\";\n\nimport { AuthorizationService } from \"./services/AuthorizationService\";\nimport { CircuitsService } from \"./services/CircuitsService\";\nimport { InternalService } from \"./services/InternalService\";\nimport { ProofsService } from \"./services/ProofsService\";\nimport { TokenService } from \"./services/TokenService\";\n\ntype HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;\n\nexport class ApiClient {\n  public readonly authorization: AuthorizationService;\n  public readonly circuits: CircuitsService;\n  public readonly internal: InternalService;\n  public readonly proofs: ProofsService;\n  public readonly token: TokenService;\n\n  public readonly request: BaseHttpRequest;\n\n  constructor(\n    config?: Partial<OpenAPIConfig>,\n    HttpRequest: HttpRequestConstructor = AxiosHttpRequest,\n  ) {\n    this.request = new HttpRequest({\n      BASE: config?.BASE ?? \"https://sindri.app\",\n      VERSION: config?.VERSION ?? \"1.17.19\",\n      WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,\n      CREDENTIALS: config?.CREDENTIALS ?? \"include\",\n      TOKEN: config?.TOKEN,\n      USERNAME: config?.USERNAME,\n      PASSWORD: config?.PASSWORD,\n      HEADERS: config?.HEADERS,\n      ENCODE_PATH: config?.ENCODE_PATH,\n    });\n\n    this.authorization = new AuthorizationService(this.request);\n    this.circuits = new CircuitsService(this.request);\n    this.internal = new InternalService(this.request);\n    this.proofs = new ProofsService(this.request);\n    this.token = new TokenService(this.request);\n  }\n}\n","import fs from \"fs\";\nimport path from \"path\";\n\nimport envPaths from \"env-paths\";\nimport _ from \"lodash\";\nimport { z } from \"zod\";\n\nimport { type Logger } from \"lib/logging\";\n\nconst getConfigPath = (): string => {\n  const paths = envPaths(\"sindri\", {\n    suffix: \"\",\n  });\n  return path.join(paths.config, \"sindri.conf.json\");\n};\n\nconst ConfigSchema = z.object({\n  auth: z\n    .nullable(\n      z.object({\n        apiKey: z.string(),\n        apiKeyId: z.string(),\n        apiKeyName: z.string(),\n        baseUrl: z.string().url(),\n        teamId: z.number(),\n        teamSlug: z.string(),\n      }),\n    )\n    .default(null),\n});\n\ntype ConfigSchema = z.infer<typeof ConfigSchema>;\n\nconst defaultConfig: ConfigSchema = ConfigSchema.parse({});\n\nexport const loadConfig = (logger?: Logger): ConfigSchema => {\n  const configPath = getConfigPath();\n  if (fs.existsSync(configPath)) {\n    logger?.debug(`Loading config from \"${configPath}\".`);\n    try {\n      const configFileContents: string = fs.readFileSync(configPath, {\n        encoding: \"utf-8\",\n      });\n      const loadedConfig = ConfigSchema.parse(JSON.parse(configFileContents));\n      logger?.debug(\"Config loaded successfully.\");\n      return loadedConfig;\n    } catch (error) {\n      logger?.warn(\n        `The config schema in \"${configPath}\" is invalid and will not be used.\\n` +\n          `To remove it and start fresh, run:\\n    rm ${configPath}`,\n      );\n      logger?.debug(error);\n    }\n  }\n  logger?.debug(\n    `Config file \"${configPath}\" does not exist, initializing default config.`,\n  );\n  return _.cloneDeep(defaultConfig);\n};\n\nexport class Config {\n  protected _config!: ConfigSchema;\n  protected readonly logger: Logger | undefined;\n\n  constructor(logger?: Logger) {\n    this.logger = logger;\n    this.reload();\n  }\n\n  get auth(): ConfigSchema[\"auth\"] {\n    return _.cloneDeep(this._config.auth);\n  }\n\n  get config(): ConfigSchema {\n    return _.cloneDeep(this._config);\n  }\n\n  reload() {\n    this._config = loadConfig(this.logger);\n  }\n\n  update(configData: Partial<ConfigSchema>) {\n    // Merge and validate the configs.\n    this.logger?.debug(\"Merging in config update:\");\n    this.logger?.debug(configData);\n    const newConfig: ConfigSchema = _.cloneDeep(this._config);\n    _.merge(newConfig, configData);\n    this._config = ConfigSchema.parse(newConfig);\n\n    // Create the directory if it doesn't exist.\n    const configPath = getConfigPath();\n    const directory = path.dirname(configPath);\n    if (!fs.existsSync(directory)) {\n      fs.mkdirSync(directory, { recursive: true });\n    }\n\n    // Write out the new config.\n    this.logger?.debug(\n      `Writing merged config to \"${configPath}\":`,\n      this._config,\n    );\n    fs.writeFileSync(configPath, JSON.stringify(this._config, null, 2), {\n      encoding: \"utf-8\",\n    });\n  }\n}\n","import pino, { type BaseLogger as Logger } from \"pino\";\nimport pretty from \"pino-pretty\";\n\nexport type { Logger };\n\n/**\n * The minimum log level to print.\n */\nexport type LogLevel =\n  | \"silent\"\n  | \"fatal\"\n  | \"error\"\n  | \"warn\"\n  | \"info\"\n  | \"debug\"\n  | \"trace\";\n\nexport const createLogger = (level?: LogLevel): Logger => {\n  const logger = pino(\n    process.env.BROWSER_BUILD\n      ? {\n          browser: { asObject: true },\n        }\n      : pretty({\n          colorize: true,\n          destination: 2,\n          ignore: \"hostname,pid\",\n          levelFirst: false,\n          sync: true,\n        }),\n  );\n  logger.level =\n    level ?? process.env.NODE_ENV === \"production\" ? \"silent\" : \"info\";\n  return logger;\n};\nexport const logger = createLogger();\n\nexport const print = console.log;\n","import type { Logger } from \"lib/logging\";\n\nlet cachedDefaultMeta: Meta | null = null;\n\n/**\n * Retrieves the default metadata from the `SINDRI_META` environment variable.\n *\n * The `SINDRI_META` environment variable can be set to a JSON object (e.g., `{\"key\": \"value\"}`) or\n * a colon-delimited string of key-value pairs (e.g., `key1=value1:key2=value2`). In the\n * colon-delimited format, you can escape actual colons by doubling them (`::` will map to `:`).\n *\n * @param options.cache - Whether to cache the default metadata. Note that retrieving a cached value\n * will not raise exceptions or log warnings, even if the `raiseExceptions` option is set to `true`.\n * @param options.logger - The optional logger to use for warning messages.\n * @param options.raiseExceptions - Whether to raise exceptions for invalid metadata entries.\n * Warnings will not be logged if this is set to `true`.\n */\nexport function getDefaultMeta({\n  cache = true,\n  logger,\n  raiseExceptions = false,\n}: { cache?: boolean; logger?: Logger; raiseExceptions?: boolean } = {}): Meta {\n  if (cache && cachedDefaultMeta) {\n    return cachedDefaultMeta;\n  }\n\n  // There are no environment variables in a browser.\n  if (process.env.BROWSER_BUILD) {\n    return (cachedDefaultMeta = {});\n  }\n\n  const { SINDRI_META } = process.env;\n  if (!SINDRI_META) {\n    return (cachedDefaultMeta = {});\n  }\n\n  // Handle the filtering, validation, logging, and/or error handling for each metadata entry.\n  const validationFilter = ([key, value]: [string, unknown]): boolean => {\n    if (typeof value !== \"string\") {\n      const errorMessage = `Invalid metadata entry for '${key}' (value must be a string).`;\n      if (raiseExceptions) {\n        throw new Error(errorMessage);\n      }\n      logger?.warn(\n        {\n          key,\n          value,\n          SINDRI_META,\n        },\n        errorMessage + \" Ignoring.\",\n      );\n      return false;\n    }\n    const validationError = validateMetaEntry(key, value);\n    if (validationError) {\n      if (raiseExceptions) {\n        throw new Error(validationError);\n      }\n      logger?.warn(\n        {\n          key,\n          value,\n          SINDRI_META,\n        },\n        validationError + \" Ignoring.\",\n      );\n      return false;\n    }\n    return true;\n  };\n\n  // Support specifying default metadata as JSON.\n  if (SINDRI_META.startsWith(\"{\")) {\n    try {\n      return (cachedDefaultMeta = Object.fromEntries(\n        Object.entries(JSON.parse(SINDRI_META)).filter(validationFilter),\n      ) as Meta);\n    } catch (error) {\n      const errorMessage = \"Failed to parse 'SINDRI_META' as JSON.\";\n      if (raiseExceptions) {\n        throw new Error(errorMessage);\n      }\n      logger?.warn(\n        {\n          SINDRI_META,\n          error: (error as Error).toString(),\n        },\n        errorMessage + \" Using '{}' as the default.\",\n      );\n      return (cachedDefaultMeta = {});\n    }\n  }\n\n  // Support the `key=value:key=value` format.\n  const colonPlaceholder = \"\\0\";\n  // Split the string into :-delimited pieces, and unescape `::` to `:` in each segment.\n  return (cachedDefaultMeta = Object.fromEntries(\n    SINDRI_META.replace(/::/g, colonPlaceholder)\n      .split(\":\")\n      .map((segment) => segment.replace(new RegExp(colonPlaceholder, \"g\"), \":\"))\n      // Split each piece into a key and value.\n      .filter((segment) => {\n        if (!segment.includes(\"=\")) {\n          const errorMessage =\n            `Invalid 'SINDRI_META' metadata segment '${segment}' ` +\n            \"(missing '=', try 'key=value').\";\n          if (raiseExceptions) {\n            throw new Error(errorMessage);\n          }\n          logger?.warn({ segment, SINDRI_META }, errorMessage + \" Ignoring.\");\n          return false;\n        }\n        return true;\n      })\n      .map((segment): [key: string, value: string] => {\n        const index = segment.indexOf(\"=\");\n        return [segment.slice(0, index), segment.slice(index + 1)];\n      })\n      // Validate the keys and values (logic should match the backend validation).\n      .filter(validationFilter),\n  ));\n}\n\nexport type Meta = Record<string, string>;\n\n/**\n * Validates the metadata and merges it with the default metadata.\n *\n * @param meta - The metadata to validate and merge.\n * @returns The validated and merged metadata.\n */\nexport function validateMetaAndMergeWithDefaults(meta: Meta): Meta {\n  const defaultMeta = getDefaultMeta({ raiseExceptions: true });\n  Object.entries(meta).forEach(([key, value]) => {\n    const validationError = validateMetaEntry(key, value);\n    if (validationError) {\n      throw new Error(validationError);\n    }\n  });\n  return { ...defaultMeta, ...meta };\n}\n\n/**\n * Validates a key-value pair of metadata.\n *\n * @param key - The metadata key.\n * @param value - The metadata value.\n * @returns An error message if the entry is invalid, otherwise `null`.\n */\nexport function validateMetaEntry(key: string, value: string): string | null {\n  // These validation constraints must be kept in sync with the backend.\n  const keyLengthLow = 1;\n  const keyLengthHigh = 64;\n  const valueLengthLow = 0;\n  const valueLengthHigh = 4096;\n  const keyRegex = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n\n  // Validate the key.\n  if (key.length < keyLengthLow || key.length > keyLengthHigh) {\n    return (\n      `Invalid metadata key length for '${key}' (must be ` +\n      `${keyLengthLow}-${keyLengthHigh} characters).`\n    );\n  }\n  if (!keyRegex.test(key)) {\n    return (\n      `Invalid metadata key for '${key}' (must start with an alphabet character and only ` +\n      \"include alphanumeric characters, underscores, and hyphens).\"\n    );\n  }\n\n  // Validate the value.\n  if (value.length < valueLengthLow || value.length > valueLengthHigh) {\n    return (\n      `Invalid metadata value length for '${key}' (must be ` +\n      `${valueLengthLow}-${valueLengthHigh} characters).`\n    );\n  }\n\n  // Otherwise, the entry is valid.\n  return null;\n}\n","import { SindriClient } from \"./client\";\n\nexport default new SindriClient();\n\nexport type * from \"./client\";\nexport type { LogLevel } from \"./logging\";\n"]}