[
  {
    "path": ".editorconfig",
    "content": "# See http://editorconfig.org/\n# EditorConfig helps developers define and maintain consistent coding styles\n# between different editors and IDEs. The EditorConfig project consists of a\n# file format for defining coding styles and a collection of text editor plugins\n# that enable editors to read the file format and adhere to defined styles.\n# EditorConfig files are easily readable and they work nicely with version\n# control systems.\n\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  parser: \"@typescript-eslint/parser\",\n  plugins: [\n    \"@typescript-eslint\",\n  ],\n  rules: {\n    \"@typescript-eslint/ban-ts-ignore\": 0,\n    \"no-console\": 0,\n    \"no-else-return\": \"error\",\n    \"@typescript-eslint/no-use-before-define\": 0,\n    \"@typescript-eslint/camelcase\": 0,\n    \"no-prototype-builtins\": 0,\n    \"max-lines-per-function\": [\n      \"error\",\n      {\n        \"max\": 20,\n        \"skipComments\": true,\n      },\n    ],\n    \"no-shadow\": \"error\",\n    \"max-params\": [\n      \"error\",\n      3,\n    ],\n    \"max-statements-per-line\": [\n      \"error\",\n      {\n        \"max\": 2,\n      },\n    ],\n    \"complexity\": [\n      \"error\",\n      15,\n    ],\n    \"no-undef\": 0,\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"*.test.ts\"],\n      \"rules\": {\n        \"max-lines-per-function\": 0,\n      },\n    },\n  ],\n  extends: [\n    \"eslint:recommended\",\n    \"plugin:@typescript-eslint/eslint-recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n  ],\n};\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "## Issue Type\n\n<!--\nKeep the one that applies and remove the others\ne.g. - Bug Report\n-->\n\n- Bug Report\n- Feature Request\n- Other\n\n## Expected\n\n<!-- Expected behavior -->\n\n## Actual\n\n<!-- Current behavior -->\n\n## Possible Solutions\n\n<!-- Maybe you can help with this bug or feature? -->\n\n## Info\n\n- DenoX version:\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## Description\nDescribe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.\n\n**Types of changes**\nWhat types of changes does your code introduce? Keep the one that applies:\n- New feature (non-breaking change which adds functionality)\n- Bugfix (non-breaking change which fixes an issue)\n- Change of existing functionality\n- Breaking change (fix or feature that would cause existing functionality to not work as expected)\n- Docs\n\n**Related links**\nRelated links section, that would have a link to issues and any other relevant information.\n\n## Changelog\n#### Added\n\n#### Changed\n\n#### Removed\n\n#### Fixed\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non: [push]\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest, windows-latest]\n        deno: [1.0.5, 1.1.3, 1.2.2]\n    steps:\n    - uses: actions/checkout@v2\n      with:\n        fetch-depth: '0'\n    - uses: denolib/setup-deno@master\n      with:\n        deno-version: ${{ matrix.deno }}\n    - uses: actions/setup-node@v1\n      with:\n        node-version: '12'\n    - run: npm install typescript eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin tsc-silent --save-dev\n    - run: ./node_modules/.bin/eslint **/**.ts --ext .ts\n    - run: deno install -Af denox.ts\n    - run: deno test -A --failfast src/ test/\n"
  },
  {
    "path": ".vscode/denox.code-workspace",
    "content": "{\n\t\"folders\": [\n\t\t{\n\t\t\t\"path\": \"..\"\n\t\t}\n\t],\n\t\"settings\": {\n\t\t\"deno.enabled\": true\n\t}\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n----------------------------------\n\n1. File an issue to notify the maintainers about what you're working on.\n2. Fork the repo, develop and test your code changes, add docs.\n3. Make sure that your commit messages clearly describe the changes.\n4. Send a pull request.\n\nFile an Issue\n----------------------------------\n\nUse the issue tracker to start the discussion. It is possible that someone\nelse is already working on your idea, your approach is not quite right, or that\nthe functionality exists already. The ticket you file in the issue tracker will\nbe used to hash that all out.\n\nStyle Guides\n-------------------\n1. Write in UTF-8 in TypeScript\n2. User modular architecture to group similar functions, classes, etc.\n3. Always use 2 spaces for indentation (don't use tabs)\n4. Try to limit line length to 80 characters\n5. Class names should always be capitalized\n6. Function names should always be camelCase\n7. Look at the existing style and adhere accordingly\n8. Run `deno fmt` before submitting your code\n\nFork the Repository\n-------------------\n\nBe sure to add the relevant tests before making the pull request.\n\nMake the Pull Request\n---------------------\n\nOnce you have made all your changes, tests, and updated the documentation,\nmake a pull request to move everything back into the main branch of the\n`repository`. Be sure to reference the original issue in the pull request.\nExpect some back-and-forth with regards to style and compliance of these\nrules.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License\n\nCopyright (c) 2020 Khaled Bentoumi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/BentoumiTech/denox\" alt=\"DenoX\">\n    <img height=\"100%\" width=\"475px\" src=\"https://raw.githubusercontent.com/BentoumiTech/denox/master/.github/img/denox-logo.png\" alt=\"Deno script runner\">\n  </a>\n  <br/>\n</h1>\n<p align=\"center\">\n  <img src=\"https://img.shields.io/github/workflow/status/BentoumiTech/denox/CI/master\" alt=\"GitHub Workflow Status\"/>\n  <img src=\"https://img.shields.io/github/v/tag/bentoumitech/denox?style=flat-square\" alt=\"latest SemVer\"/>\n  <img src=\"https://img.shields.io/badge/contribution-welcome-brightgreen.svg?style=flat-square\" alt=\"Contribution welcome\"/>\n  <img src=\"https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square\" alt=\"Commitizen friendly\"/>\n  <img src=\"https://img.shields.io/badge/semantic-release-e10079.svg?style=flat-square\" alt=\"Semantic release\"/>\n  <img src=\"https://img.shields.io/github/license/BentoumiTech/denox?logo=MIT&style=flat-square\" alt=\"MIT License\"/>\n  <br />\n  <br />\n  <a href=\"#installupgrade\">Install/Upgrade</a> •\n  <a href=\"#overview\">Overview</a> •\n  <a href=\"#usage\">Usage</a> •\n  <a href=\"#getting-started\">Getting started</a> •\n  <a href=\"#contributing\">Contributing</a>\n  <br />\n  <br />\n  <img height=\"100%\" width=\"600px\" src=\"https://raw.githubusercontent.com/bentoumitech/denox/master/.github/img/screenshot-example.png\" alt=\"DenoX screenshot example\">\n</p>\n\n## Install/Upgrade\n\nPrerequisites: [Deno](https://github.com/denoland/deno_install) (>=1.0.0)\n\n```bash\n$ deno install -Af -n denox https://denopkg.com/BentoumiTech/denox/denox.ts\n```\n\n## Overview\n\nDenoX is a cross platform script runner and workspace wrapper for Deno\n\nUsing DenoX, you can set up your workspace scripts permissions and options in declarative code.\n\nIn short, it allows you to to replace this:\n\n```bash\n$ deno run --allow-read --allow-write --allow-net main.ts\n```\n\nwith this:\n\n```bash\n$ denox run start\n```\n\n- **DRY** Only write your permissions and options once.\n- **Packaged** Your code can run on a different machine with a short single command `denox run start`\n- **Cross Platform** DenoX support and is tested on Linux, Mac OS and Windows.\n- **Extensible** :soon:\n\n## Usage\n\n```bash\n$ denox --help\ndenox v0.4.0\n\nUsage:\n  $ denox <command> [options]\n\nCommands:\n  run <script> [...args]  Run a script\n\nFor more info, run any command with the `--help` flag:\n  $ denox run --help\n\nOptions:\n  -h, --help     Display this message\n  -v, --version  Display version number\n\nExamples:\ndenox run start\n```\n\n## Getting Started\n\n### `deno-workspace` file\n\nScripts and options need to be defined in a `deno-workspace` file at the root of your project.\n\nDenoX supports YAML, JSON and typescript as format for `deno-workspace`.\n\nIn the following examples running `$ denox run start` will execute main.ts file with `example.com` networking permissions\n\n#### YAML\n\n`deno-workspace.yml`\n\n```yaml\nscripts:\n  start:\n    file: main.ts\n    deno_options:\n      allow-net: example.com\n```\n\n#### JSON\n\n`deno-workspace.json`\n\n```json\n{\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"main.ts\",\n      \"deno_options\": {\n        \"allow-net\": \"example.com\"\n      }\n    }\n  }\n}\n```\n\n#### Typescript\n\n`deno-workspace.ts`\n\n```typescript\nimport { DenoWorkspace } from \"https://denopkg.com/BentoumiTech/denox/src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"main.ts\",\n      \"deno_options\": {\n        \"allow-net\": \"example.com\"\n      }\n    },\n  },\n};\n\nexport { workspace };\n```\n\n## Scripts\n\nYou can easily run scripts using denox by adding them to the \"scripts\" field in `deno-workspace` and run them with `denox run <script-name>`.\n\n### Example:\n\n```yaml\nscripts:\n  # \"denox run start\" will execute main.ts with example.com networking permissions\n  start:\n    file: main.ts\n    deno_options:\n      allow-net: example.com\n  # \"denox run develop\" will execute main.ts with localhost networking permissions and source code cache reloaded\n  develop:\n    file: main.ts\n    deno_options:\n      allow-net: localhost\n      reload: true\n      v8-flags:\n        - --regexp-tier-up\n        - --adjust-os-scheduling-parameters true\n```\n\n## Options\n\nScripts can be extended with options.\n\n### deno_options:\n\nDeno options will add the corresponding deno argument with it's value to the deno command.\n\nIt supports string, array of strings and boolean.\n\n### Example:\n\n```yaml\nscripts:\n  # \"denox run start\" will execute \"deno run --allow-net=example.com github.com --reload --allow-read=./files main.ts\"\n  start:\n    file: main.ts\n    deno_options:\n      reload: true\n      allow-net:\n        - example.com\n        - github.com\n      allow-read: ./files\n      allow-write: false\n```\n\n### Compatibility\n\nIt currently support all the options that are accepted by the `deno run` command. For more informations refer to `deno run --help`.\n\n```\nallow-all, allow-env, allow-hrtime, allow-net, allow-plugin, allow-read, allow-run,\nallow-write, cached-only, cert, config, importmap, inspect, inspect-brk, lock, lock-write,\nlog-level, no-remote, quiet, reload, seed, unstable, v8-flags\n```\n\n## Globals\n\nOptions added in \"globals\" field gets added to all scripts.\n\n> Note: If a same option is set in a script and also set globally the script scoped value overwrite the global one\n\n### Example:\n\n```yaml\nscripts:\n  # \"denox run develop\" inherit the --allow-read permission from the globals deno_options\n  # \"deno run --all-read main.ts\"\n  develop:\n    file: main.ts\nglobals:\n  deno_options:\n    allow-read: true\n```\n\n## Contributing\n\nPlease take a look at our [contributing](./CONTRIBUTING.md) guidelines if you're interested in helping!\n"
  },
  {
    "path": "denox.ts",
    "content": "import { cac } from \"./deps.ts\";\n\nimport run from \"./src/run.ts\";\nimport { error } from \"./src/utils/consolex.ts\";\nimport { CURRENT_VERSION } from \"./src/const.ts\";\n\nconst cli = cac(\"denox\");\n\ncli\n  .command(\n    \"run <script> [...args]\",\n    \"Run a script\",\n    { allowUnknownOptions: true, ignoreOptionDefaultValue: true },\n  )\n  .example(\"denox run start arg1 arg2 --namedArg=value\")\n  .action(run);\n\n// ToDO: remove '@ts-ignore' (and eslint directive) when vscode_deno is fixed to work with @deno_types; ref: <https://github.com/cacjs/cac/issues/75> , <https://github.com/denoland/vscode_deno/issues/21>\n/* eslint @typescript-eslint/ban-ts-comment: \"off\" */\n// deno-lint-ignore ban-ts-comment\n// @ts-ignore\ncli.on(\"command:*\", () => {\n  // deno-lint-ignore ban-ts-comment\n  // @ts-ignore\n  error(`Invalid command: ${cli.args.join(\" \")}`);\n});\n\ncli.example(\"denox run start\");\n\ncli.help(() => ({}));\n\ncli.version(CURRENT_VERSION);\n\ncli.parse();\n"
  },
  {
    "path": "deps.ts",
    "content": "export { parse as parseYaml } from \"https://deno.land/std@0.88.0/encoding/yaml.ts\";\nexport { YAMLError } from \"https://deno.land/std@0.88.0/encoding/_yaml/error.ts\";\nexport { red } from \"https://deno.land/std@0.50.0/fmt/colors.ts\";\nexport { extname, resolve } from \"https://deno.land/std@0.61.0/path/mod.ts\";\n\n// @deno-types=\"https://unpkg.com/cac@6.5.9/mod.d.ts\"\nexport { cac } from \"https://unpkg.com/cac@6.5.9/mod.js\";\n"
  },
  {
    "path": "dev_deps.ts",
    "content": "export * from \"./deps.ts\";\n\nexport {\n  assertEquals,\n  assertArrayContains,\n  assertThrows,\n  assertStrContains,\n  assertThrowsAsync,\n} from \"https://deno.land/std@0.50.0/testing/asserts.ts\";\n\nexport { stripColor } from \"https://deno.land/std@0.61.0/fmt/colors.ts\";\n\nexport { join } from \"https://deno.land/std@0.61.0/path/mod.ts\";\n"
  },
  {
    "path": "example/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\nglobals:\n  deno_options:\n    allow-read:\n      - './files'\n    seed: 1\n    reload: true\n\n\n\n"
  },
  {
    "path": "example/files/test.txt",
    "content": "Hello World\n"
  },
  {
    "path": "example/main.ts",
    "content": "const data = Deno.readFileSync(\"./files/test.txt\");\nconst decoder = new TextDecoder(\"utf-8\");\n\nconsole.log(decoder.decode(data));\n"
  },
  {
    "path": "src/const.ts",
    "content": "const CURRENT_VERSION = \"0.4.0\";\nconst GITHUB_REPO_NAME = \"BentoumiTech/denox\";\nconst DENO_WORKSPACE_FILES = [\n  \"deno-workspace.yml\",\n  \"deno-workspace\",\n  \"deno-workspace.yaml\",\n  \".deno-workspace\",\n  \".deno-workspace.yml\",\n  \".deno-workspace.yaml\",\n  \"deno-workspace.json\",\n  \".deno-workspace.json\",\n  \"deno-workspace.ts\",\n  \".deno-workspace.ts\",\n];\n\nexport { CURRENT_VERSION, GITHUB_REPO_NAME, DENO_WORKSPACE_FILES };\n"
  },
  {
    "path": "src/deno_options/__tests__/build_cli_arguments.test.ts",
    "content": "import { assertEquals, assertArrayContains } from \"../../../dev_deps.ts\";\nimport { buildDenoCLIOptionsArgs } from \"../build_cli_arguments.ts\";\n\nDeno.test(\"parse a single value CLI option\", () => {\n  assertEquals(\n    buildDenoCLIOptionsArgs({ \"allow-net\": \"example.com\" }),\n    [\"--allow-net=example.com\"],\n  );\n});\n\nDeno.test(\"parse a truthy boolean value CLI option\", () => {\n  assertEquals(\n    buildDenoCLIOptionsArgs({ \"allow-env\": true }),\n    [\"--allow-env\"],\n  );\n});\n\nDeno.test(\"parse a falsey boolean value CLI option\", () => {\n  assertEquals(\n    buildDenoCLIOptionsArgs({ \"allow-env\": false }),\n    [],\n  );\n});\n\nDeno.test(\"parse an array of values CLI option\", () => {\n  assertEquals(\n    buildDenoCLIOptionsArgs({ \"allow-net\": [\"example.com\", \"google.com\"] }),\n    [\"--allow-net=example.com,google.com\"],\n  );\n});\n\nDeno.test(\"parse mutliple CLI option\", () => {\n  const cliArgumentsArray = buildDenoCLIOptionsArgs(\n    {\n      \"allow-net\": [\"example.com\", \"google.com\"],\n      \"allow-env\": true,\n      \"allow-read\": \".\",\n      \"seed\": 1,\n      \"cert\": \"./certfile\",\n      \"allow-write\": false,\n    },\n  );\n\n  assertArrayContains(\n    cliArgumentsArray,\n    [\n      \"--allow-net=example.com,google.com\",\n      \"--allow-env\",\n      \"--allow-read=.\",\n      \"--seed\",\n      1,\n      \"--cert=./certfile\",\n    ],\n  );\n\n  assertEquals(cliArgumentsArray.length, 6);\n});\n"
  },
  {
    "path": "src/deno_options/__tests__/parse.test.ts",
    "content": "import { assertEquals, assertThrows } from \"../../../dev_deps.ts\";\nimport { parseDenoOptions } from \"../parse.ts\";\nimport { DenoOptionIncorrectType } from \"../../utils/DenoXErrors.ts\";\n\nDeno.test(\"deno_options not defined\", () => {\n  const script = { file: \"\" };\n  const global = {};\n  const denoOptions = parseDenoOptions(global, script);\n\n  assertEquals(\n    denoOptions,\n    [],\n  );\n});\n\nDeno.test(\"deno_options only defined in globals\", () => {\n  const script = { file: \"\" };\n  const global = { deno_options: { \"allow-read\": true } };\n  const denoOptions = parseDenoOptions(global, script);\n\n  assertEquals(\n    denoOptions,\n    [\"--allow-read\"],\n  );\n});\n\nDeno.test(\"deno_options only defined in script\", () => {\n  const script = { deno_options: { \"allow-read\": true }, file: \"\" };\n  const global = {};\n  const denoOptions = parseDenoOptions(global, script);\n\n  assertEquals(\n    denoOptions,\n    [\"--allow-read\"],\n  );\n});\n\nDeno.test(\"deno_options only defined in script and globals\", () => {\n  const script = { deno_options: { \"allow-read\": true }, file: \"\" };\n  const global = { deno_options: { \"allow-write\": true } };\n  const denoOptions = parseDenoOptions(global, script);\n\n  assertEquals(\n    denoOptions,\n    [\"--allow-write\", \"--allow-read\"],\n  );\n});\n\nDeno.test(\"deno_options script overwrite globals one\", () => {\n  const script = { deno_options: { \"allow-read\": false }, file: \"\" };\n  const global = { deno_options: { \"allow-read\": true } };\n  const denoOptions = parseDenoOptions(global, script);\n\n  assertEquals(\n    denoOptions,\n    [],\n  );\n});\n\nDeno.test(\"validation error get thrown\", () => {\n  const script = { deno_options: { \"allow-read\": false }, file: \"\" };\n  const global = { deno_options: { \"allow-hrtime\": \"string\" } };\n\n  assertThrows(() => {\n    parseDenoOptions(global, script);\n  }, DenoOptionIncorrectType);\n});\n"
  },
  {
    "path": "src/deno_options/__tests__/utils.test.ts",
    "content": "import { assertEquals } from \"../../../dev_deps.ts\";\nimport { getOptionType } from \"../utils.ts\";\n\nDeno.test(\"string[]\", () => {\n  const optionType = getOptionType([\"first\", \"second\"]);\n\n  assertEquals(\n    optionType,\n    \"string[]\",\n  );\n});\n\nDeno.test(\"string[] with numbers\", () => {\n  const optionType = getOptionType([\"first\", 2]);\n\n  assertEquals(\n    optionType,\n    \"string[]\",\n  );\n});\n\nDeno.test(\"mixed[]\", () => {\n  const optionType = getOptionType([\"first\", { \"test\": \"string\" }]);\n\n  assertEquals(\n    optionType,\n    \"mixed[]\",\n  );\n});\n\nDeno.test(\"object\", () => {\n  const optionType = getOptionType({ \"test\": \"string\" });\n\n  assertEquals(\n    optionType,\n    \"object\",\n  );\n});\n\nDeno.test(\"string\", () => {\n  const optionType = getOptionType(\"string\");\n\n  assertEquals(\n    optionType,\n    \"string\",\n  );\n});\n\nDeno.test(\"number\", () => {\n  const optionType = getOptionType(1);\n\n  assertEquals(\n    optionType,\n    \"number\",\n  );\n});\n\nDeno.test(\"boolean\", () => {\n  const optionType = getOptionType(true);\n\n  assertEquals(\n    optionType,\n    \"boolean\",\n  );\n});\n"
  },
  {
    "path": "src/deno_options/__tests__/validate.test.ts",
    "content": "import { assertThrows } from \"../../../dev_deps.ts\";\nimport { validateOptions } from \"../validate.ts\";\nimport {\n  DenoOptionNotRecognized,\n  DenoOptionIncorrectType,\n} from \"../../utils/DenoXErrors.ts\";\n\nDeno.test(\"invalid option name error get thrown\", () => {\n  const options = { \"invalid-option\": false };\n\n  assertThrows(() => {\n    validateOptions(options);\n  }, DenoOptionNotRecognized);\n});\n\nDeno.test(\"invalid option value error get thrown\", () => {\n  const options = { \"allow-hrtime\": \"string\" };\n\n  assertThrows(() => {\n    validateOptions(options);\n  }, DenoOptionIncorrectType);\n});\n\nDeno.test(\"not throw for valid values\", () => {\n  const options = {\n    \"allow-hrtime\": true,\n    \"allow-read\": \".\",\n    \"allow-write\": true,\n    \"allow-net\": [\"google.com\", \"github.com\"],\n  };\n  validateOptions(options);\n});\n"
  },
  {
    "path": "src/deno_options/build_cli_arguments.ts",
    "content": "import { DenoOptionsEntries, DenoOptionValue } from \"../interfaces.ts\";\nimport { getOptionType, OptionTypeValues } from \"./utils.ts\";\nimport { optionsDefinitions } from \"./const.ts\";\n\ntype CLIArgument = string | number | [string, number];\ntype hashCliArgType = { name: string; value: string | boolean | number };\n\nfunction buildDenoCLIOptionsArgs(\n  denoOptions: DenoOptionsEntries,\n): CLIArgument[] {\n  const argumentsOptions: CLIArgument[] = [];\n\n  for (const [option, value] of Object.entries(denoOptions)) {\n    const argumentOption = _transformToCLIArguments(option, value);\n    argumentsOptions.push(argumentOption);\n  }\n\n  return argumentsOptions.filter((e) => e).flat(Infinity);\n}\n\nfunction _hashToCLIArg(\n  hash: hashCliArgType,\n): CLIArgument {\n  if (hash.value === false) {\n    return \"\";\n  }\n\n  const cliArgOptionName = `--${hash.name}`;\n  const cliArgOptionDefinition = optionsDefinitions[hash.name];\n\n  if (cliArgOptionDefinition.type === \"number\") {\n    return [cliArgOptionName, hash.value as number];\n  }\n\n  if (hash.value === true) {\n    return cliArgOptionName;\n  }\n\n  return `${cliArgOptionName}${cliArgOptionDefinition.spacer}${hash.value}`;\n}\n\nfunction _transformToCLIArguments(\n  option: string,\n  value: DenoOptionValue,\n): CLIArgument {\n  const optionType = getOptionType(value);\n  const optionDefinitionType = optionsDefinitions[option].type.split(\"|\");\n\n  if (!optionDefinitionType.includes(optionType)) {\n    throw new Error(\n      `Deno option \"${option}\" value is incorrect, options supports string, array of strings and boolean.`,\n    );\n  }\n\n  const argHash = _transformToArgHash(option, value, optionType);\n\n  return _hashToCLIArg(argHash);\n}\n\nfunction _transformToArgHash(\n  option: string,\n  value: DenoOptionValue,\n  optionType: OptionTypeValues,\n): hashCliArgType {\n  const argValue = optionType === \"string[]\"\n    ? (value as string[]).join(\",\")\n    : value as string | number | boolean;\n\n  return {\n    name: option,\n    value: argValue,\n  };\n}\n\nexport { buildDenoCLIOptionsArgs };\n\nexport type { CLIArgument };\n"
  },
  {
    "path": "src/deno_options/const.ts",
    "content": "type OptionsDefinitionsType = {\n  [key: string]: { type: string; spacer?: string };\n};\n\nconst optionsDefinitions: OptionsDefinitionsType = {\n  \"allow-all\": { type: \"boolean\" },\n  \"allow-env\": { type: \"boolean\" },\n  \"allow-hrtime\": { type: \"boolean\" },\n  \"allow-net\": { type: \"string|boolean|string[]\", spacer: \"=\" },\n  \"allow-plugin\": { type: \"boolean\" },\n  \"allow-read\": { type: \"string|boolean|string[]\", spacer: \"=\" },\n  \"allow-run\": { type: \"boolean\" },\n  \"allow-write\": { type: \"string|boolean|string[]\", spacer: \"=\" },\n  \"cached-only\": { type: \"boolean\" },\n  \"cert\": { type: \"string\", spacer: \"=\" },\n  \"config\": { type: \"string\", spacer: \"=\" },\n  \"importmap\": { type: \"string\", spacer: \"=\" },\n  \"inspect\": { type: \"string\", spacer: \"=\" },\n  \"inspect-brk\": { type: \"string\", spacer: \"=\" },\n  \"lock\": { type: \"string\", spacer: \"=\" },\n  \"lock-write\": { type: \"boolean\" },\n  \"log-level\": { type: \"string\", spacer: \"=\" },\n  \"no-remote\": { type: \"boolean\" },\n  \"quiet\": { type: \"boolean\" },\n  \"reload\": { type: \"string|boolean|string[]\", spacer: \"=\" },\n  \"seed\": { type: \"number\", spacer: \" \" },\n  \"unstable\": { type: \"boolean\" },\n  \"v8-flags\": { type: \"string|string[]\", spacer: \"=\" },\n};\n\nexport { optionsDefinitions };\n"
  },
  {
    "path": "src/deno_options/parse.ts",
    "content": "import { validateOptions } from \"./validate.ts\";\nimport { buildDenoCLIOptionsArgs, CLIArgument } from \"./build_cli_arguments.ts\";\nimport { WorkspaceGlobal, WorkspaceScript } from \"../interfaces.ts\";\n\nfunction parseDenoOptions(\n  workspaceGlobal: WorkspaceGlobal,\n  workspaceScript: WorkspaceScript,\n): CLIArgument[] {\n  const denoGlobalOptions = workspaceGlobal?.deno_options;\n  const denoScriptOptions = workspaceScript?.deno_options;\n\n  const options = {\n    ...denoGlobalOptions,\n    ...denoScriptOptions,\n  };\n\n  validateOptions(options);\n\n  return buildDenoCLIOptionsArgs(options);\n}\n\nexport { parseDenoOptions };\n"
  },
  {
    "path": "src/deno_options/utils.ts",
    "content": "import { DenoOptionValue } from \"../interfaces.ts\";\n\ntype TypeOfValues =\n  | \"string\"\n  | \"number\"\n  | \"bigint\"\n  | \"boolean\"\n  | \"symbol\"\n  | \"undefined\"\n  | \"object\"\n  | \"function\";\ntype OptionTypeValues = TypeOfValues | \"string[]\" | \"mixed[]\";\n\nfunction getOptionType(value: DenoOptionValue): OptionTypeValues {\n  if (Array.isArray(value)) {\n    if (_isStringNumberArray(value)) {\n      return \"string[]\";\n    }\n\n    return \"mixed[]\";\n  }\n\n  return typeof value;\n}\n\nfunction _isStringNumberArray(value: unknown[]): boolean {\n  return value.reduce((accumulator: boolean, currentValue) => {\n    return accumulator && _typeoffNumberAsString(currentValue) === \"string\";\n  }, true);\n}\n\nfunction _typeoffNumberAsString(value: unknown): TypeOfValues {\n  if (typeof value === \"number\") {\n    return \"string\";\n  }\n\n  return typeof value;\n}\n\nexport { getOptionType };\n\nexport type { OptionTypeValues };\n"
  },
  {
    "path": "src/deno_options/validate.ts",
    "content": "import { optionsDefinitions } from \"./const.ts\";\nimport {\n  DenoOptionNotRecognized,\n  DenoOptionIncorrectType,\n} from \"../utils/DenoXErrors.ts\";\nimport { getOptionType } from \"./utils.ts\";\nimport { DenoOptionsEntries } from \"../interfaces.ts\";\n\nfunction validateOptions(options: DenoOptionsEntries): void {\n  for (const [optionName, optionValue] of Object.entries(options)) {\n    _isOptionValid(optionName);\n    _isOptionTypeValid(optionName, optionValue);\n  }\n}\n\nfunction _isOptionValid(optionName: string): void {\n  if (optionsDefinitions.hasOwnProperty(optionName) === false) {\n    throw new DenoOptionNotRecognized(optionName);\n  }\n}\n\nfunction _isOptionTypeValid(optionName: string, optionValue: unknown): void {\n  const optionType = getOptionType(optionValue);\n\n  const optionDefinition = optionsDefinitions[optionName];\n  const optionDefinitionAllowedTypes = optionDefinition.type.split(\"|\");\n\n  if (optionDefinitionAllowedTypes.includes(optionType) === false) {\n    throw new DenoOptionIncorrectType(\n      optionName,\n      optionDefinition.type,\n      optionType,\n    );\n  }\n}\nexport { validateOptions };\n"
  },
  {
    "path": "src/interfaces.ts",
    "content": "type DenoOptionValue = unknown;\n\ntype DenoOptionsEntries = {\n  [key: string]: DenoOptionValue;\n};\n\ntype WorkspaceOptions = {\n  deno_options?: DenoOptionsEntries;\n};\n\ntype WorkspaceScript = {\n  file: string;\n} & WorkspaceOptions;\n\ntype WorkspaceGlobal = WorkspaceOptions;\n\ntype DenoWorkspace = {\n  scripts: {\n    [key: string]: WorkspaceScript;\n  };\n  globals?: WorkspaceGlobal;\n};\n\nexport type {\n  DenoWorkspace,\n  WorkspaceGlobal,\n  WorkspaceScript,\n  WorkspaceOptions,\n  DenoOptionsEntries,\n  DenoOptionValue,\n};\n"
  },
  {
    "path": "src/lib/semver.ts",
    "content": "/* eslint-disable */\nconst regex =\n  /^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\nexport function semver(version: string): Semver | undefined {\n  try {\n    return new Semver(version);\n  } catch {\n    return;\n  }\n}\n\nexport class Semver {\n  version: string;\n  major: number;\n  minor: number;\n  patch: number;\n  prerelease?: string;\n  buildmetadata?: string;\n\n  constructor(version: string) {\n    const m = version.match(regex);\n    if (m === null) {\n      throw new Error(\"Not valid semver\");\n    }\n    const [_, major, minor, patch, prerelease, buildmetadata] = m!;\n    this.version = version;\n    this.major = parseInt(major)!;\n    this.minor = parseInt(minor)!;\n    this.patch = parseInt(patch)!;\n    this.prerelease = prerelease;\n    this.buildmetadata = buildmetadata;\n  }\n\n  caret(other: Semver): boolean {\n    return this.major === other.major;\n  }\n\n  eq(other: Semver): boolean {\n    return this.version == other.version;\n  }\n\n  lt(other: Semver): boolean {\n    if (this.major < other.major) return true;\n    if (this.major > other.major) return false;\n\n    if (this.minor < other.minor) return true;\n    if (this.minor > other.minor) return false;\n\n    if (this.patch < other.patch) return true;\n    if (this.patch > other.patch) return false;\n\n    // This is clearly wrong...\n    if (this.prerelease === undefined) return false;\n    if (other.prerelease === undefined) return false;\n    if (this.prerelease < other.prerelease) return true;\n    if (this.prerelease > other.prerelease) return false;\n\n    if (this.buildmetadata === undefined) return false;\n    if (other.buildmetadata === undefined) return false;\n    if (this.buildmetadata < other.buildmetadata) return true;\n    if (this.buildmetadata > other.buildmetadata) return false;\n\n    return false;\n  }\n\n  tilde(other: Semver): boolean {\n    if (this.major !== other.major) return false;\n    if (this.major === 0 && other.major === 0) return true;\n\n    if (this.minor === other.minor) return true;\n    // we're not supporting prerelease and buildmetadata?\n    return false;\n  }\n\n  _(token: string, other: Semver): boolean {\n    switch (token) {\n      case \"~\":\n        return this.tilde(other);\n      case \"^\":\n        return this.caret(other);\n      case \"<\":\n        return this.lt(other);\n      // the rest of these are superfluous...\n      case \"<=\":\n        return this.eq(other) || this.lt(other);\n      case \">\":\n        return !(this.eq(other) || this.lt(other));\n      case \">=\":\n        return !this.lt(other);\n      case \"=\":\n        return this.eq(other);\n      default:\n        throw new Error(`modifier token not recognized: ${token}`);\n    }\n  }\n}\n\nexport function fragment(\n  url: string,\n  version: string,\n):\n  | ((other: Semver) => boolean)\n  | undefined {\n  const tokens = /^(~|\\^|<|<=|>|>=|=)\\s*(.*?)$/;\n  const f = url.split(\"#\")[1];\n  if (f === undefined) return;\n  const m = f.trim().match(tokens);\n  if (m === null) throw new SyntaxError(`invalid semver fragment: ${f}`);\n  const [_, t, v] = m;\n  try {\n    const s = new Semver(v || version);\n    // we have to reverse this due to the way fragments work...\n    return (other: Semver) => other._(t, s);\n  } catch (e) {\n    throw new SyntaxError(`invalid semver version: ${v || version}`);\n  }\n}\n"
  },
  {
    "path": "src/lib/upgrade_version.ts",
    "content": "import { Semver } from \"./semver.ts\";\n\nasync function getLatestVersion(repoName: string): Promise<string> {\n  const response = await fetch(`https://api.github.com/repos/${repoName}/tags`);\n  const data = await response.json();\n  return data[0].name;\n}\n\nfunction isCurrentLatestVersion(\n  currentVersion: string,\n  latestVersion: string,\n): boolean {\n  return new Semver(currentVersion)._(\">=\", new Semver(latestVersion));\n}\n\nasync function upgradeVersionMessage(\n  currentVersion: string,\n  repoName: string,\n): Promise<void> {\n  try {\n    const latestVersion = await getLatestVersion(repoName);\n\n    if (!isCurrentLatestVersion(currentVersion, latestVersion)) {\n      console.log(`\n        denox update available from ${currentVersion} to ${latestVersion}\n        To upgrade run deno install -Af -n denox https://denopkg.com/BentoumiTech/denox/denox.ts\n      `);\n    }\n  } catch (error) {\n    // continue regardless of error\n  }\n}\n\nexport { upgradeVersionMessage };\n"
  },
  {
    "path": "src/parser/__tests__/deno_workspace.test.ts",
    "content": "import {\n  assertEquals,\n  assertThrowsAsync,\n} from \"../../../dev_deps.ts\";\nimport { loadDenoWorkspace } from \"../deno_workspace.ts\";\nimport {\n  WorkspaceNotFoundError,\n  WorkspaceFileIsMalformed,\n} from \"../../utils/DenoXErrors.ts\";\nimport { changeAndRestoreCWD } from \"../../../test/utils/cwd.ts\";\n\nDeno.test(\"throw WorkspaceNotFoundError when workspace file doesn't exist\", async () => {\n  await changeAndRestoreCWD(\"test/fixture/no_workspace\", async () => {\n    await assertThrowsAsync(async () => {\n      await loadDenoWorkspace();\n    }, WorkspaceNotFoundError);\n  });\n});\n\nDeno.test(\"throw WorkspaceMalformed when yaml workspace file is not valid\", async () => {\n  await changeAndRestoreCWD(\"test/fixture/malformed_yaml\", async () => {\n    await assertThrowsAsync(async () => {\n      await loadDenoWorkspace();\n    }, WorkspaceFileIsMalformed);\n  });\n});\n\nDeno.test(\"throw WorkspaceMalformed when json workspace file is not valid\", async () => {\n  await changeAndRestoreCWD(\"test/fixture/malformed_json\", async () => {\n    await assertThrowsAsync(async () => {\n      await loadDenoWorkspace();\n    }, WorkspaceFileIsMalformed);\n  });\n});\n\nDeno.test(\"throw WorkspaceMalformed when ts workspace file is not valid\", async () => {\n  await changeAndRestoreCWD(\"test/fixture/malformed_ts\", async () => {\n    await assertThrowsAsync(async () => {\n      await loadDenoWorkspace();\n    }, WorkspaceFileIsMalformed);\n  });\n});\n\nDeno.test(\"load valid workspaces with correct order of priority\", async () => {\n  const files = [\n    \"deno-workspace.yml\",\n    \"deno-workspace\",\n    \"deno-workspace.yaml\",\n    \".deno-workspace\",\n    \".deno-workspace.yml\",\n    \".deno-workspace.yaml\",\n    \"deno-workspace.json\",\n    \".deno-workspace.json\",\n    \"deno-workspace.ts\",\n    \".deno-workspace.ts\",\n  ];\n\n  for (const file of files) {\n    await changeAndRestoreCWD(\n      `test/fixture/workspace_multiple_names/${file}`,\n      async () => {\n        assertEquals(await loadDenoWorkspace(), {\n          scripts: {\n            start: { file: `${file}.ts`, deno_options: { reload: true } },\n          },\n          globals: { deno_options: { \"allow-read\": [\"./files\"] } },\n        });\n      },\n    );\n  }\n});\n"
  },
  {
    "path": "src/parser/deno_workspace.ts",
    "content": "import { parseYaml, YAMLError, extname } from \"../../deps.ts\";\n\nimport { DENO_WORKSPACE_FILES } from \"../const.ts\";\nimport { DenoWorkspace } from \"../interfaces.ts\";\n\nimport { getFirstExistingPath, getFileContent } from \"../utils/file.ts\";\nimport {\n  WorkspaceNotFoundError,\n  WorkspaceFileIsMalformed,\n} from \"../utils/DenoXErrors.ts\";\n\nasync function loadDenoWorkspace(): Promise<DenoWorkspace> {\n  try {\n    const denoWorkspaceFilePath = await getFirstExistingPath(\n      DENO_WORKSPACE_FILES,\n    );\n\n    if (extname(denoWorkspaceFilePath) === \".ts\") {\n      return await _loadTSWorkspace(\"file:///\" + denoWorkspaceFilePath);\n    }\n\n    return await _loadYAMLWorkspace(denoWorkspaceFilePath) as DenoWorkspace;\n  } catch (e) {\n    throw _handleLoadDenoWorkspaceErrors(e);\n  }\n}\n\nasync function _loadTSWorkspace(\n  denoWorkspaceFilePath: string,\n): Promise<DenoWorkspace> {\n  const { workspace } = await import(denoWorkspaceFilePath) as {\n    workspace: DenoWorkspace;\n  };\n  return workspace;\n}\n\nasync function _loadYAMLWorkspace(\n  denoWorkspaceFilePath: string,\n): Promise<DenoWorkspace> {\n  const denoWorkspaceFileContent = await getFileContent(\n    denoWorkspaceFilePath,\n  );\n  return parseYaml(denoWorkspaceFileContent) as DenoWorkspace;\n}\n\nfunction _handleLoadDenoWorkspaceErrors(e: unknown): Error {\n  if (e instanceof Deno.errors.NotFound) {\n    return new WorkspaceNotFoundError();\n  }\n\n  if (\n    e instanceof YAMLError || e instanceof ReferenceError ||\n    e instanceof TypeError\n  ) {\n    return new WorkspaceFileIsMalformed(e.message);\n  }\n\n  return e as Error;\n}\n\nexport { loadDenoWorkspace };\n"
  },
  {
    "path": "src/run.ts",
    "content": "import { CURRENT_VERSION, GITHUB_REPO_NAME } from \"./const.ts\";\n\nimport * as consolex from \"./utils/consolex.ts\";\nimport { ScriptNotFoundError } from \"./utils/DenoXErrors.ts\";\n\nimport { upgradeVersionMessage } from \"./lib/upgrade_version.ts\";\n\nimport { loadDenoWorkspace } from \"./parser/deno_workspace.ts\";\nimport { parseDenoOptions } from \"./deno_options/parse.ts\";\nimport { CLIArgument } from \"./deno_options/build_cli_arguments.ts\";\nimport { WorkspaceOptions, WorkspaceScript } from \"./interfaces.ts\";\n\nasync function run(scriptName: string): Promise<void> {\n  try {\n    const args = Deno.args.slice(2);\n    const { code } = await _runScript(scriptName, args);\n\n    await upgradeVersionMessage(CURRENT_VERSION, GITHUB_REPO_NAME);\n\n    Deno.exit(code);\n  } catch (e) {\n    if (e instanceof Deno.errors.PermissionDenied) {\n      consolex.error(`\n        Please reinstall denox with the correct permissions\n        deno install -Af -n denox https://denopkg.com/BentoumiTech/denox/denox.ts\n      `);\n    } else {\n      consolex.error(e.message);\n    }\n  }\n}\n\nasync function _runScript(\n  scriptName: string,\n  args: string[],\n): Promise<{ code: number }> {\n  const workspace = await loadDenoWorkspace();\n\n  const workspaceScript = workspace.scripts[scriptName];\n  const workspaceGlobal = workspace?.globals || {};\n\n  if (workspaceScript === undefined) {\n    throw new ScriptNotFoundError(scriptName);\n  }\n\n  return await _runDenoFile(workspaceScript, workspaceGlobal, args);\n}\n\nasync function _runDenoFile(\n  workspaceScript: WorkspaceScript,\n  workspaceGlobal: WorkspaceOptions,\n  args: string[],\n): Promise<{ code: number }> {\n  const denoOptions = await _getDenoOptions(workspaceScript, workspaceGlobal);\n  const process = Deno.run({\n    // ToDO: remove '@ts-ignore' (and eslint directive) when vscode_deno is fixed to work with @deno_types; ref: <https://github.com/cacjs/cac/issues/75> , <https://github.com/denoland/vscode_deno/issues/21>\n    /* eslint @typescript-eslint/ban-ts-comment: \"off\" */\n    // deno-lint-ignore ban-ts-comment\n    // @ts-ignore\n    cmd: [\n      \"deno\",\n      \"run\",\n      ...denoOptions,\n      workspaceScript.file,\n      ...args,\n    ],\n  });\n  const { code } = await process.status();\n\n  return { code };\n}\n\nasync function _getDenoOptions(\n  workspaceScript: WorkspaceScript,\n  workspaceGlobal: WorkspaceOptions,\n): Promise<CLIArgument[]> {\n  return parseDenoOptions(\n    workspaceGlobal,\n    workspaceScript,\n  );\n}\n\nexport default run;\n"
  },
  {
    "path": "src/utils/DenoXErrors.ts",
    "content": "class DenoXError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = this.constructor.name;\n  }\n}\n\nclass WorkspaceNotFoundError extends DenoXError {\n  constructor() {\n    super(`\n      deno-workspace file not found in \"${Deno.cwd()}\"\n      Run \"denox init\" in your project root directory.\n    `);\n  }\n}\n\nclass ScriptNotFoundError extends DenoXError {\n  constructor(script: string) {\n    super(\n      `Script \"${script}\" not found please add it to your deno-workspace file`,\n    );\n  }\n}\n\nclass WorkspaceFileIsMalformed extends DenoXError {\n  constructor(parserMessage: string) {\n    super(`\n      deno-workspace file is not valid\n\n      ${parserMessage}\n    `);\n  }\n}\n\nclass DenoOptionNotRecognized extends DenoXError {\n  constructor(option: string) {\n    super(`\n      The option: \"${option}\" in deno-workspace file is not valid.\n      For a list of valid options enter \"deno run --help\"\n    `);\n  }\n}\n\nclass DenoOptionIncorrectType extends DenoXError {\n  constructor(\n    optionName: string,\n    optionDefinitionType: string,\n    optionType: string,\n  ) {\n    super(`\n      The option: \"${optionName}\" in deno-workspace type is not valid.\n      Currently it's \"${optionType}\" but only \"${optionDefinitionType}\" is/are valid\n    `);\n  }\n}\n\nexport {\n  ScriptNotFoundError,\n  WorkspaceNotFoundError,\n  WorkspaceFileIsMalformed,\n  DenoOptionNotRecognized,\n  DenoOptionIncorrectType,\n};\n"
  },
  {
    "path": "src/utils/__tests__/file.test.ts",
    "content": "import {\n  assertEquals,\n  assertThrowsAsync,\n  resolve,\n  assertStrContains,\n} from \"../../../dev_deps.ts\";\nimport { getFileContent, getFirstExistingPath, exists } from \"../file.ts\";\n\nDeno.test(\"read file\", async () => {\n  const fileContent = await getFileContent(\n    \"./src/utils/__tests__/fixture/file.txt\",\n  );\n\n  assertStrContains(\n    fileContent,\n    \"test file content\",\n  );\n});\n\nDeno.test(\"throw error if file doesn't exist\", async () => {\n  await assertThrowsAsync(async () => {\n    await getFileContent(\"./src/utils/__tests__/fixture/no-found.txt\");\n  }, Deno.errors.NotFound);\n});\n\nDeno.test(\"return first existing path\", async () => {\n  const firstExistingPath = await getFirstExistingPath([\n    \"./src/utils/__tests__/fixture/list-files/first.txt\",\n    \"./src/utils/__tests__/fixture/list-files/second.txt\",\n    \"./src/utils/__tests__/fixture/list-files/third.txt\",\n  ]);\n\n  assertEquals(\n    firstExistingPath,\n    resolve(\"./src/utils/__tests__/fixture/list-files/second.txt\"),\n  );\n});\n\nDeno.test(\"throw error if no file in list exist\", async () => {\n  await assertThrowsAsync(async () => {\n    await getFirstExistingPath([\n      \"./src/utils/__tests__/fixture/list-files/fourth.txt\",\n      \"./src/utils/__tests__/fixture/list-files/fifth.txt\",\n      \"./src/utils/__tests__/fixture/list-files/sixth.txt\",\n    ]);\n  }, Deno.errors.NotFound);\n});\n\nDeno.test(\"return true if file exist\", async () => {\n  const fileExist = await exists(\"./src/utils/__tests__/fixture/file.txt\");\n\n  assertEquals(\n    fileExist,\n    true,\n  );\n});\n\nDeno.test(\"return false if file is not found\", async () => {\n  const fileExist = await exists(\n    \"./src/utils/__tests__/fixture/file-not-found.txt\",\n  );\n\n  assertEquals(\n    fileExist,\n    false,\n  );\n});\n"
  },
  {
    "path": "src/utils/__tests__/fixture/file.txt",
    "content": "test file content\n"
  },
  {
    "path": "src/utils/__tests__/fixture/list-files/second.txt",
    "content": ""
  },
  {
    "path": "src/utils/__tests__/fixture/list-files/third.txt",
    "content": ""
  },
  {
    "path": "src/utils/consolex.ts",
    "content": "import { red } from \"../../deps.ts\";\n\nfunction error(msg: string): void {\n  console.error(`${red(\"error\")} ${msg}`);\n  Deno.exit(1);\n}\n\nexport { error };\n"
  },
  {
    "path": "src/utils/file.ts",
    "content": "import { resolve } from \"../../deps.ts\";\n\nasync function getFileContent(\n  filePath: string,\n): Promise<string> {\n  const fileBytes = await Deno.readFile(filePath);\n  const decoder = new TextDecoder(\"utf-8\");\n  return decoder.decode(fileBytes);\n}\n\nasync function getFirstExistingPath(\n  files: string[],\n): Promise<string> {\n  const [firstFile, ...restFiles] = files;\n  const firstFileFullPath = resolve(firstFile);\n  const isfirstFileFullPathExist = await exists(firstFileFullPath);\n\n  if (isfirstFileFullPathExist) {\n    return firstFileFullPath;\n  }\n\n  if (restFiles.length > 0) {\n    return await getFirstExistingPath(restFiles);\n  }\n\n  throw new Deno.errors.NotFound();\n}\n\nasync function exists(filename: string): Promise<boolean> {\n  try {\n    await Deno.stat(filename);\n    return true;\n  } catch (error) {\n    if (error instanceof Deno.errors.NotFound) {\n      return false;\n    }\n\n    throw error;\n  }\n}\n\nexport { getFirstExistingPath, getFileContent, exists };\n"
  },
  {
    "path": "test/e2e/args.test.ts",
    "content": "import { testDenoXRun } from \"../utils/denox-run.ts\";\nimport { assertEquals } from \"../../dev_deps.ts\";\n\nDeno.test(\"Args are passed to the denox script\", async () => {\n  const args = {\n    parsed: {\n      _: [\"first\", \"second\", \"third\"],\n      s: \"value\",\n      full: \"value\",\n      \"--\": [\"--test=arg\", \"fourth\", \"fifth\"],\n    },\n    \"raw\": [\n      \"first\",\n      \"second\",\n      \"third\",\n      \"-s=value\",\n      \"--full=value\",\n      \"--\",\n      \"--test=arg\",\n      \"fourth\",\n      \"fifth\",\n    ],\n  };\n\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/args\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      assertEquals(JSON.parse(output), args);\n    },\n    \"first second third -s=value --full=value -- --test=arg fourth fifth\".split(\n      \" \",\n    ),\n  );\n});\n"
  },
  {
    "path": "test/e2e/deno_options/options.test.ts",
    "content": "import {\n  assertEquals,\n  assertStrContains,\n  resolve,\n  stripColor,\n  join,\n} from \"../../../dev_deps.ts\";\nimport { testDenoXRun } from \"../../utils/denox-run.ts\";\nimport { exists } from \"../../../src/utils/file.ts\";\n\nDeno.test(\"permissions are applied\", async () => {\n  await testDenoXRun(\n    \"permissions\",\n    \"test/fixture/deno_options\",\n    async ({ output, code }) => {\n      assertEquals(code, 0);\n\n      output = stripColor(output);\n      assertStrContains(\n        output,\n        'allow-env: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-hrtime: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-net: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-plugin: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-read: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-run: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-write: PermissionStatus { state: \"granted\" }',\n      );\n    },\n  );\n});\n\nDeno.test(\"allow-all permissions are applied\", async () => {\n  await testDenoXRun(\n    \"all-permissions\",\n    \"test/fixture/deno_options\",\n    async ({ output, code }) => {\n      assertEquals(code, 0);\n\n      output = stripColor(output);\n      assertStrContains(\n        output,\n        'allow-env: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-hrtime: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-net: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-plugin: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-read: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-run: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-write: PermissionStatus { state: \"granted\" }',\n      );\n    },\n  );\n});\n\nDeno.test(\"false permissions are applied\", async () => {\n  await testDenoXRun(\n    \"false-permissions\",\n    \"test/fixture/deno_options\",\n    async ({ output, code }) => {\n      assertEquals(code, 0);\n\n      output = stripColor(output);\n      assertStrContains(\n        output,\n        'allow-env: PermissionStatus { state: \"prompt\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-hrtime: PermissionStatus { state: \"prompt\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-net: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-plugin: PermissionStatus { state: \"prompt\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-read: PermissionStatus { state: \"granted\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-run: PermissionStatus { state: \"prompt\" }',\n      );\n      assertStrContains(\n        output,\n        'allow-write: PermissionStatus { state: \"granted\" }',\n      );\n    },\n  );\n});\n\nDeno.test(\"seed option is applied\", async () => {\n  await testDenoXRun(\n    \"seed\",\n    \"test/fixture/deno_options\",\n    async ({ output, code }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"seed: 0.147205063401058\");\n    },\n  );\n});\n\nDeno.test(\"quiet option is applied\", async () => {\n  await testDenoXRun(\n    \"quiet\",\n    \"test/fixture/deno_options\",\n    async ({ output, code }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"Only console.log\\n\");\n    },\n  );\n});\n\nDeno.test(\"lock option is applied\", async () => {\n  await testDenoXRun(\"lock\", \"test/fixture/deno_options\", async ({ code }) => {\n    const lockFilePath = resolve(\"../../fixture/deno_options/files/lock.json\");\n    const isLockFilePresent = await exists(lockFilePath);\n\n    assertEquals(code, 0);\n    assertEquals(isLockFilePresent, true);\n\n    await Deno.remove(lockFilePath);\n  });\n});\n\nDeno.test(\"log-level option is applied\", async () => {\n  await testDenoXRun(\n    \"log-level\",\n    \"test/fixture/deno_options\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"DEBUG JS\");\n    },\n  );\n});\n\nDeno.test(\"config option is applied\", async () => {\n  await testDenoXRun(\n    \"config\",\n    \"test/fixture/deno_options\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"tsconfig.json\");\n    },\n  );\n});\n\nDeno.test(\"import map option is applied\", async () => {\n  await testDenoXRun(\n    \"import-map\",\n    \"test/fixture/deno_options\",\n    async ({ code, errOutput }) => {\n      assertEquals(code, 0);\n      errOutput = stripColor(errOutput);\n      assertStrContains(\n        errOutput,\n        'ModuleSpecifier(\"https://deno.land/std/http/\"',\n      );\n    },\n  );\n});\n\nDeno.test(\"v8-flags, cached-only, cert, no-remote, reload options do not crash\", async () => {\n  await testDenoXRun(\n    \"rest-options\",\n    \"test/fixture/deno_options\",\n    async ({ code }) => {\n      assertEquals(code, 0);\n    },\n  );\n});\n"
  },
  {
    "path": "test/e2e/deno_options/scoped_global.test.ts",
    "content": "import {\n  assertEquals,\n  assertStrContains,\n  stripColor,\n} from \"../../../dev_deps.ts\";\nimport { testDenoXRun } from \"../../utils/denox-run.ts\";\n\nDeno.test(\"run script with scoped options\", async () => {\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/script_permission\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"I'm text file content\");\n    },\n  );\n});\n\nDeno.test(\"run script with global options\", async () => {\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/global_permission\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"I'm text file content\");\n    },\n  );\n});\n\nDeno.test(\"run script with scoped and global options\", async () => {\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/script_global_permission\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      output = stripColor(output);\n      assertStrContains(output, \"I'm text file content\");\n      assertStrContains(output, \"seed: 0.147205063401058\");\n    },\n  );\n});\n\nDeno.test(\"run script with erroneous merged scoped and global options\", async () => {\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/merged_scoped_global__invalid_permission\",\n    async ({ code, errOutput }) => {\n      assertEquals(code, 1);\n      errOutput = stripColor(errOutput);\n      assertStrContains(\n        errOutput,\n        'Uncaught PermissionDenied: network access to \"https://jsonplaceho',\n      );\n    },\n  );\n});\n"
  },
  {
    "path": "test/e2e/scripts.test.ts",
    "content": "import { assertEquals, assertStrContains } from \"../../dev_deps.ts\";\nimport { testDenoXRun } from \"../utils/denox-run.ts\";\n\nDeno.test(\"Return an error when script doesn't exist\", async () => {\n  await testDenoXRun(\n    \"not-found-script\",\n    \"test/fixture/single_script\",\n    async ({ code, errOutput }) => {\n      assertEquals(code, 1);\n      assertStrContains(errOutput, '\"not-found-script\" not found');\n    },\n  );\n});\n\nDeno.test(\"execute existing script\", async () => {\n  await testDenoXRun(\n    \"start\",\n    \"test/fixture/single_script\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      assertStrContains(output, \"Hello World!\");\n    },\n  );\n});\n\nDeno.test(\"execute existing script when multiple are specified\", async () => {\n  await testDenoXRun(\n    \"develop\",\n    \"test/fixture/multiple_scripts\",\n    async ({ code, output }) => {\n      assertEquals(code, 0);\n      assertStrContains(output, \"Hello World Develop!\");\n    },\n  );\n});\n"
  },
  {
    "path": "test/fixture/args/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"main.ts\",\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/args/main.ts",
    "content": "import { parse } from \"https://deno.land/std/flags/mod.ts\";\n\nconsole.log(JSON.stringify({\n  parsed: parse(Deno.args, { \"--\": true }),\n  raw: Deno.args,\n}));\n"
  },
  {
    "path": "test/fixture/deno_options/deno-workspace.yml",
    "content": "scripts:\n  permissions:\n    file: permissions.ts\n    deno_options:\n      allow-env: true\n      allow-hrtime: true\n      allow-net: google.com\n      allow-plugin: true\n      allow-read: ./files\n      allow-run: true\n      allow-write: ./files\n      unstable: true\n  all-permissions:\n    file: permissions.ts\n    deno_options:\n      allow-all: true\n      unstable: true\n  false-permissions:\n    file: permissions.ts\n    deno_options:\n      allow-env: false\n      allow-hrtime: false\n      allow-net: google.com\n      allow-plugin: false\n      allow-read: ./files\n      allow-run: false\n      allow-write: ./files\n      unstable: true\n  seed:\n    file: seed.ts\n    deno_options:\n      seed: 1\n  quiet:\n    file: quiet.ts\n    deno_options:\n      log-level: debug\n      quiet: true\n  lock:\n    file: main.ts\n    deno_options:\n      lock: ./files/lock.json\n      lock-write: true\n  log-level:\n    file: main.ts\n    deno_options:\n      log-level: debug\n  config:\n    file: main.ts\n    deno_options:\n      config: ./files/tsconfig.json\n      log-level: debug\n  import-map:\n    file: main.ts\n    deno_options:\n      importmap: files/import_map.json\n      log-level: debug\n      unstable: true\n  rest-options:\n    file: main.ts\n    deno_options:\n      v8-flags:\n        - --regexp-tier-up\n        - --adjust-os-scheduling-parameters true\n      cached-only: true\n      cert: ./files/test.cer\n      no-remote: true\n      reload: true\n\n"
  },
  {
    "path": "test/fixture/deno_options/files/import_map.json",
    "content": "{\n  \"imports\": {\n     \"http/\": \"https://deno.land/std/http/\"\n  }\n}\n"
  },
  {
    "path": "test/fixture/deno_options/files/test.cer",
    "content": ""
  },
  {
    "path": "test/fixture/deno_options/files/test.txt",
    "content": ""
  },
  {
    "path": "test/fixture/deno_options/files/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n"
  },
  {
    "path": "test/fixture/deno_options/main.ts",
    "content": ""
  },
  {
    "path": "test/fixture/deno_options/permissions.ts",
    "content": "console.log(\"allow-env:\", await Deno.permissions.query({ name: \"env\" }));\nconsole.log(\"allow-hrtime:\", await Deno.permissions.query({ name: \"hrtime\" }));\nconsole.log(\n  \"allow-net:\",\n  await Deno.permissions.query({ name: \"net\", url: \"https://google.com\" }),\n);\nconsole.log(\"allow-plugin:\", await Deno.permissions.query({ name: \"plugin\" }));\nconsole.log(\n  \"allow-read:\",\n  await Deno.permissions.query({ name: \"read\", path: \"./files\" }),\n);\nconsole.log(\"allow-run:\", await Deno.permissions.query({ name: \"run\" }));\nconsole.log(\n  \"allow-write:\",\n  await Deno.permissions.query({ name: \"write\", path: \"./files\" }),\n);\n"
  },
  {
    "path": "test/fixture/deno_options/quiet.ts",
    "content": "console.log(\"Only console.log\");\n"
  },
  {
    "path": "test/fixture/deno_options/seed.ts",
    "content": "console.log(\"seed:\", Math.random());\n"
  },
  {
    "path": "test/fixture/global_permission/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\nglobals:\n  deno_options:\n    allow-read:\n      - './files'\n"
  },
  {
    "path": "test/fixture/global_permission/files/test.txt",
    "content": "I'm text file content\n"
  },
  {
    "path": "test/fixture/global_permission/main.ts",
    "content": "const data = Deno.readFileSync(\"./files/test.txt\");\nconst decoder = new TextDecoder(\"utf-8\");\n\nconsole.log(decoder.decode(data));\n"
  },
  {
    "path": "test/fixture/malformed_json/deno-workspace.json",
    "content": "{\n  test,\n\n"
  },
  {
    "path": "test/fixture/malformed_ts/deno-workspace.ts",
    "content": "malformedts;\n"
  },
  {
    "path": "test/fixture/malformed_yaml/deno-workspace",
    "content": "maleformed/yaml: invalid:\n"
  },
  {
    "path": "test/fixture/merged_scoped_global__invalid_permission/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\n    deno_options:\n      allow-net: false\nglobals:\n  deno_options:\n    allow-read:\n      - './files'\n    allow-net: jsonplaceholder.typicode.com\n"
  },
  {
    "path": "test/fixture/merged_scoped_global__invalid_permission/files/test.txt",
    "content": "I'm text file content\n"
  },
  {
    "path": "test/fixture/merged_scoped_global__invalid_permission/main.ts",
    "content": "const data = Deno.readFileSync(\"./files/test.txt\");\nconst decoder = new TextDecoder(\"utf-8\");\n\nconsole.log(decoder.decode(data));\n\nconst response = await fetch(\"https://jsonplaceholder.typicode.com/todos/1\");\nconst json = await response.json();\nconsole.log(json);\n"
  },
  {
    "path": "test/fixture/multiple_scripts/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\n  develop:\n    file: develop.ts\n\n"
  },
  {
    "path": "test/fixture/multiple_scripts/develop.ts",
    "content": "console.log(\"Hello World Develop!\");\n"
  },
  {
    "path": "test/fixture/multiple_scripts/main.ts",
    "content": "console.log(\"Hello World!\");\n"
  },
  {
    "path": "test/fixture/no_workspace/.keep",
    "content": ""
  },
  {
    "path": "test/fixture/script_global_permission/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\n    deno_options:\n      seed: 1\nglobals:\n  deno_options:\n    allow-read:\n      - './files'\n"
  },
  {
    "path": "test/fixture/script_global_permission/files/test.txt",
    "content": "I'm text file content\n"
  },
  {
    "path": "test/fixture/script_global_permission/main.ts",
    "content": "const data = Deno.readFileSync(\"./files/test.txt\");\nconst decoder = new TextDecoder(\"utf-8\");\n\nconsole.log(decoder.decode(data));\n\nconsole.log(\"seed:\", Math.random());\n"
  },
  {
    "path": "test/fixture/script_permission/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\n    deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/script_permission/files/test.txt",
    "content": "I'm text file content\n"
  },
  {
    "path": "test/fixture/script_permission/main.ts",
    "content": "const data = Deno.readFileSync(\"./files/test.txt\");\nconst decoder = new TextDecoder(\"utf-8\");\n\nconsole.log(decoder.decode(data));\n"
  },
  {
    "path": "test/fixture/single_script/deno-workspace",
    "content": "scripts:\n  start:\n    file: main.ts\n\n"
  },
  {
    "path": "test/fixture/single_script/main.ts",
    "content": "console.log(\"Hello World!\");\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/.deno-workspace",
    "content": "scripts:\n  start:\n    file: .deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/.deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.json/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.json/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.json/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.ts/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yaml/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yaml/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yaml/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yaml/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yaml/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/.deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/.deno-workspace.yml/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/.deno-workspace",
    "content": "scripts:\n  start:\n    file: .deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/.deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/deno-workspace",
    "content": "scripts:\n  start:\n    file: deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace/deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.json/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.json/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.json/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.json/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.ts/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.ts/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/.deno-workspace",
    "content": "scripts:\n  start:\n    file: .deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/.deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yaml/deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/.deno-workspace",
    "content": "scripts:\n  start:\n    file: .deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/.deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \".deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/.deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \".deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/.deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/.deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: .deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/deno-workspace",
    "content": "scripts:\n  start:\n    file: deno-workspace.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/deno-workspace.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"start\": {\n\t\t\t\"file\": \"deno-workspace.json.ts\",\n\t\t\t\"deno_options\": {\n\t\t\t\t\"reload\": true\n\t\t\t}\n\t\t}\n\t},\n\t\"globals\": {\n\t\t\"deno_options\": {\n\t\t\t\"allow-read\": [\n\t\t\t\t\"./files\"\n\t\t\t]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/deno-workspace.ts",
    "content": "import { DenoWorkspace } from \"../../../../src/interfaces.ts\";\n\nconst workspace: DenoWorkspace = {\n  \"scripts\": {\n    \"start\": {\n      \"file\": \"deno-workspace.ts.ts\",\n      \"deno_options\": {\n        \"reload\": true,\n      },\n    },\n  },\n  \"globals\": {\n    \"deno_options\": {\n      \"allow-read\": [\n        \"./files\",\n      ],\n    },\n  },\n};\n\nexport { workspace };\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/deno-workspace.yaml",
    "content": "scripts:\n  start:\n    file: deno-workspace.yaml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/fixture/workspace_multiple_names/deno-workspace.yml/deno-workspace.yml",
    "content": "scripts:\n  start:\n    file: deno-workspace.yml.ts\n    deno_options:\n      reload: true\nglobals:\n  deno_options:\n      allow-read:\n        - './files'\n"
  },
  {
    "path": "test/utils/cwd.ts",
    "content": "import {\n  resolve,\n} from \"../../dev_deps.ts\";\n\nasync function changeAndRestoreCWD(\n  directory: string,\n  assertion: (denoxPath: string) => Promise<void>,\n): Promise<void> {\n  const cwd = Deno.cwd();\n  const denoxPath = resolve(\"./denox.ts\");\n  Deno.chdir(resolve(directory));\n\n  await assertion(denoxPath);\n\n  Deno.chdir(cwd);\n}\n\nexport { changeAndRestoreCWD };\n"
  },
  {
    "path": "test/utils/denox-run.ts",
    "content": "import { changeAndRestoreCWD } from \"./cwd.ts\";\n\ntype ProcessOutputs = { output: string; errOutput: string };\n\n// eslint-disable-next-line max-params\nasync function testDenoXRun(\n  scriptName: string,\n  workspaceFolder: string,\n  assertRunOutput: (\n    denoxOutput: { output: string; errOutput: string; code: number },\n  ) => Promise<void>,\n  args: string[] = [],\n): Promise<void> {\n  await changeAndRestoreCWD(\n    workspaceFolder,\n    async (denoxPath) => {\n      const process = _denoXRun(denoxPath, scriptName, args);\n      const { output, errOutput } = await _getProcessOutputs(process);\n      const { code } = await process.status();\n      process.close();\n\n      await assertRunOutput({ output, errOutput, code });\n    },\n  );\n}\n\nfunction _denoXRun(\n  denoxPath: string,\n  scriptName: string,\n  args: string[],\n): Deno.Process {\n  return Deno.run({\n    cmd: [\n      \"deno\",\n      \"run\",\n      \"-A\",\n      denoxPath,\n      \"run\",\n      scriptName,\n      ...args,\n    ],\n    stdout: \"piped\",\n    stderr: \"piped\",\n  });\n}\n\nasync function _getProcessOutputs(\n  process: Deno.Process,\n): Promise<ProcessOutputs> {\n  const outputBuffer = await process.output();\n  const errOutputBuffer = await process.stderrOutput();\n\n  const output = new TextDecoder().decode(outputBuffer);\n  const errOutput = new TextDecoder().decode(errOutputBuffer);\n\n  return { output, errOutput };\n}\n\nexport { testDenoXRun };\n"
  }
]