{"version":3,"file":"environment.mjs","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":";;;;;;AAMA,OAAO,EAAE,WAAW,EAAE,mCAAmC;AAMzD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,wBAAwB;AAE7D,OAAO,gBAAe,8BAA8B;;AAGpD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,8BAAoB;AAEtD,OAAO,EAAE,UAAU,EAAE,sBAAkB;AAMvC,MAAM,GAAG,GAAG,kBAAkB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAE1D,MAAM,OAAO,gBAAiB,SAAQ,eAAe;IAC1C,QAAQ,CAA0B;IAE3C,OAAO,CAAqB;IAE5B,SAAS,CAA4C;IAErD;;;;;OAKG;IACH,YAAY,OAA8B,EAAE,OAA2B;QACrE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QAEpB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,CAAC;QAC3D,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,WAAW,CAKf,SAAiB,IAAI,CAAC,MAAM,EAC5B,UAAgD,EAAE;QAElD,MAAM,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,CAAC;QAC3D,IAAI,CAAC,SAAS,GAAG,MAAM,WAAW,CAAC,MAAgB,EAAE,OAAO,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,MAAM;QACR,MAAM,CACJ,IAAI,CAAC,OAAO,EACZ,yEAAyE,CAC1E,CAAC;QAEF,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAiB,CAAC;QACvD,OAAO,0BAA0B,IAAI,EAAE,CAAC;IAC1C,CAAC;CACF;AAED,eAAe,gBAAgB,CAAC","sourcesContent":["import type {\n  EnvironmentContext,\n  JestEnvironmentConfig,\n} from '@jest/environment';\nimport type { ExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { installSnap } from '@metamask/snaps-simulation';\nimport type {\n  InstalledSnap,\n  InstallSnapOptions,\n  SnapHelpers,\n} from '@metamask/snaps-simulation';\nimport { assert, createModuleLogger } from '@metamask/utils';\nimport type { Server } from 'http';\nimport NodeEnvironment from 'jest-environment-node';\nimport type { AddressInfo } from 'net';\n\nimport { rootLogger, startServer } from './internals';\nimport type { SnapsEnvironmentOptions } from './options';\nimport { getOptions } from './options';\n\ndeclare global {\n  const snapsEnvironment: SnapsEnvironment;\n}\n\nconst log = createModuleLogger(rootLogger, 'environment');\n\nexport class SnapsEnvironment extends NodeEnvironment {\n  readonly #options: SnapsEnvironmentOptions;\n\n  #server: Server | undefined;\n\n  #instance: (InstalledSnap & SnapHelpers) | undefined;\n\n  /**\n   * Constructor.\n   *\n   * @param options - The environment options.\n   * @param context - The environment context.\n   */\n  constructor(options: JestEnvironmentConfig, context: EnvironmentContext) {\n    super(options, context);\n    this.#options = getOptions(options.projectConfig.testEnvironmentOptions);\n  }\n\n  /**\n   * Set up the environment. This starts the built-in HTTP server, and creates a\n   * new browser instance.\n   */\n  async setup() {\n    await super.setup();\n\n    if (this.#options.server.enabled) {\n      log('Starting server.');\n      this.#server = await startServer(this.#options.server);\n    }\n\n    this.global.snapsEnvironment = this;\n  }\n\n  /**\n   * Tear down the environment. This closes the browser, and stops the built-in\n   * HTTP server.\n   */\n  async teardown() {\n    await this.#instance?.executionService.terminateAllSnaps();\n    this.#server?.close();\n    await super.teardown();\n  }\n\n  /**\n   * Install a Snap in the environment. This will terminate any previously\n   * installed Snaps, and run the Snap code in a new execution service.\n   *\n   * @param snapId - The ID of the Snap to install.\n   * @param options - The options to use when installing the Snap.\n   * @param options.executionService - The execution service to use.\n   * @param options.executionServiceOptions - The options to use when creating the\n   * execution service, if any. This should only include options specific to the\n   * provided execution service.\n   * @param options.options - The simulation options.\n   * @template Service - The type of the execution service.\n   * @returns The installed Snap.\n   */\n  async installSnap<\n    Service extends new (\n      ...args: any[]\n    ) => InstanceType<typeof ExecutionService>,\n  >(\n    snapId: string = this.snapId,\n    options: Partial<InstallSnapOptions<Service>> = {},\n  ) {\n    await this.#instance?.executionService.terminateAllSnaps();\n    this.#instance = await installSnap(snapId as SnapId, options);\n    return this.#instance;\n  }\n\n  /**\n   * Get the snap ID for the current environment, which is used if no snap ID is\n   * passed to {@link installSnap}. This assumes that the built-in server is\n   * running.\n   *\n   * @returns The snap ID.\n   * @throws If the server is not running.\n   */\n  get snapId() {\n    assert(\n      this.#server,\n      'You must specify a snap ID, because the built-in server is not running.',\n    );\n\n    const { port } = this.#server.address() as AddressInfo;\n    return `local:http://localhost:${port}`;\n  }\n}\n\nexport default SnapsEnvironment;\n"]}