├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── extensions.json ├── project.code-workspace └── settings.json ├── LICENSE ├── README.md ├── deno.json ├── package-lock.json ├── package.json ├── packages ├── sham-weakref │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.test.ts │ │ └── index.ts │ └── tsconfig.json ├── shim-crypto │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── scripts │ │ └── generateCryptoTypes.ts │ ├── src │ │ ├── crypto.types.gen.ts │ │ └── index.ts │ └── tsconfig.json ├── shim-deno-test │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── scripts │ │ └── generateDenoTypes.ts │ ├── src │ │ ├── definitions.ts │ │ ├── deno.types.gen.d.ts │ │ ├── deno.types.gen.ts │ │ ├── index.ts │ │ └── test.ts │ └── tsconfig.json ├── shim-deno │ ├── LICENSE │ ├── PROGRESS.md │ ├── README.md │ ├── lib │ │ └── shim-deno.lib.d.ts │ ├── package.json │ ├── src │ │ ├── deno │ │ │ ├── internal │ │ │ │ ├── Conn.ts │ │ │ │ ├── Listener.ts │ │ │ │ ├── consts.ts │ │ │ │ ├── errorMap.ts │ │ │ │ ├── fs_flags.ts │ │ │ │ ├── iterutil.ts │ │ │ │ ├── random_id.ts │ │ │ │ ├── streams.test.ts │ │ │ │ ├── streams.ts │ │ │ │ └── version.ts │ │ │ └── stable │ │ │ │ ├── classes.ts │ │ │ │ ├── classes │ │ │ │ ├── FsFile.ts │ │ │ │ ├── PermissionStatus.ts │ │ │ │ └── Permissions.ts │ │ │ │ ├── enums.ts │ │ │ │ ├── enums │ │ │ │ └── SeekMode.ts │ │ │ │ ├── functions.ts │ │ │ │ ├── functions │ │ │ │ ├── addSignalListener.ts │ │ │ │ ├── chdir.ts │ │ │ │ ├── chmod.ts │ │ │ │ ├── chmodSync.ts │ │ │ │ ├── chown.ts │ │ │ │ ├── chownSync.ts │ │ │ │ ├── close.ts │ │ │ │ ├── connect.ts │ │ │ │ ├── connectTls.ts │ │ │ │ ├── consoleSize.ts │ │ │ │ ├── copy.ts │ │ │ │ ├── copyFile.ts │ │ │ │ ├── copyFileSync.ts │ │ │ │ ├── create.ts │ │ │ │ ├── createSync.ts │ │ │ │ ├── cwd.ts │ │ │ │ ├── execPath.ts │ │ │ │ ├── exit.ts │ │ │ │ ├── fdatasync.ts │ │ │ │ ├── fdatasyncSync.ts │ │ │ │ ├── fstat.ts │ │ │ │ ├── fstatSync.ts │ │ │ │ ├── fsync.ts │ │ │ │ ├── fsyncSync.ts │ │ │ │ ├── ftruncate.ts │ │ │ │ ├── ftruncateSync.ts │ │ │ │ ├── gid.ts │ │ │ │ ├── hostname.ts │ │ │ │ ├── inspect.ts │ │ │ │ ├── kill.ts │ │ │ │ ├── link.ts │ │ │ │ ├── linkSync.ts │ │ │ │ ├── listen.ts │ │ │ │ ├── listenTls.ts │ │ │ │ ├── loadavg.ts │ │ │ │ ├── lstat.ts │ │ │ │ ├── lstatSync.ts │ │ │ │ ├── makeTempDir.ts │ │ │ │ ├── makeTempDirSync.ts │ │ │ │ ├── makeTempFile.ts │ │ │ │ ├── makeTempFileSync.ts │ │ │ │ ├── memoryUsage.ts │ │ │ │ ├── mkdir.ts │ │ │ │ ├── mkdirSync.ts │ │ │ │ ├── open.test.ts │ │ │ │ ├── open.ts │ │ │ │ ├── openSync.ts │ │ │ │ ├── osRelease.ts │ │ │ │ ├── osUptime.ts │ │ │ │ ├── read.ts │ │ │ │ ├── readDir.ts │ │ │ │ ├── readDirSync.ts │ │ │ │ ├── readFile.ts │ │ │ │ ├── readFileSync.ts │ │ │ │ ├── readLink.ts │ │ │ │ ├── readLinkSync.ts │ │ │ │ ├── readSync.ts │ │ │ │ ├── readTextFile.ts │ │ │ │ ├── readTextFileSync.ts │ │ │ │ ├── realPath.ts │ │ │ │ ├── realPathSync.ts │ │ │ │ ├── remove.ts │ │ │ │ ├── removeSignalListener.ts │ │ │ │ ├── removeSync.ts │ │ │ │ ├── rename.ts │ │ │ │ ├── renameSync.ts │ │ │ │ ├── resolveDns.test.ts │ │ │ │ ├── resolveDns.ts │ │ │ │ ├── run.test.ts │ │ │ │ ├── run.ts │ │ │ │ ├── shutdown.ts │ │ │ │ ├── stat.ts │ │ │ │ ├── statSync.ts │ │ │ │ ├── symlink.ts │ │ │ │ ├── symlinkSync.ts │ │ │ │ ├── test.ts │ │ │ │ ├── truncate.ts │ │ │ │ ├── truncateSync.ts │ │ │ │ ├── uid.ts │ │ │ │ ├── watchFs.ts │ │ │ │ ├── write.ts │ │ │ │ ├── writeFile.ts │ │ │ │ ├── writeFileSync.ts │ │ │ │ ├── writeSync.ts │ │ │ │ ├── writeTextFile.ts │ │ │ │ └── writeTextFileSync.ts │ │ │ │ ├── main.ts │ │ │ │ ├── types.js │ │ │ │ ├── types.ts │ │ │ │ ├── variables.ts │ │ │ │ └── variables │ │ │ │ ├── args.ts │ │ │ │ ├── build.ts │ │ │ │ ├── customInspect.ts │ │ │ │ ├── env.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── mainModule.test.ts │ │ │ │ ├── mainModule.ts │ │ │ │ ├── metrics.ts │ │ │ │ ├── noColor.ts │ │ │ │ ├── permissions.ts │ │ │ │ ├── pid.ts │ │ │ │ ├── ppid.ts │ │ │ │ ├── resources.ts │ │ │ │ ├── std.ts │ │ │ │ └── version.ts │ │ ├── index.ts │ │ ├── package.json │ │ └── test-internals.ts │ ├── third_party │ │ └── package.json │ ├── tools │ │ ├── bundle.ts │ │ ├── deno_version.ts │ │ ├── denolib.ts │ │ ├── generateDeclarationFile.ts │ │ ├── missing.ts │ │ ├── run_tests.mjs │ │ ├── untested.sh │ │ └── working_test_files.txt │ ├── tsconfig.esm.json │ └── tsconfig.json ├── shim-prompts │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── readlineSync.ts │ └── tsconfig.json └── shim-timers │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── index.test.ts │ └── index.ts │ └── tsconfig.json └── scripts ├── extract_types_from_symbol.ts ├── helpers.ts ├── mod.ts └── ts_morph.ts /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # [Choice] Debian OS version: bullseye, buster 2 | ARG VARIANT=bullseye 3 | FROM --platform=linux/amd64 mcr.microsoft.com/devcontainers/base:0-${VARIANT} 4 | 5 | ENV DENO_INSTALL=/deno 6 | RUN mkdir -p /deno \ 7 | && curl -fsSL https://deno.land/x/install/install.sh | sh \ 8 | && chown -R vscode /deno 9 | 10 | ENV PATH=${DENO_INSTALL}/bin:${PATH} \ 11 | DENO_DIR=${DENO_INSTALL}/.cache/deno 12 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Deno", 3 | "build": { 4 | "dockerfile": "Dockerfile" 5 | }, 6 | 7 | // Configure tool-specific properties. 8 | "customizations": { 9 | // Configure properties specific to VS Code. 10 | "vscode": { 11 | // Set *default* container specific settings.json values on container create. 12 | "settings": { 13 | // Enables the project as a Deno project 14 | "deno.enable": true, 15 | // Enables Deno linting for the project 16 | "deno.lint": true, 17 | // Sets Deno as the default formatter for the project 18 | "editor.defaultFormatter": "denoland.vscode-deno" 19 | }, 20 | 21 | // Add the IDs of extensions you want installed when the container is created. 22 | "extensions": [ 23 | "denoland.vscode-deno" 24 | ] 25 | } 26 | }, 27 | 28 | "remoteUser": "vscode", 29 | "features": { 30 | "ghcr.io/devcontainers/features/node:1": {} 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | insert_final_newline = true 4 | trim_trailing_whitespace = true 5 | indent_style = space 6 | indent_size = 2 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | packages/shim-deno/lib/shim-deno.lib.d.ts linguist-generated=true 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | branches: [main] 5 | push: 6 | branches: [main] 7 | tags: 8 | - '*' 9 | jobs: 10 | test: 11 | runs-on: ${{ matrix.os }} 12 | timeout-minutes: 10 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | os: [macos-latest, ubuntu-latest, windows-latest] 17 | steps: 18 | - run: git config --global core.autocrlf false 19 | - uses: actions/checkout@v3 20 | with: 21 | submodules: true 22 | - run: (cd packages/shim-deno/third_party/deno; git submodule update --init --depth=1 test_util/std) 23 | shell: bash 24 | - uses: actions/setup-node@v2 25 | with: 26 | node-version: '18' 27 | registry-url: 'https://registry.npmjs.org' 28 | - uses: denoland/setup-deno@v1 29 | with: 30 | deno-version: 1.40.2 31 | - run: deno lint 32 | if: matrix.os == 'ubuntu-latest' 33 | - run: deno fmt --check 34 | if: matrix.os == 'ubuntu-latest' 35 | - run: npm -v 36 | - run: npm ci --ignore-scripts 37 | - run: npm run --silent build --workspaces 38 | - run: npm run --silent test --workspaces 39 | - name: Try running on Node 16 40 | run: cd packages/shim-deno && npx node@16 dist/index.cjs && npx node@16 dist/index.mjs 41 | if: matrix.os == 'ubuntu-latest' 42 | - run: cd packages/shim-deno && tools/untested.sh 43 | if: matrix.os == 'ubuntu-latest' 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib.deno.d.ts 4 | lib.deno.unstable.d.ts 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "packages/shim-deno/third_party/deno"] 2 | path = packages/shim-deno/third_party/deno 3 | url = https://github.com/denoland/deno 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "denoland.vscode-deno" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/project.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "name": "ROOT", 5 | "path": "../" 6 | }, 7 | { 8 | "name": "sham-weakref", 9 | "path": "../packages/sham-weakref" 10 | }, 11 | { 12 | "name": "shim-crypto", 13 | "path": "../packages/shim-crypto" 14 | }, 15 | { 16 | "name": "shim-deno", 17 | "path": "../packages/shim-deno/src/" 18 | }, 19 | { 20 | "name": "shim-deno-test", 21 | "path": "../packages/shim-deno-test/src/" 22 | }, 23 | { 24 | "name": "shim-deno-tools", 25 | "path": "../packages/shim-deno/tools" 26 | }, 27 | { 28 | "name": "third_party", 29 | "path": "../packages/shim-deno/third_party" 30 | }, 31 | { 32 | "name": "shim-timers", 33 | "path": "../packages/shim-timers" 34 | } 35 | ], 36 | "settings": { 37 | "files.exclude": { 38 | "**/.git": true, 39 | "**/.svn": true, 40 | "**/.hg": true, 41 | "**/CVS": true, 42 | "**/.DS_Store": true, 43 | "packages/shim-deno/src/": true, 44 | "packages/shim-deno/tools/": true, 45 | "packages/shim-deno/third_party/": true 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.lint": true, 3 | "deno.unstable": true, 4 | "deno.enablePaths": [ 5 | "./scripts", 6 | "./packages/shim-crypto/scripts", 7 | "./packages/shim-deno/tools", 8 | "./packages/shim-deno-test/scripts" 9 | ], 10 | "editor.defaultFormatter": "denoland.vscode-deno", 11 | "editor.formatOnSave": true 12 | } 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node_deno_shims 2 | 3 | Deno shims for Node.js 4 | 5 | ## Packages 6 | 7 | - [@deno/shim-deno](packages/shim-deno) - Deno namespace shim. 8 | - [@deno/shim-deno-test](packages/shim-deno-test) - `Deno.test` only shim. 9 | - [@deno/shim-crypto](packages/shim-crypto) - Shim for the `crypto` global. 10 | - [@deno/shim-prompts](packages/shim-prompts) - Shims for `alert`, `confirm` and 11 | `prompt`. 12 | - [@deno/shim-timers](packages/shim-timers) - Shims for `setTimeout` and 13 | `setInterval`. 14 | - [@deno/sham-weakref](packages/sham-weakref) - Sham for the `WeakRef` global 15 | that uses the global `WeakRef` if it exists. 16 | 17 | ## Contributing 18 | 19 | Commands: 20 | 21 | ```sh 22 | # get submodules if you did not clone them initially 23 | git submodule init --recursive 24 | git submodule update --recursive 25 | # npm install 26 | npm i --ignore-scripts 27 | # build all packages 28 | npm run build --workspaces 29 | # test all packages 30 | npm run test --workspaces 31 | # format 32 | deno fmt 33 | # lint 34 | deno lint 35 | ``` 36 | 37 | For package specific development commands, see the package.json scripts in each 38 | package. 39 | -------------------------------------------------------------------------------- /deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "lock": false, 3 | "lint": { 4 | "exclude": [ 5 | "node_modules", 6 | "dist", 7 | "packages/sham-weakref/dist", 8 | "packages/sham-weakref/node_modules", 9 | "packages/shim-crypto/dist", 10 | "packages/shim-crypto/node_modules", 11 | "packages/shim-deno/dist", 12 | "packages/shim-deno/node_modules", 13 | "packages/shim-deno/src/deno/stable/lib.deno.d.ts", 14 | "packages/shim-deno/src/deno/unstable/lib.deno.unstable.d.ts", 15 | "packages/shim-deno/lib", 16 | "packages/shim-deno/third_party", 17 | "packages/shim-deno-test/dist", 18 | "packages/shim-deno-test/node_modules", 19 | "packages/shim-prompts/dist", 20 | "packages/shim-prompts/node_modules", 21 | "packages/shim-timers/dist", 22 | "packages/shim-timers/node_modules" 23 | ], 24 | "rules": { 25 | "exclude": ["no-explicit-any"] 26 | } 27 | }, 28 | "fmt": { 29 | "exclude": [ 30 | "node_modules", 31 | "dist", 32 | "packages/sham-weakref/dist", 33 | "packages/sham-weakref/node_modules", 34 | "packages/shim-crypto/dist", 35 | "packages/shim-crypto/node_modules", 36 | "packages/shim-deno/dist", 37 | "packages/shim-deno/node_modules", 38 | "packages/shim-deno/src/deno/stable/lib.deno.d.ts", 39 | "packages/shim-deno/src/deno/unstable/lib.deno.unstable.d.ts", 40 | "packages/shim-deno/lib", 41 | "packages/shim-deno/third_party", 42 | "packages/shim-deno-test/dist", 43 | "packages/shim-deno-test/node_modules", 44 | "packages/shim-prompts/dist", 45 | "packages/shim-prompts/node_modules", 46 | "packages/shim-timers/dist", 47 | "packages/shim-timers/node_modules" 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node_deno_shimsworkspace", 3 | "workspaces": [ 4 | "packages/sham-weakref", 5 | "packages/shim-crypto", 6 | "packages/shim-deno-test", 7 | "packages/shim-deno", 8 | "packages/shim-prompts", 9 | "packages/shim-timers" 10 | ], 11 | "scripts": { 12 | "lint": "deno lint", 13 | "fmt": "deno fmt" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/sham-weakref/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/sham-weakref/README.md: -------------------------------------------------------------------------------- 1 | # @deno/sham-weakref 2 | 3 | Sham for `WeakRef`. It is not possible to shim `WeakRef` in old node 4 | environments, so this module provides a sham to allow the code to compile, but 5 | it will throw when used. The sham will use the global `WeakRef` if it exists 6 | though. 7 | -------------------------------------------------------------------------------- /packages/sham-weakref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/sham-weakref", 3 | "version": "0.1.0", 4 | "description": "WeakRef sham that uses the global WeakRef if it exists.", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "tsc", 9 | "test": "ts-node --project tsconfig.json src/index.test.ts" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/denoland/node_deno_shims.git" 17 | }, 18 | "keywords": [ 19 | "shim", 20 | "deno", 21 | "node.js", 22 | "timers" 23 | ], 24 | "author": "The Deno authors", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/denoland/node_deno_shims/issues" 28 | }, 29 | "homepage": "https://github.com/denoland/node_deno_shims#readme", 30 | "devDependencies": { 31 | "typescript": "^5.2.2", 32 | "ts-node": "^10.9.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/sham-weakref/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { WeakRef } from "./index"; 2 | import * as assert from "assert/strict"; 3 | 4 | if (globalThis.WeakRef != null) { 5 | console.log("should store a value in the WeakRef..."); 6 | const value = new WeakRef({ value: 5 }); 7 | assert.equal(value.deref().value, 5); 8 | } else { 9 | console.log("should throw when getting a value from the WeakRef..."); 10 | const value = new WeakRef({ value: 5 }); 11 | assert.throws(() => value.deref().value); 12 | } 13 | -------------------------------------------------------------------------------- /packages/sham-weakref/src/index.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore-file 2 | 3 | // https://github.com/microsoft/TypeScript/blob/main/src/lib/es2021.weakref.d.ts 4 | export interface WeakRef { 5 | readonly [Symbol.toStringTag]: "WeakRef"; 6 | 7 | /** 8 | * Returns the WeakRef instance's target object, or undefined if the target object has been 9 | * reclaimed. 10 | */ 11 | deref(): T | undefined; 12 | } 13 | 14 | export interface WeakRefConstructor { 15 | readonly prototype: WeakRef; 16 | 17 | /** 18 | * Creates a WeakRef instance for the given target object. 19 | * @param target The target object for the WeakRef instance. 20 | */ 21 | new (target: T): WeakRef; 22 | } 23 | 24 | export const WeakRef: WeakRefConstructor = (globalThis as any).WeakRef ?? 25 | class WeakRef { 26 | readonly [Symbol.toStringTag] = "WeakRef"; 27 | 28 | constructor(_target: T) { 29 | } 30 | 31 | deref(): T | undefined { 32 | throw new Error("WeakRef is not supported in Node 14 and below."); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /packages/sham-weakref/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2019", 6 | "lib": ["ES2019"], 7 | "declaration": true, 8 | "outDir": "dist", 9 | "stripInternal": true 10 | }, 11 | "ts-node": { 12 | "transpileOnly": true, 13 | "files": true 14 | }, 15 | "files": ["src/index.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/shim-crypto/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/shim-crypto/README.md: -------------------------------------------------------------------------------- 1 | # @deno/shim-crypto 2 | 3 | Node shim for the web's `crypto` global. 4 | -------------------------------------------------------------------------------- /packages/shim-crypto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/shim-crypto", 3 | "version": "0.3.1", 4 | "description": "Node shim for the web's `crypto` global.", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "npm run generate-crypto-types && tsc", 9 | "generate-crypto-types": "deno run --allow-read --allow-write ./scripts/generateCryptoTypes.ts", 10 | "test": "echo \"None at the moment\"" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/denoland/node_deno_shims.git" 18 | }, 19 | "keywords": [ 20 | "shim", 21 | "deno", 22 | "node.js", 23 | "crypto" 24 | ], 25 | "author": "The Deno authors", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/denoland/node_deno_shims/issues" 29 | }, 30 | "homepage": "https://github.com/denoland/node_deno_shims#readme", 31 | "devDependencies": { 32 | "typescript": "^5.2.2", 33 | "ts-node": "^10.9.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/shim-crypto/scripts/generateCryptoTypes.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { extractTypesFromSymbol } from "../../../scripts/extract_types_from_symbol.ts"; 4 | import { 5 | IndentationText, 6 | Project, 7 | StatementStructures, 8 | } from "../../../scripts/ts_morph.ts"; 9 | 10 | /// Analyzes lib.dom.d.ts and extracts out all the types used by the `Crypto` interface. 11 | const project = new Project({ 12 | manipulationSettings: { 13 | indentationText: IndentationText.TwoSpaces, 14 | }, 15 | }); 16 | const domDtsFile = project.addSourceFileAtPath( 17 | "../shim-deno/third_party/deno/cli/tsc/dts/lib.dom.d.ts", 18 | ); 19 | const statements: (StatementStructures | string)[] = []; 20 | statements.push("// deno-lint-ignore-file"); 21 | statements.push("// deno-fmt-ignore-file"); 22 | statements.push( 23 | "// DO NOT EDIT - This file is automatically maintained by `npm run generate-crypto-types`", 24 | ); 25 | 26 | const crypto = domDtsFile.getInterfaceOrThrow("Crypto"); 27 | 28 | statements.push(...extractTypesFromSymbol({ 29 | symbol: crypto.getSymbolOrThrow(), 30 | isContainedDeclaration: (node) => node.getSourceFile() === domDtsFile, 31 | })); 32 | 33 | project.createSourceFile( 34 | "./src/crypto.types.gen.ts", 35 | { statements }, 36 | { overwrite: true }, 37 | ).saveSync(); 38 | -------------------------------------------------------------------------------- /packages/shim-crypto/src/crypto.types.gen.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore-file 2 | // deno-fmt-ignore-file 3 | // DO NOT EDIT - This file is automatically maintained by `npm run generate-crypto-types` 4 | 5 | /** 6 | * Basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives. 7 | * 8 | * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto) 9 | */ 10 | export interface Crypto { 11 | /** 12 | * Available only in secure contexts. 13 | * 14 | * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/subtle) 15 | */ 16 | readonly subtle: SubtleCrypto; 17 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ 18 | getRandomValues(array: T): T; 19 | /** 20 | * Available only in secure contexts. 21 | * 22 | * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) 23 | */ 24 | randomUUID(): `${string}-${string}-${string}-${string}-${string}`; 25 | } 26 | 27 | /** 28 | * This Web Crypto API interface provides a number of low-level cryptographic functions. It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto). 29 | * Available only in secure contexts. 30 | * 31 | * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto) 32 | */ 33 | export interface SubtleCrypto { 34 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/decrypt) */ 35 | decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise; 36 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveBits) */ 37 | deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length: number): Promise; 38 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */ 39 | deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise; 40 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest) */ 41 | digest(algorithm: AlgorithmIdentifier, data: BufferSource): Promise; 42 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/encrypt) */ 43 | encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise; 44 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/exportKey) */ 45 | exportKey(format: "jwk", key: CryptoKey): Promise; 46 | exportKey(format: Exclude, key: CryptoKey): Promise; 47 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */ 48 | generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray): Promise; 49 | generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray): Promise; 50 | generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise; 51 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */ 52 | importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray): Promise; 53 | importKey(format: Exclude, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise; 54 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/sign) */ 55 | sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise; 56 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */ 57 | unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise; 58 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/verify) */ 59 | verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise; 60 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/wrapKey) */ 61 | wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise; 62 | } 63 | 64 | export type AlgorithmIdentifier = Algorithm | string; 65 | 66 | export interface Algorithm { 67 | name: string; 68 | } 69 | 70 | export interface RsaOaepParams extends Algorithm { 71 | label?: BufferSource; 72 | } 73 | 74 | export type BufferSource = ArrayBufferView | ArrayBuffer; 75 | 76 | export interface AesCtrParams extends Algorithm { 77 | counter: BufferSource; 78 | length: number; 79 | } 80 | 81 | export interface AesCbcParams extends Algorithm { 82 | iv: BufferSource; 83 | } 84 | 85 | export interface AesGcmParams extends Algorithm { 86 | additionalData?: BufferSource; 87 | iv: BufferSource; 88 | tagLength?: number; 89 | } 90 | 91 | /** 92 | * The CryptoKey dictionary of the Web Crypto API represents a cryptographic key. 93 | * Available only in secure contexts. 94 | * 95 | * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey) 96 | */ 97 | export interface CryptoKey { 98 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/algorithm) */ 99 | readonly algorithm: KeyAlgorithm; 100 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/extractable) */ 101 | readonly extractable: boolean; 102 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/type) */ 103 | readonly type: KeyType; 104 | /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/usages) */ 105 | readonly usages: KeyUsage[]; 106 | } 107 | 108 | export interface KeyAlgorithm { 109 | name: string; 110 | } 111 | 112 | export type KeyType = "private" | "public" | "secret"; 113 | export type KeyUsage = "decrypt" | "deriveBits" | "deriveKey" | "encrypt" | "sign" | "unwrapKey" | "verify" | "wrapKey"; 114 | export declare var CryptoKey: { 115 | prototype: CryptoKey; 116 | new(): CryptoKey; 117 | }; 118 | 119 | export interface EcdhKeyDeriveParams extends Algorithm { 120 | public: CryptoKey; 121 | } 122 | 123 | export interface HkdfParams extends Algorithm { 124 | hash: HashAlgorithmIdentifier; 125 | info: BufferSource; 126 | salt: BufferSource; 127 | } 128 | 129 | export type HashAlgorithmIdentifier = AlgorithmIdentifier; 130 | 131 | export interface Pbkdf2Params extends Algorithm { 132 | hash: HashAlgorithmIdentifier; 133 | iterations: number; 134 | salt: BufferSource; 135 | } 136 | 137 | export interface AesDerivedKeyParams extends Algorithm { 138 | length: number; 139 | } 140 | 141 | export interface HmacImportParams extends Algorithm { 142 | hash: HashAlgorithmIdentifier; 143 | length?: number; 144 | } 145 | 146 | export interface JsonWebKey { 147 | alg?: string; 148 | crv?: string; 149 | d?: string; 150 | dp?: string; 151 | dq?: string; 152 | e?: string; 153 | ext?: boolean; 154 | k?: string; 155 | key_ops?: string[]; 156 | kty?: string; 157 | n?: string; 158 | oth?: RsaOtherPrimesInfo[]; 159 | p?: string; 160 | q?: string; 161 | qi?: string; 162 | use?: string; 163 | x?: string; 164 | y?: string; 165 | } 166 | 167 | export interface RsaOtherPrimesInfo { 168 | d?: string; 169 | r?: string; 170 | t?: string; 171 | } 172 | 173 | export type KeyFormat = "jwk" | "pkcs8" | "raw" | "spki"; 174 | 175 | export interface RsaHashedKeyGenParams extends RsaKeyGenParams { 176 | hash: HashAlgorithmIdentifier; 177 | } 178 | 179 | export interface RsaKeyGenParams extends Algorithm { 180 | modulusLength: number; 181 | publicExponent: BigInteger; 182 | } 183 | 184 | export type BigInteger = Uint8Array; 185 | 186 | export interface EcKeyGenParams extends Algorithm { 187 | namedCurve: NamedCurve; 188 | } 189 | 190 | export type NamedCurve = string; 191 | 192 | export interface CryptoKeyPair { 193 | privateKey: CryptoKey; 194 | publicKey: CryptoKey; 195 | } 196 | 197 | export interface AesKeyGenParams extends Algorithm { 198 | length: number; 199 | } 200 | 201 | export interface HmacKeyGenParams extends Algorithm { 202 | hash: HashAlgorithmIdentifier; 203 | length?: number; 204 | } 205 | 206 | export interface RsaHashedImportParams extends Algorithm { 207 | hash: HashAlgorithmIdentifier; 208 | } 209 | 210 | export interface EcKeyImportParams extends Algorithm { 211 | namedCurve: NamedCurve; 212 | } 213 | 214 | export interface AesKeyAlgorithm extends KeyAlgorithm { 215 | length: number; 216 | } 217 | 218 | export interface RsaPssParams extends Algorithm { 219 | saltLength: number; 220 | } 221 | 222 | export interface EcdsaParams extends Algorithm { 223 | hash: HashAlgorithmIdentifier; 224 | } 225 | 226 | export declare var SubtleCrypto: { 227 | prototype: SubtleCrypto; 228 | new(): SubtleCrypto; 229 | }; 230 | export declare var Crypto: { 231 | prototype: Crypto; 232 | new(): Crypto; 233 | }; 234 | -------------------------------------------------------------------------------- /packages/shim-crypto/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { webcrypto } from "crypto"; 4 | import type { Crypto } from "./crypto.types.gen.js"; 5 | 6 | // At the time of writing this, DefinitelyTyped is missing types for webcrypto for Node. 7 | // The workaround is to just use the types from lib.dom.ts and hope people are 8 | // running unit tests in order to find any issues. 9 | const crypto = webcrypto as unknown as Crypto; 10 | 11 | export { crypto }; 12 | export * from "./crypto.types.gen.js"; 13 | -------------------------------------------------------------------------------- /packages/shim-crypto/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2019", 6 | "lib": ["ES2019"], 7 | "declaration": true, 8 | "outDir": "dist", 9 | "stripInternal": true 10 | }, 11 | "ts-node": { 12 | "transpileOnly": true, 13 | "files": true 14 | }, 15 | "files": ["src/index.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/shim-deno-test/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/shim-deno-test/README.md: -------------------------------------------------------------------------------- 1 | # @deno/shim-deno-test 2 | 3 | Subset of [@deno/shim-deno](https://www.npmjs.com/package/@deno/shim-deno) for 4 | only `Deno.test`. 5 | 6 | ```ts 7 | import { Deno, test, testDefinitions } from "@deno/shim-deno-test"; 8 | 9 | Deno.test("some test", () => { 10 | // test here 11 | }); 12 | 13 | // or 14 | test("some other test", () => { 15 | // test here 16 | }); 17 | 18 | // read from testDefinitions here 19 | testDefinitions.length === 2; 20 | ``` 21 | 22 | ## Note - Not a Test Runner 23 | 24 | This shim is not a test runner. It simply collects tests into the 25 | `testDefinitions` array. The idea is that you run a module that does `Deno.test` 26 | calls and then you splice out the test definitions from `testDefinitions` (ex. 27 | `const definitions = testDefinitions.splice(0, testDefinitions.length)`) and 28 | provide those to a test runner. 29 | -------------------------------------------------------------------------------- /packages/shim-deno-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/shim-deno-test", 3 | "version": "0.5.0", 4 | "description": "Deno.test only shim.", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "npm run generate-deno-types && tsc", 9 | "generate-deno-types": "deno run --allow-read --allow-write=. ./scripts/generateDenoTypes.ts", 10 | "test": "echo 'tested by shim-deno package.'" 11 | }, 12 | "files": [ 13 | "dist" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/denoland/node_deno_shims.git" 18 | }, 19 | "keywords": [ 20 | "shim", 21 | "deno", 22 | "test", 23 | "node.js" 24 | ], 25 | "author": "The Deno authors", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/denoland/node_deno_shims/issues" 29 | }, 30 | "homepage": "https://github.com/denoland/node_deno_shims#readme", 31 | "devDependencies": { 32 | "typescript": "^5.2.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/shim-deno-test/scripts/generateDenoTypes.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { 4 | exitIfDiagnostics, 5 | extractTypesFromSymbol, 6 | tsMorph, 7 | } from "../../../scripts/mod.ts"; 8 | 9 | /// Analyzes lib.deno.ns.d.ts and extracts out all the types used by Deno.test 10 | const project = new tsMorph.Project({ 11 | manipulationSettings: { 12 | indentationText: tsMorph.IndentationText.TwoSpaces, 13 | }, 14 | }); 15 | const libDenoFile = project.addSourceFileAtPath( 16 | "../shim-deno/third_party/deno/cli/tsc/dts/lib.deno.ns.d.ts", 17 | ); 18 | const statements: (tsMorph.StatementStructures | string)[] = []; 19 | statements.push("// deno-lint-ignore-file"); 20 | statements.push("// deno-fmt-ignore-file"); 21 | statements.push( 22 | "// DO NOT EDIT - This file is automatically maintained by `npm run generate-deno-types`", 23 | ); 24 | statements.push(`import { URL } from "url";`); 25 | 26 | const denoNs = libDenoFile.getModuleOrThrow("Deno"); 27 | const testFunc = denoNs.getVariableDeclarationOrThrow("test"); 28 | 29 | statements.push(...extractTypesFromSymbol({ 30 | symbol: testFunc.getSymbolOrThrow(), 31 | isContainedDeclaration: (node) => { 32 | if (tsMorph.Node.isModuleDeclaration(node) && node.getName() === "Deno") { 33 | return false; 34 | } 35 | if (tsMorph.Node.isFunctionDeclaration(node) && node.getName() === "exit") { 36 | return false; 37 | } 38 | 39 | const inDeclFile = node.getSourceFile() === libDenoFile; 40 | return inDeclFile; 41 | }, 42 | })); 43 | 44 | for (const statement of statements) { 45 | if (tsMorph.Structure.isVariableStatement(statement)) { 46 | statement.hasDeclareKeyword = true; 47 | } 48 | } 49 | 50 | const outputFile = project.createSourceFile( 51 | "./src/deno.types.gen.d.ts", 52 | { statements }, 53 | { overwrite: true }, 54 | ); 55 | outputFile.saveSync(); 56 | 57 | exitIfDiagnostics( 58 | project, 59 | project.getPreEmitDiagnostics() 60 | .filter((d) => d.getSourceFile() === outputFile), 61 | ); 62 | -------------------------------------------------------------------------------- /packages/shim-deno-test/src/definitions.ts: -------------------------------------------------------------------------------- 1 | import type { TestDefinition } from "./deno.types.gen.js"; 2 | 3 | /** Reference to the array that `Deno.test` calls insert their definition into. */ 4 | export const testDefinitions: TestDefinition[] = []; 5 | -------------------------------------------------------------------------------- /packages/shim-deno-test/src/index.ts: -------------------------------------------------------------------------------- 1 | export * as Deno from "./test.js"; 2 | export * from "./test.js"; 3 | export { testDefinitions } from "./definitions.js"; 4 | -------------------------------------------------------------------------------- /packages/shim-deno-test/src/test.ts: -------------------------------------------------------------------------------- 1 | import { testDefinitions } from "./definitions.js"; 2 | import * as Deno from "./deno.types.gen.js"; 3 | 4 | export type { 5 | TestContext, 6 | TestDefinition, 7 | TestStepDefinition, 8 | } from "./deno.types.gen.js"; 9 | 10 | export const test: typeof Deno.test = Object.assign(function test() { 11 | handleDefinition(arguments); 12 | }, { 13 | ignore() { 14 | handleDefinition(arguments, { ignore: true }); 15 | }, 16 | only() { 17 | handleDefinition(arguments, { only: true }); 18 | }, 19 | }); 20 | 21 | function handleDefinition( 22 | args: IArguments, 23 | additional?: { ignore?: boolean; only?: boolean }, 24 | ) { 25 | let testDef: Deno.TestDefinition; 26 | const firstArg = args[0]; 27 | const secondArg = args[1]; 28 | const thirdArg = args[2]; 29 | 30 | if (typeof firstArg === "string") { 31 | if (typeof secondArg === "object") { 32 | if (typeof thirdArg === "function") { 33 | if (secondArg.fn != null) { 34 | throw new TypeError( 35 | "Unexpected 'fn' field in options, test function is already provided as the third argument.", 36 | ); 37 | } 38 | } 39 | if (secondArg.name != null) { 40 | throw new TypeError( 41 | "Unexpected 'name' field in options, test name is already provided as the first argument.", 42 | ); 43 | } 44 | // name, options, fn 45 | testDef = { name: firstArg, fn: thirdArg, ...secondArg }; 46 | } else { 47 | // name, fn 48 | testDef = { name: firstArg, fn: secondArg }; 49 | } 50 | } else if (firstArg instanceof Function) { 51 | // function only 52 | if (firstArg.name.length === 0) { 53 | throw new TypeError("The test function must have a name"); 54 | } 55 | testDef = { fn: firstArg, name: firstArg.name }; 56 | 57 | if (secondArg != null) { 58 | throw new TypeError("Unexpected second argument to Deno.test()"); 59 | } 60 | } else if (typeof firstArg === "object") { 61 | testDef = { ...firstArg }; 62 | if (typeof secondArg === "function") { 63 | // options, fn 64 | testDef.fn = secondArg; 65 | if (firstArg.fn != null) { 66 | throw new TypeError( 67 | "Unexpected 'fn' field in options, test function is already provided as the second argument.", 68 | ); 69 | } 70 | if (testDef.name == null) { 71 | if (secondArg.name.length === 0) { 72 | throw new TypeError("The test function must have a name"); 73 | } 74 | // options without name, fn 75 | testDef.name = secondArg.name; 76 | } 77 | } else { 78 | if (typeof firstArg.fn !== "function") { 79 | throw new TypeError( 80 | "Expected 'fn' field in the first argument to be a test function.", 81 | ); 82 | } 83 | } 84 | } else { 85 | throw new TypeError("Unknown test overload"); 86 | } 87 | 88 | if (typeof testDef.fn !== "function") { 89 | throw new TypeError("Missing test function"); 90 | } 91 | 92 | if ((testDef.name?.length ?? 0) === 0) { 93 | throw new TypeError("The test name can't be empty"); 94 | } 95 | 96 | if (additional?.ignore) { 97 | testDef.ignore = true; 98 | } 99 | if (additional?.only) { 100 | testDef.only = true; 101 | } 102 | 103 | testDefinitions.push(testDef); 104 | } 105 | -------------------------------------------------------------------------------- /packages/shim-deno-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2019", 6 | "lib": ["ES2019"], 7 | "declaration": true, 8 | "outDir": "./dist", 9 | "stripInternal": true, 10 | "rootDir": "./src" 11 | }, 12 | "ts-node": { 13 | "transpileOnly": true, 14 | "files": true 15 | }, 16 | "files": ["src/index.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/shim-deno/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/shim-deno/PROGRESS.md: -------------------------------------------------------------------------------- 1 | # Stable Progress 2 | 3 | 87%. 24 stable members to go: 4 | 5 | - [x] 👻 **`Addr`** 6 | - [ ] 👻 **`BenchDefinition`** 7 | - [ ] 👎 **`Buffer`** 8 | - [x] 👻 **`CAARecord`** 9 | - [ ] **`ChildProcess`** 10 | - [x] 👻 **`Closer`** 11 | - [ ] **`Command`** 12 | - [ ] 👻 **`CommandOptions`** 13 | - [ ] 👻 **`CommandOutput`** 14 | - [ ] 👻 **`CommandStatus`** 15 | - [x] 👻 **`Conn`** 16 | - [x] 👻 **`ConnectOptions`** 17 | - [x] 👻 **`ConnectTlsOptions`** 18 | - [x] 👻 **`DirEntry`** 19 | - [x] 👻 **`Env`** 20 | - [x] 👻 **`EnvPermissionDescriptor`** 21 | - [x] 👻 **`FfiPermissionDescriptor`** 22 | - [x] 👎 **`File`** 23 | - [x] 👻 **`FileInfo`** 24 | - [x] 👻 **`FsEvent`** 25 | - [x] 👻 **`FsEventFlag`** 26 | - [x] **`FsFile`** 27 | - [x] 👻 **`FsWatcher`** 28 | - [x] 👻 **`HrtimePermissionDescriptor`** 29 | - [ ] 👻 **`HttpConn`** 30 | - [x] 👻 **`InspectOptions`** 31 | - [x] 👻 **`ListenOptions`** 32 | - [x] 👻 **`ListenTlsOptions`** 33 | - [x] 👻 **`Listener`** 34 | - [x] 👻 **`MXRecord`** 35 | - [x] 👻 **`MakeTempOptions`** 36 | - [x] 👻 **`MemoryUsage`** 37 | - [x] 👻 **`Metrics`** 38 | - [x] 👻 **`MkdirOptions`** 39 | - [x] 👻 **`NAPTRRecord`** 40 | - [x] 👻 **`NetAddr`** 41 | - [x] 👻 **`NetPermissionDescriptor`** 42 | - [ ] 👻 **`NetworkInterfaceInfo`** 43 | - [x] 👻 **`OpMetrics`** 44 | - [x] 👻 **`OpenOptions`** 45 | - [x] 👻 **`PermissionDescriptor`** 46 | - [x] 👻 **`PermissionName`** 47 | - [x] 👻 **`PermissionOptions`** 48 | - [x] 👻 **`PermissionOptionsObject`** 49 | - [x] 👻 **`PermissionState`** 50 | - [x] **`PermissionStatus`** 51 | - [x] 👻 **`PermissionStatusEventMap`** 52 | - [x] **`Permissions`** 53 | - [x] **`Process`** 54 | - [x] 👎 👻 **`ProcessStatus`** 55 | - [x] 👻 **`ReadFileOptions`** 56 | - [x] 👻 **`ReadPermissionDescriptor`** 57 | - [x] 👻 **`Reader`** 58 | - [x] 👻 **`ReaderSync`** 59 | - [x] 👻 **`RecordType`** 60 | - [x] 👻 **`RemoveOptions`** 61 | - [ ] 👻 **`RequestEvent`** 62 | - [x] 👻 **`ResolveDnsOptions`** 63 | - [x] 👻 **`ResourceMap`** 64 | - [x] 👎 👻 **`RunOptions`** 65 | - [x] 👻 **`RunPermissionDescriptor`** 66 | - [x] 👻 **`SOARecord`** 67 | - [x] 👻 **`SRVRecord`** 68 | - [x] **`SeekMode`** 69 | - [x] 👻 **`Seeker`** 70 | - [x] 👻 **`SeekerSync`** 71 | - [x] 👻 **`SetRawOptions`** 72 | - [x] 👻 **`Signal`** 73 | - [ ] 👻 **`StartTlsOptions`** 74 | - [x] 👻 **`SymlinkOptions`** 75 | - [x] 👻 **`SysPermissionDescriptor`** 76 | - [ ] 👻 **`SystemMemoryInfo`** 77 | - [x] 👻 **`TcpConn`** 78 | - [x] 👻 **`TcpListenOptions`** 79 | - [x] 👻 **`TestContext`** 80 | - [x] 👻 **`TestDefinition`** 81 | - [x] 👻 **`TestStepDefinition`** 82 | - [x] 👻 **`TlsConn`** 83 | - [x] 👻 **`TlsHandshakeInfo`** 84 | - [x] 👻 **`TlsListener`** 85 | - [x] 👻 **`UnixAddr`** 86 | - [x] 👻 **`UnixConn`** 87 | - [ ] 👻 **`UpgradeWebSocketOptions`** 88 | - [ ] 👻 **`WebSocketUpgrade`** 89 | - [x] 👻 **`WriteFileOptions`** 90 | - [x] 👻 **`WritePermissionDescriptor`** 91 | - [x] 👻 **`Writer`** 92 | - [x] 👻 **`WriterSync`** 93 | - [x] **`addSignalListener`** 94 | - [x] **`args`** 95 | - [ ] **`bench`** 96 | - [x] **`build`** 97 | - [x] **`chdir`** 98 | - [x] **`chmod`** 99 | - [x] **`chmodSync`** 100 | - [x] **`chown`** 101 | - [x] **`chownSync`** 102 | - [x] **`close`** 103 | - [x] **`connect`** 104 | - [x] **`connectTls`** 105 | - [ ] **`consoleSize`** 106 | - [x] 👎 **`copy`** 107 | - [x] **`copyFile`** 108 | - [x] **`copyFileSync`** 109 | - [x] **`create`** 110 | - [x] **`createSync`** 111 | - [x] 👎 **`customInspect`** 112 | - [x] **`cwd`** 113 | - [x] **`env`** 114 | - [x] **`errors`** 115 | - [x] **`execPath`** 116 | - [x] **`exit`** 117 | - [x] **`fdatasync`** 118 | - [x] **`fdatasyncSync`** 119 | - [x] **`fstat`** 120 | - [x] **`fstatSync`** 121 | - [x] **`fsync`** 122 | - [x] **`fsyncSync`** 123 | - [x] **`ftruncate`** 124 | - [x] **`ftruncateSync`** 125 | - [x] **`futime`** 126 | - [x] **`futimeSync`** 127 | - [x] **`gid`** 128 | - [x] **`hostname`** 129 | - [x] **`inspect`** 130 | - [x] **`isatty`** 131 | - [ ] 👎 **`iter`** 132 | - [ ] 👎 **`iterSync`** 133 | - [x] **`kill`** 134 | - [x] **`link`** 135 | - [x] **`linkSync`** 136 | - [x] **`listen`** 137 | - [x] **`listenTls`** 138 | - [x] **`loadavg`** 139 | - [x] **`lstat`** 140 | - [x] **`lstatSync`** 141 | - [x] **`mainModule`** 142 | - [x] **`makeTempDir`** 143 | - [x] **`makeTempDirSync`** 144 | - [x] **`makeTempFile`** 145 | - [x] **`makeTempFileSync`** 146 | - [x] **`memoryUsage`** 147 | - [x] **`metrics`** 148 | - [x] **`mkdir`** 149 | - [x] **`mkdirSync`** 150 | - [ ] **`networkInterfaces`** 151 | - [x] **`noColor`** 152 | - [x] **`open`** 153 | - [x] **`openSync`** 154 | - [x] **`osRelease`** 155 | - [x] **`osUptime`** 156 | - [x] **`permissions`** 157 | - [x] **`pid`** 158 | - [x] **`ppid`** 159 | - [x] **`read`** 160 | - [ ] 👎 **`readAll`** 161 | - [ ] 👎 **`readAllSync`** 162 | - [x] **`readDir`** 163 | - [x] **`readDirSync`** 164 | - [x] **`readFile`** 165 | - [x] **`readFileSync`** 166 | - [x] **`readLink`** 167 | - [x] **`readLinkSync`** 168 | - [x] **`readSync`** 169 | - [x] **`readTextFile`** 170 | - [x] **`readTextFileSync`** 171 | - [x] **`realPath`** 172 | - [x] **`realPathSync`** 173 | - [ ] **`refTimer`** 174 | - [x] **`remove`** 175 | - [x] **`removeSignalListener`** 176 | - [x] **`removeSync`** 177 | - [x] **`rename`** 178 | - [x] **`renameSync`** 179 | - [x] **`resolveDns`** 180 | - [x] **`resources`** 181 | - [x] 👎 **`run`** 182 | - [ ] **`seek`** 183 | - [ ] **`seekSync`** 184 | - [ ] **`serveHttp`** 185 | - [x] **`shutdown`** 186 | - [ ] **`startTls`** 187 | - [x] **`stat`** 188 | - [x] **`statSync`** 189 | - [x] **`stderr`** 190 | - [x] **`stdin`** 191 | - [x] **`stdout`** 192 | - [x] **`symlink`** 193 | - [x] **`symlinkSync`** 194 | - [ ] **`systemMemoryInfo`** 195 | - [x] **`test`** 196 | - [x] **`truncate`** 197 | - [x] **`truncateSync`** 198 | - [x] **`uid`** 199 | - [ ] **`unrefTimer`** 200 | - [ ] **`upgradeWebSocket`** 201 | - [x] **`utime`** 202 | - [x] **`utimeSync`** 203 | - [x] **`version`** 204 | - [x] **`watchFs`** 205 | - [x] **`write`** 206 | - [ ] 👎 **`writeAll`** 207 | - [ ] 👎 **`writeAllSync`** 208 | - [x] **`writeFile`** 209 | - [x] **`writeFileSync`** 210 | - [x] **`writeSync`** 211 | - [x] **`writeTextFile`** 212 | - [x] **`writeTextFileSync`** 213 | 214 | # Unstable Progress 215 | 216 | 33%. 2 unstable members to go: 217 | 218 | - [ ] 🧪 👻 **`AtomicCheck`** 219 | - [ ] 🧪 **`AtomicOperation`** 220 | - [ ] 🧪 👻 **`BasicAuth`** 221 | - [x] 🧪 👻 **`ConnectTlsOptions`** 222 | - [ ] 🧪 👻 **`CreateHttpClientOptions`** 223 | - [ ] 🧪 👻 **`DatagramConn`** 224 | - [ ] 🧪 👻 **`DynamicLibrary`** 225 | - [ ] 🧪 👻 **`ForeignFunction`** 226 | - [ ] 🧪 👻 **`ForeignLibraryInterface`** 227 | - [ ] 🧪 👻 **`ForeignStatic`** 228 | - [ ] 🧪 👻 **`HttpClient`** 229 | - [ ] 🧪 **`Kv`** 230 | - [ ] 👻 **`KvCommitError`** 231 | - [ ] 👻 **`KvCommitResult`** 232 | - [ ] 🧪 👻 **`KvConsistencyLevel`** 233 | - [ ] 🧪 👻 **`KvEntry`** 234 | - [ ] 🧪 👻 **`KvEntryMaybe`** 235 | - [ ] 🧪 👻 **`KvKey`** 236 | - [ ] 🧪 👻 **`KvKeyPart`** 237 | - [ ] 🧪 **`KvListIterator`** 238 | - [ ] 🧪 👻 **`KvListOptions`** 239 | - [ ] 🧪 👻 **`KvListSelector`** 240 | - [ ] 🧪 👻 **`KvMutation`** 241 | - [ ] 🧪 **`KvU64`** 242 | - [x] 🧪 👻 **`ListenTlsOptions`** 243 | - [ ] 🧪 👻 **`NativeResultType`** 244 | - [ ] 🧪 👻 **`NativeType`** 245 | - [ ] 🧪 👻 **`PointerValue`** 246 | - [ ] 🧪 👻 **`Proxy`** 247 | - [ ] 🧪 👻 **`ServeHandler`** 248 | - [ ] 🧪 👻 **`ServeHandlerInfo`** 249 | - [ ] 🧪 👻 **`ServeInit`** 250 | - [ ] 🧪 👻 **`ServeOptions`** 251 | - [ ] 🧪 👻 **`ServeTlsOptions`** 252 | - [ ] 🧪 👻 **`StartTlsOptions`** 253 | - [x] 👻 **`TcpListenOptions`** 254 | - [x] 🧪 👻 **`TlsConn`** 255 | - [x] 🧪 👻 **`TlsHandshakeInfo`** 256 | - [ ] 🧪 👻 **`UdpListenOptions`** 257 | - [x] 🧪 👻 **`UnixConnectOptions`** 258 | - [x] 🧪 👻 **`UnixListenOptions`** 259 | - [ ] 🧪 **`UnsafeCallback`** 260 | - [ ] 🧪 👻 **`UnsafeCallbackDefinition`** 261 | - [ ] 🧪 **`UnsafeFnPointer`** 262 | - [ ] 🧪 **`UnsafePointer`** 263 | - [ ] 🧪 **`UnsafePointerView`** 264 | - [x] 🧪 **`connect`** 265 | - [x] 🧪 **`connectTls`** 266 | - [ ] 🧪 **`createHttpClient`** 267 | - [ ] 🧪 **`dlopen`** 268 | - [ ] 🧪 **`flock`** 269 | - [ ] 🧪 **`flockSync`** 270 | - [ ] 🧪 **`funlock`** 271 | - [ ] 🧪 **`funlockSync`** 272 | - [x] 🧪 **`listen`** 273 | - [ ] 🧪 **`listenDatagram`** 274 | - [ ] 🧪 **`openKv`** 275 | - [x] 🧪 **`run`** 276 | - [ ] 🧪 **`serve`** 277 | - [ ] 🧪 **`umask`** 278 | - [ ] 🧪 **`upgradeHttp`** 279 | -------------------------------------------------------------------------------- /packages/shim-deno/README.md: -------------------------------------------------------------------------------- 1 | # @deno/shim-deno 2 | 3 | [`Deno` namespace](https://doc.deno.land/builtin/stable) shim for Node.js. 4 | 5 | See 6 | [PROGRESS.md](https://github.com/denoland/node_deno_shims/blob/main/packages/shim-deno/PROGRESS.md) 7 | 8 | ## Acknowledgements 9 | 10 | Special thanks to the [@fromdeno](https://github.com/fromdeno) organization for 11 | starting this project and for their contributions—specifically 12 | [@wojpawlik](https://github.com/wojpawlik), 13 | [@MKRhere](https://github.com/MKRhere), and 14 | [@trgwii](https://github.com/trgwii). 15 | 16 | ## Contributing 17 | 18 | ### Updating Deno 19 | 20 | 1. Update local version. 21 | 1. In `/.github/workflows/ci.yml`, increase the deno version in the setup-deno 22 | action 23 | 1. Update version in `./tools/denolib.ts` 24 | 1. Go into `./third_party/deno` and update the submodule: 25 | - `git fetch --tags` 26 | - `git checkout v1.x.x` -- replace with version 27 | - `git submodule update` 28 | 1. In this package ensure the following work and if not, fix any issues: 29 | - `npm run build` 30 | - `npm run test` 31 | -------------------------------------------------------------------------------- /packages/shim-deno/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/shim-deno", 3 | "version": "0.19.2", 4 | "description": "Deno namespace shim for Node.js", 5 | "keywords": [ 6 | "deno namespace", 7 | "deno", 8 | "polyfill", 9 | "ponyfill", 10 | "shim" 11 | ], 12 | "main": "./dist/index.cjs", 13 | "types": "./dist/index.d.cts", 14 | "author": "Thomas Rory Gummerson (https://trgwii.no/)", 15 | "contributors": [ 16 | "Wojciech Pawlik ", 17 | "Muthu Kumar (https://mkr.pw)" 18 | ], 19 | "license": "MIT", 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/denoland/node_deno_shims.git" 23 | }, 24 | "exports": { 25 | ".": { 26 | "import": "./dist/index.mjs", 27 | "require": "./dist/index.cjs" 28 | }, 29 | "./test-internals": { 30 | "import": "./dist/test-internals.mjs", 31 | "require": "./dist/test-internals.cjs" 32 | } 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "build": "npm run denolib && tsc && tsc --build tsconfig.esm.json && npm run generate-declaration-file && deno run -A tools/bundle.ts", 39 | "prepublishOnly": "npm run build", 40 | "clean": "git clean -fXde !node_modules/", 41 | "test": "node --loader=ts-node/esm tools/run_tests.mjs", 42 | "denolib": "deno run --allow-run --allow-write=src/deno tools/denolib.ts", 43 | "generate-declaration-file": "deno run --allow-write=lib,dist --allow-read tools/generateDeclarationFile.ts", 44 | "update-progress": "deno run --allow-read tools/missing.ts > PROGRESS.md" 45 | }, 46 | "dependencies": { 47 | "@deno/shim-deno-test": "^0.5.0", 48 | "which": "^4.0.0" 49 | }, 50 | "devDependencies": { 51 | "@types/node": "^20.9.0", 52 | "@types/which": "^3.0.2", 53 | "ts-node": "^10.9.1", 54 | "typescript": "^5.2.2" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/Conn.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { Socket } from "net"; 4 | import { once } from "events"; 5 | 6 | import { FsFile } from "../stable/classes/FsFile.js"; 7 | 8 | export class Conn extends FsFile implements Deno.Conn { 9 | #socket: Socket; 10 | 11 | constructor( 12 | readonly rid: number, 13 | readonly localAddr: Deno.Addr, 14 | readonly remoteAddr: Deno.Addr, 15 | socket?: Socket, 16 | ) { 17 | super(rid); 18 | this.#socket = socket || new Socket({ fd: rid }); 19 | } 20 | 21 | [Symbol.dispose]() { 22 | this.close(); 23 | } 24 | 25 | async closeWrite() { 26 | await new Promise((resolve) => this.#socket.end(resolve)); 27 | } 28 | 29 | setNoDelay(enable?: boolean) { 30 | this.#socket.setNoDelay(enable); 31 | } 32 | 33 | setKeepAlive(enable?: boolean) { 34 | this.#socket.setKeepAlive(enable); 35 | } 36 | 37 | ref(): void { 38 | this.#socket.ref(); 39 | } 40 | 41 | unref(): void { 42 | this.#socket.unref(); 43 | } 44 | 45 | async read(p: Uint8Array): Promise { 46 | try { 47 | return await super.read(p); 48 | } catch (error) { 49 | if ( 50 | !(error instanceof Error && "code" in error && 51 | error.code == "EAGAIN") 52 | ) { 53 | throw error; 54 | } 55 | } 56 | await once(this.#socket, "readable"); 57 | return await super.read(p); 58 | } 59 | } 60 | 61 | export class TlsConn extends Conn implements Deno.TlsConn { 62 | handshake(): Promise { 63 | console.warn("@deno/shim-deno: Handshake is not supported."); 64 | return Promise.resolve({ 65 | alpnProtocol: null, 66 | }); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/Listener.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { close } from "../stable/functions/close.js"; 4 | import * as errors from "../stable/variables/errors.js"; 5 | 6 | export class Listener implements Deno.Listener { 7 | #listener: AsyncIterableIterator; 8 | 9 | constructor( 10 | readonly rid: number, 11 | readonly addr: Deno.Addr, 12 | listener: AsyncIterableIterator, 13 | ) { 14 | this.#listener = listener; 15 | } 16 | 17 | [Symbol.dispose]() { 18 | this.close(); 19 | } 20 | 21 | async accept() { 22 | if (!this.#listener) { 23 | throw new errors.BadResource("Listener not initialised"); 24 | } 25 | 26 | const result = await this.#listener.next(); 27 | if (result.done) { 28 | throw new errors.BadResource("Server not listening"); 29 | } 30 | return result.value; 31 | } 32 | 33 | async next() { 34 | let conn; 35 | try { 36 | conn = await this.accept(); 37 | } catch (error) { 38 | if (error instanceof errors.BadResource) { 39 | return { value: undefined, done: true } as const; 40 | } 41 | throw error; 42 | } 43 | return { value: conn, done: false }; 44 | } 45 | 46 | return(value: T | Deno.Conn) { 47 | this.close(); 48 | return Promise.resolve({ value, done: true }); 49 | } 50 | 51 | close() { 52 | close(this.rid); 53 | } 54 | 55 | ref() { 56 | throw new Error("Not implemented"); 57 | } 58 | 59 | unref() { 60 | throw new Error("Not implemented"); 61 | } 62 | 63 | [Symbol.asyncIterator]() { 64 | return this; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/consts.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_BUFFER_SIZE = 32 * 1024; 2 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/errorMap.ts: -------------------------------------------------------------------------------- 1 | import * as errors from "../stable/variables/errors.js"; 2 | 3 | type Class = new (...params: unknown[]) => T; 4 | 5 | type ClassOrT = T extends Class ? U : T; 6 | 7 | const mapper = (Ctor: typeof errors[keyof typeof errors]) => (err: Error) => 8 | Object.assign(new Ctor(err.message), { 9 | stack: err.stack, 10 | }) as unknown as ClassOrT; 11 | 12 | const map: Record> = { 13 | EEXIST: mapper(errors.AlreadyExists), 14 | ENOENT: mapper(errors.NotFound), 15 | EBADF: mapper(errors.BadResource), 16 | }; 17 | 18 | const isNodeErr = (e: unknown): e is Error & { code: string } => { 19 | return e instanceof Error && "code" in e; 20 | }; 21 | 22 | export default function mapError(e: E) { 23 | if (!isNodeErr(e)) return e; 24 | return map[e.code]?.(e) || e; 25 | } 26 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/fs_flags.ts: -------------------------------------------------------------------------------- 1 | // getAccessFlag and getCreationFlag adapted from the original in Rust's std::fs 2 | // 3 | 4 | import * as errors from "../stable/variables/errors.js"; 5 | import { constants } from "fs"; 6 | import os from "os"; 7 | 8 | const { O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY } = 9 | constants; 10 | 11 | // deno-lint-ignore ban-types 12 | type Optional = { [K in keyof T]?: T[K] }; 13 | 14 | type Opts = Optional>; 15 | 16 | type AccessModes = "read" | "write" | "append"; 17 | type CreationModes = "write" | "append" | "create" | "truncate" | "createNew"; 18 | 19 | export function getAccessFlag(opts: Opts) { 20 | if (opts.read && !opts.write && !opts.append) return O_RDONLY; 21 | if (!opts.read && opts.write && !opts.append) return O_WRONLY; 22 | if (opts.read && opts.write && !opts.append) return O_RDWR; 23 | if (!opts.read && opts.append) return O_WRONLY | O_APPEND; 24 | if (opts.read && opts.append) return O_RDWR | O_APPEND; 25 | 26 | if (!opts.read && !opts.write && !opts.append) { 27 | throw new errors.BadResource( 28 | "EINVAL: One of 'read', 'write', 'append' is required to open file.", 29 | ); 30 | } 31 | 32 | throw new errors.BadResource("EINVAL: Invalid fs flags."); 33 | } 34 | 35 | export function getCreationFlag(opts: Opts) { 36 | if (!opts.write && !opts.append) { 37 | if (opts.truncate || opts.create || opts.createNew) { 38 | throw new errors.BadResource( 39 | "EINVAL: One of 'write', 'append' is required to 'truncate', 'create' or 'createNew' file.", 40 | ); 41 | } 42 | } 43 | if (opts.append) { 44 | if (opts.truncate && !opts.createNew) { 45 | throw new errors.BadResource( 46 | "EINVAL: unexpected 'truncate': true and 'createNew': false when 'append' is true.", 47 | ); 48 | } 49 | } 50 | 51 | if (!opts.create && !opts.truncate && !opts.createNew) return 0; 52 | if (opts.create && !opts.truncate && !opts.createNew) return O_CREAT; 53 | if (!opts.create && opts.truncate && !opts.createNew) { 54 | if (os.platform() === "win32") { 55 | // for some reason only providing O_TRUNC on windows will 56 | // throw a "EINVAL: invalid argument", so to work around this 57 | // we relax the restriction here to also create the file if it 58 | // doesn't exist 59 | return O_CREAT | O_TRUNC; 60 | } else { 61 | return O_TRUNC; 62 | } 63 | } 64 | if (opts.create && opts.truncate && !opts.createNew) { 65 | return O_CREAT | O_TRUNC; 66 | } 67 | if (opts.createNew) return O_CREAT | O_EXCL; 68 | 69 | throw new errors.BadResource("EINVAL: Invalid fs flags."); 70 | } 71 | 72 | export function getFsFlag(flags: Opts) { 73 | return getAccessFlag(flags) | getCreationFlag(flags); 74 | } 75 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/iterutil.ts: -------------------------------------------------------------------------------- 1 | export function* map(iter: Iterable, f: (t: T) => U): Iterable { 2 | for (const i of iter) { 3 | yield f(i); 4 | } 5 | } 6 | 7 | export async function* mapAsync( 8 | iter: AsyncIterable, 9 | f: (t: T) => U, 10 | ): AsyncIterable { 11 | for await (const i of iter) { 12 | yield f(i); 13 | } 14 | } 15 | 16 | export async function* filterAsync( 17 | iter: AsyncIterable, 18 | filter: (t: T) => boolean, 19 | ): AsyncIterable { 20 | for await (const i of iter) { 21 | if (filter(i)) { 22 | yield i; 23 | } 24 | } 25 | } 26 | 27 | export async function* merge(iterables: AsyncIterable[]) { 28 | const racers = new Map, Promise>>( 29 | map( 30 | map(iterables, (iter) => iter[Symbol.asyncIterator]()), 31 | (iter) => [iter, iter.next()], 32 | ), 33 | ); 34 | 35 | while (racers.size > 0) { 36 | const winner = await Promise.race( 37 | map( 38 | racers.entries(), 39 | ([iter, prom]) => prom.then((result) => ({ result, iter })), 40 | ), 41 | ); 42 | 43 | if (winner.result.done) { 44 | racers.delete(winner.iter); 45 | } else { 46 | yield await winner.result.value; 47 | racers.set(winner.iter, winner.iter.next()); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/random_id.ts: -------------------------------------------------------------------------------- 1 | export const randomId = () => { 2 | const n = (Math.random() * 0xfffff * 1000000).toString(16); 3 | return "" + n.slice(0, 6); 4 | }; 5 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/streams.test.ts: -------------------------------------------------------------------------------- 1 | import { BufferStreamReader, StreamWriter } from "./streams.js"; 2 | import fs from "fs"; 3 | import assert from "assert/strict"; 4 | 5 | // use a small buffer size for testing to cause many reads and writes 6 | const highWaterMark = 128; 7 | 8 | Deno.test("reader should read", async () => { 9 | const stream = fs.createReadStream("README.md", { highWaterMark }); 10 | const reader = new BufferStreamReader(stream); 11 | const chunks: Buffer[] = []; 12 | while (true) { 13 | const buffer = Buffer.alloc(getRandomBufferSize()); 14 | const readSize = await reader.read(buffer); 15 | if (readSize == null) { 16 | break; 17 | } 18 | chunks.push(buffer.slice(0, readSize)); 19 | } 20 | stream.close(); 21 | const result = Buffer.concat(chunks); 22 | const expectedBytes = fs.readFileSync("README.md"); 23 | assert.deepEqual(expectedBytes, result); 24 | }); 25 | 26 | Deno.test("reader should read all", async () => { 27 | const stream = fs.createReadStream("README.md", { highWaterMark }); 28 | const reader = new BufferStreamReader(stream); 29 | const result = await reader.readAll(); 30 | stream.close(); 31 | const expectedBytes = fs.readFileSync("README.md"); 32 | assert.deepEqual(expectedBytes, Buffer.from(result)); 33 | }); 34 | 35 | Deno.test("writer should write", async () => { 36 | const tempFile = await Deno.makeTempFile(); 37 | try { 38 | const readStream = fs.createReadStream("README.md", { highWaterMark }); 39 | const reader = new BufferStreamReader(readStream); 40 | const writeStream = fs.createWriteStream(tempFile, { highWaterMark }); 41 | const writer = new StreamWriter(writeStream); 42 | while (true) { 43 | const buffer = Buffer.alloc(getRandomBufferSize()); 44 | const readSize = await reader.read(buffer); 45 | if (readSize == null) { 46 | break; 47 | } 48 | await writer.write(buffer.slice(0, readSize)); 49 | } 50 | writeStream.close(); 51 | readStream.close(); 52 | 53 | assert.deepEqual( 54 | fs.readFileSync("README.md"), 55 | fs.readFileSync(tempFile), 56 | ); 57 | } finally { 58 | fs.unlinkSync(tempFile); 59 | } 60 | }); 61 | 62 | function getRandomBufferSize() { 63 | // use a value sometimes higher than the buffer size and sometimes lower 64 | const highValue = highWaterMark * 2; 65 | const lowValue = Math.floor(highWaterMark / 2); 66 | return Math.floor(Math.random() * (highValue - lowValue + 1)) + lowValue; 67 | } 68 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/streams.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export class BufferStreamReader implements Deno.Reader { 4 | readonly #stream: NodeJS.ReadableStream; 5 | #error: any; 6 | #ended = false; 7 | #pendingActions: (() => void)[] = []; 8 | 9 | constructor(stream: NodeJS.ReadableStream) { 10 | this.#stream = stream; 11 | this.#stream.pause(); 12 | 13 | this.#stream.on("error", (error) => { 14 | this.#error = error; 15 | this.#runPendingActions(); 16 | }); 17 | 18 | this.#stream.on("readable", () => { 19 | this.#runPendingActions(); 20 | }); 21 | 22 | this.#stream.on("end", () => { 23 | this.#ended = true; 24 | this.#runPendingActions(); 25 | }); 26 | } 27 | 28 | readAll(): Promise { 29 | return new Promise((resolve, reject) => { 30 | const chunks: Buffer[] = []; 31 | const action = () => { 32 | if (this.#error) { 33 | reject(this.#error); 34 | return; 35 | } 36 | 37 | const buffer = this.#stream.read() as Buffer; 38 | if (buffer != null) { 39 | chunks.push(buffer); 40 | this.#pendingActions.push(action); 41 | } else if (this.#ended) { 42 | const result = Buffer.concat(chunks); 43 | resolve(result); 44 | } else { 45 | this.#pendingActions.push(action); 46 | } 47 | }; 48 | 49 | action(); 50 | }); 51 | } 52 | 53 | read(p: Uint8Array): Promise { 54 | return new Promise((resolve, reject) => { 55 | const action = () => { 56 | if (this.#error) { 57 | reject(this.#error); 58 | return; 59 | } 60 | 61 | const readBuffer = this.#stream.read(p.byteLength) as Buffer; 62 | if (readBuffer && readBuffer.byteLength > 0) { 63 | readBuffer.copy(p, 0, 0, readBuffer.byteLength); 64 | resolve(readBuffer.byteLength); 65 | return; 66 | } 67 | 68 | if (this.#ended) { 69 | resolve(null); 70 | } else { 71 | this.#pendingActions.push(action); 72 | } 73 | }; 74 | 75 | action(); 76 | }); 77 | } 78 | 79 | #runPendingActions() { 80 | const errors: any[] = []; 81 | for (const action of this.#pendingActions.splice(0)) { 82 | try { 83 | action(); 84 | } catch (err) { 85 | errors.push(err); 86 | } 87 | } 88 | if (errors.length > 0) { 89 | throw (errors.length > 1 90 | ? new (globalThis as any).AggregateError(errors) 91 | : errors[0]); 92 | } 93 | } 94 | } 95 | 96 | export class StreamWriter implements Deno.Writer { 97 | #stream: NodeJS.WritableStream; 98 | 99 | constructor(stream: NodeJS.WritableStream) { 100 | this.#stream = stream; 101 | } 102 | 103 | write(p: Uint8Array): Promise { 104 | return new Promise((resolve, reject) => { 105 | this.#stream.write(p, (err) => { 106 | if (err) { 107 | reject(err); 108 | } else { 109 | resolve(p.byteLength); 110 | } 111 | }); 112 | }); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/internal/version.ts: -------------------------------------------------------------------------------- 1 | export const deno = "1.40.2"; 2 | export const typescript = "5.3.3"; 3 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/classes.ts: -------------------------------------------------------------------------------- 1 | export { File, FsFile } from "./classes/FsFile.js"; 2 | export { Permissions } from "./classes/Permissions.js"; 3 | export { PermissionStatus } from "./classes/PermissionStatus.js"; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/classes/FsFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import * as stream from "stream"; 5 | import { fstat } from "../functions/fstat.js"; 6 | import { fstatSync } from "../functions/fstatSync.js"; 7 | import { ftruncate } from "../functions/ftruncate.js"; 8 | import { ftruncateSync } from "../functions/ftruncateSync.js"; 9 | import { fdatasync } from "../functions/fdatasync.js"; 10 | import { fdatasyncSync } from "../functions/fdatasyncSync.js"; 11 | import { read } from "../functions/read.js"; 12 | import { readSync } from "../functions/readSync.js"; 13 | import { write } from "../functions/write.js"; 14 | import { writeSync } from "../functions/writeSync.js"; 15 | 16 | (Symbol as any).dispose ??= Symbol("Symbol.dispose"); 17 | (Symbol as any).asyncDispose ??= Symbol("Symbol.asyncDispose"); 18 | 19 | export class FsFile implements Deno.FsFile { 20 | #closed = false; 21 | 22 | constructor(readonly rid: number) {} 23 | 24 | [Symbol.dispose]() { 25 | if (!this.#closed) { 26 | this.close(); 27 | } 28 | } 29 | 30 | async write(p: Uint8Array): Promise { 31 | return await write(this.rid, p); 32 | } 33 | 34 | writeSync(p: Uint8Array): number { 35 | return writeSync(this.rid, p); 36 | } 37 | 38 | async truncate(len?: number): Promise { 39 | await ftruncate(this.rid, len); 40 | } 41 | 42 | truncateSync(len?: number): void { 43 | return ftruncateSync(this.rid, len); 44 | } 45 | 46 | read(p: Uint8Array): Promise { 47 | return read(this.rid, p); 48 | } 49 | 50 | readSync(p: Uint8Array): number | null { 51 | return readSync(this.rid, p); 52 | } 53 | 54 | seek(_offset: number, _whence: Deno.SeekMode): Promise { 55 | throw new Error("Method not implemented."); 56 | } 57 | 58 | seekSync(_offset: number, _whence: Deno.SeekMode): number { 59 | throw new Error("Method not implemented."); 60 | } 61 | 62 | async stat(): Promise { 63 | return await fstat(this.rid); 64 | } 65 | 66 | statSync(): Deno.FileInfo { 67 | return fstatSync(this.rid); 68 | } 69 | 70 | sync(): Promise { 71 | throw new Error("Method not implemented."); 72 | } 73 | 74 | syncSync(): void { 75 | throw new Error("Method not implemented."); 76 | } 77 | 78 | syncData(): Promise { 79 | return fdatasync(this.rid); 80 | } 81 | 82 | syncDataSync(): void { 83 | return fdatasyncSync(this.rid); 84 | } 85 | 86 | utime(_atime: number | Date, _mtime: number | Date): Promise { 87 | throw new Error("Method not implemented."); 88 | } 89 | 90 | utimeSync(_atime: number | Date, _mtime: number | Date): void { 91 | throw new Error("Method not implemented."); 92 | } 93 | 94 | close(): void { 95 | this.#closed = true; 96 | fs.closeSync(this.rid); 97 | } 98 | 99 | #readableStream: ReadableStream | undefined; 100 | get readable(): ReadableStream { 101 | if (this.#readableStream == null) { 102 | const nodeStream = fs.createReadStream(null as any, { 103 | fd: this.rid, 104 | autoClose: false, 105 | }); 106 | this.#readableStream = stream.Readable.toWeb(nodeStream); 107 | } 108 | return this.#readableStream; 109 | } 110 | 111 | #writableStream: WritableStream | undefined; 112 | get writable(): WritableStream { 113 | if (this.#writableStream == null) { 114 | const nodeStream = fs.createWriteStream(null as any, { 115 | fd: this.rid, 116 | autoClose: false, 117 | }); 118 | this.#writableStream = stream.Writable.toWeb(nodeStream); 119 | } 120 | return this.#writableStream; 121 | } 122 | } 123 | 124 | const File = FsFile; 125 | 126 | export { File }; 127 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/classes/PermissionStatus.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export class PermissionStatus extends EventTarget 4 | implements Deno.PermissionStatus { 5 | onchange: ((this: PermissionStatus, ev: Event) => any) | null = null; 6 | readonly partial: boolean = false; 7 | 8 | /** @internal */ 9 | constructor(readonly state: Deno.PermissionState) { 10 | super(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/classes/Permissions.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { PermissionStatus } from "../classes/PermissionStatus.js"; 4 | 5 | export class Permissions implements Deno.Permissions { 6 | query(desc: Deno.PermissionDescriptor) { 7 | return Promise.resolve(this.querySync(desc)); 8 | } 9 | 10 | querySync(_desc: Deno.PermissionDescriptor) { 11 | return new PermissionStatus("granted"); 12 | } 13 | 14 | revoke(desc: Deno.PermissionDescriptor) { 15 | return Promise.resolve(this.revokeSync(desc)); 16 | } 17 | 18 | revokeSync(_desc: Deno.PermissionDescriptor) { 19 | return new PermissionStatus("denied"); 20 | } 21 | 22 | request(desc: Deno.PermissionDescriptor) { 23 | return this.query(desc); 24 | } 25 | 26 | requestSync(desc: Deno.PermissionDescriptor) { 27 | return this.querySync(desc); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/enums.ts: -------------------------------------------------------------------------------- 1 | export { SeekMode } from "./enums/SeekMode.js"; 2 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/enums/SeekMode.ts: -------------------------------------------------------------------------------- 1 | export enum SeekMode { 2 | Start = 0, 3 | Current = 1, 4 | End = 2, 5 | } 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import mapError from "../internal/errorMap.js"; 3 | import { errors } from "./variables.js"; 4 | 5 | // todo(dsherret): collapse all these files into here 6 | 7 | export { isatty } from "tty"; 8 | export { addSignalListener } from "./functions/addSignalListener.js"; 9 | export { chdir } from "./functions/chdir.js"; 10 | export { chmod } from "./functions/chmod.js"; 11 | export { chmodSync } from "./functions/chmodSync.js"; 12 | export { chown } from "./functions/chown.js"; 13 | export { chownSync } from "./functions/chownSync.js"; 14 | export { close } from "./functions/close.js"; 15 | export { connect } from "./functions/connect.js"; 16 | export { connectTls } from "./functions/connectTls.js"; 17 | export { consoleSize } from "./functions/consoleSize.js"; 18 | export { copy } from "./functions/copy.js"; 19 | export { copyFile } from "./functions/copyFile.js"; 20 | export { copyFileSync } from "./functions/copyFileSync.js"; 21 | export { create } from "./functions/create.js"; 22 | export { createSync } from "./functions/createSync.js"; 23 | export { cwd } from "./functions/cwd.js"; 24 | export { execPath } from "./functions/execPath.js"; 25 | export { exit } from "./functions/exit.js"; 26 | export { fdatasync } from "./functions/fdatasync.js"; 27 | export { fdatasyncSync } from "./functions/fdatasyncSync.js"; 28 | export { fstat } from "./functions/fstat.js"; 29 | export { fstatSync } from "./functions/fstatSync.js"; 30 | export { fsync } from "./functions/fsync.js"; 31 | export { fsyncSync } from "./functions/fsyncSync.js"; 32 | export { ftruncate } from "./functions/ftruncate.js"; 33 | export { ftruncateSync } from "./functions/ftruncateSync.js"; 34 | export { gid } from "./functions/gid.js"; 35 | export { hostname } from "./functions/hostname.js"; 36 | export { inspect } from "./functions/inspect.js"; 37 | export { kill } from "./functions/kill.js"; 38 | export { link } from "./functions/link.js"; 39 | export { linkSync } from "./functions/linkSync.js"; 40 | export { listen } from "./functions/listen.js"; 41 | export { listenTls } from "./functions/listenTls.js"; 42 | export { loadavg } from "./functions/loadavg.js"; 43 | export { lstat } from "./functions/lstat.js"; 44 | export { lstatSync } from "./functions/lstatSync.js"; 45 | export { makeTempDir } from "./functions/makeTempDir.js"; 46 | export { makeTempDirSync } from "./functions/makeTempDirSync.js"; 47 | export { makeTempFile } from "./functions/makeTempFile.js"; 48 | export { makeTempFileSync } from "./functions/makeTempFileSync.js"; 49 | export { memoryUsage } from "./functions/memoryUsage.js"; 50 | export { mkdir } from "./functions/mkdir.js"; 51 | export { mkdirSync } from "./functions/mkdirSync.js"; 52 | export { open } from "./functions/open.js"; 53 | export { openSync } from "./functions/openSync.js"; 54 | export { osRelease } from "./functions/osRelease.js"; 55 | export { osUptime } from "./functions/osUptime.js"; 56 | export { read } from "./functions/read.js"; 57 | export { readDir } from "./functions/readDir.js"; 58 | export { readDirSync } from "./functions/readDirSync.js"; 59 | export { readFile } from "./functions/readFile.js"; 60 | export { readFileSync } from "./functions/readFileSync.js"; 61 | export { readLink } from "./functions/readLink.js"; 62 | export { readLinkSync } from "./functions/readLinkSync.js"; 63 | export { readSync } from "./functions/readSync.js"; 64 | export { readTextFile } from "./functions/readTextFile.js"; 65 | export { readTextFileSync } from "./functions/readTextFileSync.js"; 66 | export { realPath } from "./functions/realPath.js"; 67 | export { realPathSync } from "./functions/realPathSync.js"; 68 | export { remove } from "./functions/remove.js"; 69 | export { removeSignalListener } from "./functions/removeSignalListener.js"; 70 | export { removeSync } from "./functions/removeSync.js"; 71 | export { rename } from "./functions/rename.js"; 72 | export { renameSync } from "./functions/renameSync.js"; 73 | export { resolveDns } from "./functions/resolveDns.js"; 74 | export { Process, run } from "./functions/run.js"; 75 | export type { UnstableRunOptions } from "./functions/run.js"; 76 | export { shutdown } from "./functions/shutdown.js"; 77 | export { stat } from "./functions/stat.js"; 78 | export { statSync } from "./functions/statSync.js"; 79 | export { symlink } from "./functions/symlink.js"; 80 | export { symlinkSync } from "./functions/symlinkSync.js"; 81 | export { test } from "./functions/test.js"; 82 | export { truncate } from "./functions/truncate.js"; 83 | export { truncateSync } from "./functions/truncateSync.js"; 84 | export { uid } from "./functions/uid.js"; 85 | export { watchFs } from "./functions/watchFs.js"; 86 | export { write } from "./functions/write.js"; 87 | export { writeFile } from "./functions/writeFile.js"; 88 | export { writeFileSync } from "./functions/writeFileSync.js"; 89 | export { writeSync } from "./functions/writeSync.js"; 90 | export { writeTextFile } from "./functions/writeTextFile.js"; 91 | export { writeTextFileSync } from "./functions/writeTextFileSync.js"; 92 | export { args } from "./variables/args.js"; 93 | 94 | export const futime: typeof Deno.futime = async function (rid, atime, mtime) { 95 | try { 96 | await new Promise((resolve, reject) => { 97 | // doesn't exist in fs.promises 98 | fs.futimes(rid, atime, mtime, (err) => { 99 | if (err) { 100 | reject(err); 101 | } else { 102 | resolve(); 103 | } 104 | }); 105 | }); 106 | } catch (error) { 107 | throw mapError(error); 108 | } 109 | }; 110 | 111 | export const futimeSync: typeof Deno.futimeSync = function (rid, atime, mtime) { 112 | try { 113 | fs.futimesSync(rid, atime, mtime); 114 | } catch (error: any) { 115 | throw mapError(error); 116 | } 117 | }; 118 | 119 | export const utime: typeof Deno.utime = async function (path, atime, mtime) { 120 | try { 121 | await fs.promises.utimes(path, atime, mtime); 122 | } catch (error: any) { 123 | if (error?.code === "ENOENT") { 124 | throw new errors.NotFound( 125 | `No such file or directory (os error 2), utime '${path}'`, 126 | ); 127 | } 128 | throw mapError(error); 129 | } 130 | }; 131 | 132 | export const utimeSync: typeof Deno.utimeSync = function (path, atime, mtime) { 133 | try { 134 | fs.utimesSync(path, atime, mtime); 135 | } catch (error: any) { 136 | if (error?.code === "ENOENT") { 137 | throw new errors.NotFound( 138 | `No such file or directory (os error 2), utime '${path}'`, 139 | ); 140 | } 141 | throw mapError(error); 142 | } 143 | }; 144 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/addSignalListener.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import ps from "process"; 4 | 5 | function denoSignalToNodeJs(signal: Deno.Signal): NodeJS.Signals { 6 | if (signal === "SIGEMT") { 7 | throw new Error("SIGEMT is not supported"); 8 | } 9 | return signal; 10 | } 11 | 12 | export const addSignalListener: typeof Deno.addSignalListener = ( 13 | signal, 14 | handler, 15 | ) => { 16 | ps.addListener(denoSignalToNodeJs(signal), handler); 17 | }; 18 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/chdir.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fileURLToPath } from "url"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import { errors } from "../variables.js"; 6 | 7 | export const chdir: typeof Deno.chdir = function (path: string | URL) { 8 | try { 9 | return process.chdir(path instanceof URL ? fileURLToPath(path) : path); 10 | } catch (error: any) { 11 | if (error?.code === "ENOENT") { 12 | throw new errors.NotFound( 13 | `No such file or directory (os error 2), chdir '${path}'`, 14 | ); 15 | } 16 | throw mapError(error); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/chmod.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const chmod: typeof Deno.chmod = fs.chmod; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/chmodSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const chmodSync: typeof Deno.chmodSync = fs.chmodSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/chown.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const chown: typeof Deno.chown = async (path, uid, gid) => 6 | await fs.chown(path, uid ?? -1, gid ?? -1); 7 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/chownSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const chownSync: typeof Deno.chownSync = (path, uid, gid) => 6 | fs.chownSync(path, uid ?? -1, gid ?? -1); 7 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/close.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const close: typeof Deno.close = fs.closeSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/connect.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { createConnection } from "net"; 4 | import { Conn } from "../../internal/Conn.js"; 5 | 6 | export const connect: typeof Deno.connect = function connect(options) { 7 | if (options.transport === "unix") { 8 | throw new Error("Unstable UnixConnectOptions is not implemented"); 9 | } 10 | const { transport = "tcp", hostname = "127.0.0.1", port } = options; 11 | if (transport !== "tcp") { 12 | throw new Error("Deno.connect is only implemented for transport: tcp"); 13 | } 14 | 15 | const socket = createConnection({ port, host: hostname }); 16 | 17 | socket.on("error", (err) => console.error(err)); 18 | 19 | return new Promise((resolve) => { 20 | socket.once("connect", () => { 21 | // @ts-expect-error undocumented socket._handle property 22 | const rid: number = socket._handle.fd; 23 | 24 | const localAddr: Deno.Addr = { 25 | // cannot be undefined while socket is connected 26 | hostname: socket.localAddress!, 27 | port: socket.localPort!, 28 | transport: "tcp", 29 | }; 30 | 31 | const remoteAddr: Deno.Addr = { 32 | // cannot be undefined while socket is connected 33 | hostname: socket.remoteAddress!, 34 | port: socket.remotePort!, 35 | transport: "tcp", 36 | }; 37 | 38 | resolve(new Conn(rid, localAddr, remoteAddr, socket)); 39 | }); 40 | }); 41 | }; 42 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/connectTls.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { connect as tlsConnect } from "tls"; 4 | import { TlsConn } from "../../internal/Conn.js"; 5 | import { readTextFile } from "./readTextFile.js"; 6 | 7 | export const connectTls: typeof Deno.connectTls = async function connectTls( 8 | { port, hostname = "127.0.0.1", certFile }, 9 | ) { 10 | const cert = certFile && await readTextFile(certFile); 11 | 12 | const socket = tlsConnect({ port, host: hostname, cert }); 13 | 14 | return new Promise((resolve) => { 15 | socket.on("connect", () => { 16 | // @ts-expect-error undocumented socket._handle property 17 | const rid: number = socket._handle.fd; 18 | const localAddr: Deno.Addr = { 19 | // cannot be undefined while socket is connected 20 | hostname: socket.localAddress!, 21 | port: socket.localPort!, 22 | transport: "tcp", 23 | }; 24 | const remoteAddr: Deno.Addr = { 25 | // cannot be undefined while socket is connected 26 | hostname: socket.remoteAddress!, 27 | port: socket.remotePort!, 28 | transport: "tcp", 29 | }; 30 | 31 | resolve(new TlsConn(rid, localAddr, remoteAddr, socket)); 32 | }); 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/consoleSize.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const consoleSize: typeof Deno.consoleSize = function consoleSize() { 4 | const pipes = [process.stderr, process.stdout]; 5 | for (const pipe of pipes) { 6 | if (pipe.columns != null) { 7 | const { columns, rows } = pipe; 8 | return { columns, rows }; 9 | } 10 | } 11 | // Both stdout and stderr were piped. This is not the best error message, 12 | // but it's what Deno does. Opened: https://github.com/denoland/deno/issues/22162 13 | throw new Error("The handle is invalid."); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/copy.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { DEFAULT_BUFFER_SIZE } from "../../internal/consts.js"; 4 | 5 | export const copy: typeof Deno.copy = async function copy(src, dst, options) { 6 | let n = 0; 7 | const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; 8 | const b = new Uint8Array(bufSize); 9 | let gotEOF = false; 10 | while (gotEOF === false) { 11 | const result = await src.read(b); 12 | if (result === null) { 13 | gotEOF = true; 14 | } else { 15 | let nwritten = 0; 16 | while (nwritten < result) { 17 | nwritten += await dst.write(b.subarray(nwritten, result)); 18 | } 19 | n += nwritten; 20 | } 21 | } 22 | return n; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/copyFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import * as errors from "../variables/errors.js"; 6 | 7 | export const copyFile: typeof Deno.copyFile = async (src, dest) => { 8 | try { 9 | await fs.copyFile(src, dest); 10 | } catch (error: any) { 11 | if (error?.code === "ENOENT") { 12 | throw new errors.NotFound(`File not found, copy '${src}' -> '${dest}'`); 13 | } 14 | throw mapError(error); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/copyFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import * as errors from "../variables/errors.js"; 6 | 7 | export const copyFileSync: typeof Deno.copyFileSync = (src, dest) => { 8 | try { 9 | fs.copyFileSync(src, dest); 10 | } catch (error: any) { 11 | if (error?.code === "ENOENT") { 12 | throw new errors.NotFound(`File not found, copy '${src}' -> '${dest}'`); 13 | } 14 | throw mapError(error); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/create.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { open } from "./open.js"; 4 | 5 | export const create: typeof Deno.create = async function create(path) { 6 | return await open(path, { write: true, create: true, truncate: true }); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/createSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { openSync } from "./openSync.js"; 4 | 5 | export const createSync: typeof Deno.createSync = function createSync(path) { 6 | return openSync(path, { 7 | create: true, 8 | truncate: true, 9 | read: true, 10 | write: true, 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/cwd.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const cwd: typeof Deno.cwd = process.cwd; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/execPath.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import which from "which"; 4 | 5 | export const execPath: typeof Deno.execPath = () => which.sync("deno"); 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/exit.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const exit: typeof Deno.exit = function exit(code) { 4 | return process.exit(code); 5 | }; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fdatasync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fdatasync as nodefdatasync } from "fs"; 4 | import { promisify } from "util"; 5 | 6 | const _fdatasync = promisify(nodefdatasync); 7 | 8 | export const fdatasync: typeof Deno.fdatasync = _fdatasync; 9 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fdatasyncSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fdatasyncSync as nodefdatasyncSync } from "fs"; 4 | 5 | export const fdatasyncSync: typeof Deno.fdatasyncSync = nodefdatasyncSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fstat.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import { promisify } from "util"; 5 | import { denoifyFileInfo } from "./stat.js"; 6 | import mapError from "../../internal/errorMap.js"; 7 | 8 | const nodeFstat = promisify(fs.fstat); 9 | 10 | export const fstat: typeof Deno.fstat = async function (fd) { 11 | try { 12 | return denoifyFileInfo(await nodeFstat(fd)); 13 | } catch (err) { 14 | throw mapError(err); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fstatSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fstatSync as nodeFstatSync } from "fs"; 4 | import { denoifyFileInfo } from "./stat.js"; 5 | import mapError from "../../internal/errorMap.js"; 6 | 7 | export const fstatSync: typeof Deno.fstatSync = function fstatSync(fd) { 8 | try { 9 | return denoifyFileInfo(nodeFstatSync(fd)); 10 | } catch (err) { 11 | throw mapError(err); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fsync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fsync as nodeFsync } from "fs"; 4 | import { promisify } from "util"; 5 | 6 | export const fsync: typeof Deno.fsync = function fsync(rid) { 7 | return promisify(nodeFsync)(rid); 8 | }; 9 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/fsyncSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { fsyncSync as nodeFsyncSync } from "fs"; 4 | 5 | export const fsyncSync: typeof Deno.fsyncSync = function fsyncSync(rid) { 6 | return nodeFsyncSync(rid); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/ftruncate.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { ftruncate as nodeftruncate } from "fs"; 4 | import { promisify } from "util"; 5 | 6 | const _ftruncate = promisify(nodeftruncate); 7 | 8 | export const ftruncate: typeof Deno.ftruncate = _ftruncate; 9 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/ftruncateSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { ftruncateSync as nodeftruncateSync } from "fs"; 4 | 5 | export const ftruncateSync: typeof Deno.ftruncateSync = nodeftruncateSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/gid.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import ps from "process"; 4 | 5 | export const gid: typeof Deno.gid = ps.getgid ?? (() => null); 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/hostname.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as os from "os"; 4 | 5 | export const hostname: typeof Deno.hostname = function hostname() { 6 | return os.hostname(); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/inspect.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as util from "util"; 4 | 5 | export const inspect: typeof Deno.inspect = (value, options = {}) => 6 | util.inspect(value, options); 7 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/kill.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import os from "os"; 4 | import ps from "process"; 5 | 6 | export const kill: typeof Deno.kill = function (pid, signo) { 7 | if (pid < 0 && os.platform() === "win32") { 8 | throw new TypeError("Invalid pid"); 9 | } 10 | ps.kill(pid, signo); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/link.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const link: typeof Deno.link = fs.link; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/linkSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const linkSync: typeof Deno.linkSync = fs.linkSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/listen.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { createServer, Server } from "net"; 4 | 5 | import { Conn } from "../../internal/Conn.js"; 6 | import { Listener } from "../../internal/Listener.js"; 7 | 8 | async function* _listen( 9 | server: Server, 10 | waitFor: Promise, 11 | ): AsyncIterableIterator { 12 | await waitFor; 13 | 14 | while (server.listening) { 15 | yield new Promise((resolve) => 16 | server.once("connection", (socket) => { 17 | socket.on("error", (err) => console.error(err)); 18 | 19 | // @ts-expect-error undocumented socket._handle property 20 | const rid: number = socket._handle.fd; 21 | 22 | const localAddr: Deno.Addr = { 23 | // cannot be undefined while socket is connected 24 | hostname: socket.localAddress!, 25 | port: socket.localPort!, 26 | transport: "tcp", 27 | }; 28 | 29 | const remoteAddr: Deno.Addr = { 30 | // cannot be undefined while socket is connected 31 | hostname: socket.remoteAddress!, 32 | port: socket.remotePort!, 33 | transport: "tcp", 34 | }; 35 | 36 | resolve(new Conn(rid, localAddr, remoteAddr)); 37 | }) 38 | ); 39 | } 40 | } 41 | 42 | export const listen: typeof Deno.listen = function listen(options) { 43 | if (options.transport === "unix") { 44 | throw new Error("Unstable UnixListenOptions is not implemented"); 45 | } 46 | const { port, hostname = "0.0.0.0", transport = "tcp" } = options; 47 | if (transport !== "tcp") { 48 | throw new Error("Deno.listen is only implemented for transport: tcp"); 49 | } 50 | 51 | const server = createServer(); 52 | 53 | const waitFor = new Promise((resolve) => 54 | // server._handle.fd is assigned immediately on .listen() 55 | server.listen(port, hostname, resolve) 56 | ); 57 | 58 | // @ts-expect-error undocumented socket._handle property 59 | const listener = new Listener(server._handle.fd, { 60 | hostname, 61 | port, 62 | transport: "tcp", 63 | }, _listen(server, waitFor)); 64 | 65 | return listener; 66 | }; 67 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/listenTls.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { createServer, Server } from "tls"; 4 | 5 | import { TlsConn } from "../../internal/Conn.js"; 6 | import { Listener } from "../../internal/Listener.js"; 7 | import { readTextFileSync } from "./readTextFileSync.js"; 8 | 9 | async function* _listen( 10 | server: Server, 11 | waitFor: Promise, 12 | ): AsyncIterableIterator { 13 | await waitFor; 14 | 15 | while (server.listening) { 16 | yield new Promise((resolve) => 17 | server.once("secureConnection", (socket) => { 18 | socket.on("error", (err) => console.error(err)); 19 | 20 | // @ts-expect-error undocumented socket._handle property 21 | const rid: number = socket._handle.fd; 22 | 23 | const localAddr: Deno.Addr = { 24 | // cannot be undefined while socket is connected 25 | hostname: socket.localAddress!, 26 | port: socket.localPort!, 27 | transport: "tcp", 28 | }; 29 | 30 | const remoteAddr: Deno.Addr = { 31 | // cannot be undefined while socket is connected 32 | hostname: socket.remoteAddress!, 33 | port: socket.remotePort!, 34 | transport: "tcp", 35 | }; 36 | 37 | resolve(new TlsConn(rid, localAddr, remoteAddr)); 38 | }) 39 | ); 40 | } 41 | } 42 | 43 | export const listenTls: typeof Deno.listenTls = function listen( 44 | { port, hostname = "0.0.0.0", transport = "tcp", certFile, keyFile }, 45 | ) { 46 | if (transport !== "tcp") { 47 | throw new Error("Deno.listen is only implemented for transport: tcp"); 48 | } 49 | 50 | const [cert, key] = [certFile, keyFile].map((f) => 51 | f == null ? undefined : readTextFileSync(f) 52 | ); 53 | 54 | const server = createServer({ cert, key }); 55 | 56 | const waitFor = new Promise((resolve) => 57 | // server._handle.fd is assigned immediately on .listen() 58 | server.listen(port, hostname, resolve) 59 | ); 60 | 61 | // @ts-expect-error undocumented socket._handle property 62 | const listener = new Listener(server._handle.fd, { 63 | hostname, 64 | port, 65 | transport: "tcp", 66 | }, _listen(server, waitFor)); 67 | 68 | return listener; 69 | }; 70 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/loadavg.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as os from "os"; 4 | 5 | export const loadavg: typeof Deno.loadavg = function loadavg() { 6 | return os.loadavg(); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/lstat.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | import { denoifyFileInfo } from "./stat.js"; 5 | import mapError from "../../internal/errorMap.js"; 6 | 7 | export const lstat: typeof Deno.lstat = async (path) => { 8 | try { 9 | return denoifyFileInfo(await fs.lstat(path)); 10 | } catch (e) { 11 | throw mapError(e); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/lstatSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import { denoifyFileInfo } from "./stat.js"; 5 | import mapError from "../../internal/errorMap.js"; 6 | 7 | export const lstatSync: typeof Deno.lstatSync = (path) => { 8 | try { 9 | return denoifyFileInfo(fs.lstatSync(path)); 10 | } catch (err) { 11 | throw mapError(err); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/makeTempDir.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { mkdtemp } from "fs/promises"; 4 | import { join } from "path"; 5 | import { tmpdir } from "os"; 6 | 7 | export const makeTempDir: typeof Deno.makeTempDir = function makeTempDir( 8 | { prefix = "" } = {}, 9 | ) { 10 | return mkdtemp(join(tmpdir(), prefix || "/")); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/makeTempDirSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { mkdtempSync } from "fs"; 4 | import { join } from "path"; 5 | import { tmpdir } from "os"; 6 | 7 | export const makeTempDirSync: typeof Deno.makeTempDirSync = 8 | function makeTempDirSync( 9 | { prefix = "" } = {}, 10 | ) { 11 | return mkdtempSync(join(tmpdir(), prefix || "/")); 12 | }; 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/makeTempFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { tmpdir } from "os"; 4 | import { join } from "path"; 5 | import { randomId } from "../../internal/random_id.js"; 6 | import { writeTextFile } from "./writeTextFile.js"; 7 | 8 | export const makeTempFile: typeof Deno.makeTempFile = 9 | async function makeTempFile( 10 | { prefix = "" } = {}, 11 | ) { 12 | const name = join(tmpdir(), prefix, randomId()); 13 | await writeTextFile(name, ""); 14 | return name; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/makeTempFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { tmpdir } from "os"; 4 | import { join } from "path"; 5 | import { randomId } from "../../internal/random_id.js"; 6 | import { writeTextFileSync } from "./writeTextFileSync.js"; 7 | 8 | export const makeTempFileSync: typeof Deno.makeTempFileSync = 9 | function makeTempFileSync( 10 | { prefix = "" } = {}, 11 | ) { 12 | const name = join(tmpdir(), prefix, randomId()); 13 | writeTextFileSync(name, ""); 14 | return name; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/memoryUsage.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const memoryUsage: typeof Deno.memoryUsage = process.memoryUsage; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/mkdir.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { mkdir as nodeMkdir } from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import { errors } from "../variables.js"; 6 | 7 | export const mkdir: typeof Deno.mkdir = async function mkdir(path, options) { 8 | try { 9 | await nodeMkdir(path, options); 10 | } catch (error: any) { 11 | if (error?.code === "EEXIST") { 12 | throw new errors.AlreadyExists( 13 | `File exists (os error 17), mkdir '${path}'`, 14 | ); 15 | } 16 | throw mapError(error); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/mkdirSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import { errors } from "../variables.js"; 6 | 7 | export const mkdirSync: typeof Deno.mkdirSync = (path, options) => { 8 | try { 9 | fs.mkdirSync(path, options); 10 | } catch (error: any) { 11 | if (error?.code === "EEXIST") { 12 | throw new errors.AlreadyExists( 13 | `File exists (os error 17), mkdir '${path}'`, 14 | ); 15 | } 16 | throw mapError(error); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/open.test.ts: -------------------------------------------------------------------------------- 1 | import { open } from "./open.ts"; 2 | import assert from "assert/strict"; 3 | import path from "path"; 4 | 5 | const withTempDir = 6 | (test: (tempDirPath: string) => Promise) => async () => { 7 | const tempDirPath = await Deno.makeTempDir(); 8 | try { 9 | await test(tempDirPath); 10 | } finally { 11 | await Deno.remove(tempDirPath, { recursive: true }); 12 | } 13 | }; 14 | 15 | Deno.test( 16 | "creates file when createNew is set to true and file does not exist", 17 | withTempDir(async (tempDirPath) => { 18 | const filePath = path.join(tempDirPath, "some"); 19 | 20 | const fileHandle = await open(filePath, { createNew: true, write: true }); 21 | fileHandle.close(); 22 | 23 | assert.ok(await Deno.stat(filePath)); 24 | }), 25 | ); 26 | 27 | Deno.test( 28 | "errors when createNew is set to true and file exists", 29 | withTempDir(async (tempDirPath) => { 30 | const testFile = await Deno.makeTempFile({ dir: tempDirPath }); 31 | 32 | await assert.rejects( 33 | open(testFile, { createNew: true, write: true }), 34 | { message: `EEXIST: file already exists, open '${testFile}'` }, 35 | ); 36 | }), 37 | ); 38 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/open.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { open as _open } from "fs"; 4 | import { promisify } from "util"; 5 | 6 | import { File } from "../classes/FsFile.js"; 7 | import { getFsFlag } from "../../internal/fs_flags.js"; 8 | import mapError from "../../internal/errorMap.js"; 9 | 10 | const nodeOpen = promisify(_open); 11 | 12 | export const open: typeof Deno.open = async function open( 13 | path, 14 | { read, write, append, truncate, create, createNew, mode = 0o666 } = { 15 | read: true, 16 | }, 17 | ) { 18 | const flagMode = getFsFlag({ 19 | read, 20 | write, 21 | append, 22 | truncate, 23 | create, 24 | createNew, 25 | }); 26 | try { 27 | const fd = await nodeOpen(path, flagMode, mode); 28 | return new File(fd); 29 | } catch (err) { 30 | throw mapError(err); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/openSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { openSync as nodeOpenSync } from "fs"; 4 | 5 | import { File } from "../classes/FsFile.js"; 6 | import { getFsFlag } from "../../internal/fs_flags.js"; 7 | import mapError from "../../internal/errorMap.js"; 8 | 9 | export const openSync: typeof Deno.openSync = function openSync( 10 | path, 11 | { read, write, append, truncate, create, createNew, mode = 0o666 } = { 12 | read: true, 13 | }, 14 | ) { 15 | const flagMode = getFsFlag({ 16 | read, 17 | write, 18 | append, 19 | truncate, 20 | create, 21 | createNew, 22 | }); 23 | try { 24 | const fd = nodeOpenSync(path, flagMode, mode); 25 | return new File(fd); 26 | } catch (err) { 27 | throw mapError(err); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/osRelease.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { release } from "os"; 4 | 5 | export const osRelease: typeof Deno.osRelease = function osRelease() { 6 | return release(); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/osUptime.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { uptime } from "os"; 4 | 5 | export const osUptime: typeof Deno.osUptime = function osUptime() { 6 | return uptime(); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/read.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { promisify } from "util"; 4 | import { read as nodeRead } from "fs"; 5 | 6 | const _read = promisify(nodeRead); 7 | 8 | export const read: typeof Deno.read = async function read(rid, buffer) { 9 | if (buffer == null) { 10 | throw new TypeError("Buffer must not be null."); 11 | } 12 | if (buffer.length === 0) { 13 | return 0; 14 | } 15 | 16 | const { bytesRead } = await _read(rid, buffer, 0, buffer.length, null); 17 | // node returns 0 on EOF, Deno expects null 18 | return bytesRead === 0 ? null : bytesRead; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readDir.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { opendir } from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readDir: typeof Deno.readDir = async function* readDir(path) { 7 | try { 8 | for await (const e of await opendir(String(path))) { 9 | const ent: Deno.DirEntry = { 10 | name: e.name, 11 | isFile: e.isFile(), 12 | isDirectory: e.isDirectory(), 13 | isSymlink: e.isSymbolicLink(), 14 | }; 15 | yield ent; 16 | } 17 | } catch (e) { 18 | throw mapError(e); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readDirSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { readdirSync as nodeReadDir } from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readDirSync: typeof Deno.readDirSync = function* readDir(path) { 7 | try { 8 | for (const e of nodeReadDir(String(path), { withFileTypes: true })) { 9 | const ent: Deno.DirEntry = { 10 | name: e.name, 11 | isFile: e.isFile(), 12 | isDirectory: e.isDirectory(), 13 | isSymlink: e.isSymbolicLink(), 14 | }; 15 | yield ent; 16 | } 17 | } catch (e) { 18 | throw mapError(e); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { readFile as nodeReadFile } from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readFile: typeof Deno.readFile = async function readFile( 7 | path, 8 | { signal } = {}, 9 | ) { 10 | try { 11 | const buf = await nodeReadFile(path, { signal }); 12 | return new Uint8Array(buf.buffer, buf.byteOffset, buf.length); 13 | } catch (e) { 14 | throw mapError(e); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { readFileSync as nodeReadFile } from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readFileSync: typeof Deno.readFileSync = function readFileSync( 7 | path, 8 | ) { 9 | try { 10 | const buf = nodeReadFile(path); 11 | return new Uint8Array(buf.buffer, buf.byteOffset, buf.length); 12 | } catch (e) { 13 | throw mapError(e); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readLink.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const readLink: typeof Deno.readLink = fs.readlink; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readLinkSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const readLinkSync: typeof Deno.readLinkSync = fs.readlinkSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const readSync: typeof Deno.readSync = (fd, buffer) => { 6 | const bytesRead = fs.readSync(fd, buffer); 7 | // node returns 0 on EOF, Deno expects null 8 | return bytesRead === 0 ? null : bytesRead; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readTextFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { readFile } from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readTextFile: typeof Deno.readTextFile = async ( 7 | path, 8 | { signal } = {}, 9 | ) => { 10 | try { 11 | return await readFile(path, { encoding: "utf8", signal }); 12 | } catch (e) { 13 | throw mapError(e); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/readTextFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const readTextFileSync: typeof Deno.readTextFileSync = function (path) { 7 | try { 8 | return fs.readFileSync(path, "utf8"); 9 | } catch (e) { 10 | throw mapError(e); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/realPath.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const realPath: typeof Deno.realPath = fs.realpath; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/realPathSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const realPathSync: typeof Deno.realPathSync = fs.realpathSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/remove.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { rm, rmdir } from "fs/promises"; 4 | 5 | export const remove: typeof Deno.remove = async function remove( 6 | path, 7 | options = {}, 8 | ) { 9 | const innerOptions = options.recursive 10 | ? { recursive: true, force: true } 11 | : {}; 12 | try { 13 | return await rm(path, innerOptions); 14 | } catch (err) { 15 | if ((err as any).code === "ERR_FS_EISDIR") { 16 | return await rmdir(path, innerOptions); 17 | } else { 18 | throw err; 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/removeSignalListener.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import ps from "process"; 4 | 5 | export const removeSignalListener: typeof Deno.removeSignalListener = ( 6 | signal, 7 | handler, 8 | ) => { 9 | ps.removeListener(signal, handler); 10 | }; 11 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/removeSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const removeSync: typeof Deno.removeSync = (path, options = {}) => { 6 | const innerOptions = options.recursive 7 | ? { recursive: true, force: true } 8 | : {}; 9 | try { 10 | fs.rmSync(path, innerOptions); 11 | } catch (err) { 12 | if ((err as any).code === "ERR_FS_EISDIR") { 13 | fs.rmdirSync(path, innerOptions); 14 | } else { 15 | throw err; 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/rename.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { rename as nodeRename } from "fs/promises"; 4 | 5 | export const rename: typeof Deno.rename = function rename(oldpath, newpath) { 6 | return nodeRename(oldpath, newpath); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/renameSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const renameSync: typeof Deno.renameSync = fs.renameSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/resolveDns.test.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert/strict"; 2 | import { resolveDns } from "./resolveDns.js"; 3 | 4 | Deno.test("resolve A as ipV4 string", async () => { 5 | const ips = await resolveDns("www.github.com", "A"); 6 | assert(ips[0].match(/(\d+\.){3}\d+/), "Must be a IP v4"); 7 | }); 8 | 9 | Deno.test("resolve A as ipV6 string", async () => { 10 | const ips = await resolveDns("www.google.com", "AAAA"); 11 | assert(ips[0].match(/[0-9a-f]{1,4}:[0-9a-f:]+/), "Must be a IP v6"); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/resolveDns.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import dns from "dns"; 4 | 5 | export const resolveDns: typeof Deno.resolveDns = function resolveDns( 6 | query, 7 | recordType, 8 | options, 9 | ): Promise { 10 | if (options) { 11 | throw Error(`resolveDns option not implemnted yet`); 12 | } 13 | switch (recordType) { 14 | case "A": 15 | /* falls through */ 16 | case "AAAA": 17 | case "CNAME": 18 | case "NS": 19 | case "PTR": 20 | return new Promise((resolve, reject) => { 21 | dns.resolve(query, recordType, (err, addresses) => { 22 | if (err) { 23 | reject(err); 24 | } else { 25 | resolve(addresses as string[]); 26 | } 27 | }); 28 | }); 29 | case "ANAME": 30 | case "CAA": 31 | case "MX": 32 | case "NAPTR": 33 | case "SOA": 34 | case "SRV": 35 | case "TXT": 36 | default: 37 | throw Error(`resolveDns type ${recordType} not implemnted yet`); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/run.test.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert/strict"; 2 | import { run } from "./run.js"; 3 | 4 | Deno.test("error when cwd doesn't exist", () => { 5 | assert.throws(() => { 6 | run({ 7 | cmd: ["echo"], 8 | cwd: "non-existent-directory", 9 | }); 10 | }, { message: "The directory name is invalid." }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/run.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import childProcess from "child_process"; 4 | import fs from "fs"; 5 | import os from "os"; 6 | import url from "url"; 7 | import { once } from "events"; 8 | import which from "which"; 9 | 10 | import { BufferStreamReader, StreamWriter } from "../../internal/streams.js"; 11 | import * as errors from "../variables/errors.js"; 12 | import { RunOptions } from "../types.js"; 13 | 14 | type SignalName = keyof typeof os.constants.signals; 15 | 16 | export type UnstableRunOptions = RunOptions & { 17 | clearEnv?: boolean; 18 | gid?: number; 19 | uid?: number; 20 | }; 21 | 22 | export const run: typeof Deno.run = function run< 23 | T extends UnstableRunOptions = UnstableRunOptions, 24 | >(options: T) { 25 | const [cmd, ...args] = options.cmd; 26 | 27 | if (options.cwd && !fs.existsSync(options.cwd)) { 28 | throw new Error("The directory name is invalid."); 29 | } 30 | 31 | // childProcess.spawn will asynchronously check if the command exists, but 32 | // we need to do this synchronously 33 | const commandName = getCmd(cmd); 34 | if (!which.sync(commandName, { nothrow: true })) { 35 | throw new errors.NotFound("The system cannot find the file specified."); 36 | } 37 | 38 | const process = childProcess.spawn(commandName, args as string[], { 39 | cwd: options.cwd, 40 | env: getEnv(options), 41 | uid: options.uid, 42 | gid: options.gid, 43 | shell: false, 44 | stdio: [ 45 | getStdio(options.stdin, "in"), 46 | getStdio(options.stdout, "out"), 47 | getStdio(options.stderr, "out"), 48 | ], 49 | }); 50 | return new Process(process); 51 | }; 52 | 53 | function getStdio( 54 | value: Deno.RunOptions["stdout"] | undefined, 55 | kind: "in" | "out", 56 | ): childProcess.StdioPipe | childProcess.StdioNull { 57 | if (value === "inherit" || value == null) { 58 | return "inherit" as const; // default 59 | } else if (value === "piped") { 60 | return "pipe" as const; 61 | } else if (value === "null") { 62 | return "ignore" as const; 63 | } else if (typeof value === "number") { 64 | switch (kind) { 65 | case "in": 66 | return fs.createReadStream(null as any, { fd: value }); 67 | case "out": 68 | return fs.createWriteStream(null as any, { fd: value }); 69 | default: { 70 | const _assertNever: never = kind; 71 | throw new Error("Unreachable."); 72 | } 73 | } 74 | } else { 75 | const _assertNever: never = value; 76 | throw new Error("Unknown value."); 77 | } 78 | } 79 | 80 | function getCmd(firstArg: string | URL) { 81 | if (firstArg instanceof URL) { 82 | return url.fileURLToPath(firstArg); 83 | } else { 84 | return firstArg; 85 | } 86 | } 87 | 88 | function getEnv(options: UnstableRunOptions) { 89 | const env = options.env ?? {}; 90 | for (const name in process.env) { 91 | if (!Object.prototype.hasOwnProperty.call(env, name)) { 92 | if (options.clearEnv) { 93 | if (os.platform() === "win32") { 94 | env[name] = ""; 95 | } else { 96 | delete env[name]; 97 | } 98 | } else { 99 | env[name] = process.env[name]!; 100 | } 101 | } 102 | } 103 | return env; 104 | } 105 | 106 | export class Process 107 | implements Deno.Process { 108 | readonly #process: childProcess.ChildProcess; 109 | readonly #stderr: ProcessReadStream | null; 110 | readonly #stdout: ProcessReadStream | null; 111 | readonly #stdin: ProcessWriteStream | null; 112 | readonly #status; 113 | #receivedStatus = false; 114 | 115 | /** @internal */ 116 | constructor(process: childProcess.ChildProcess) { 117 | this.#process = process; 118 | this.#stdout = ProcessReadStream.fromNullable(this.#process.stdout) ?? null; 119 | this.#stderr = ProcessReadStream.fromNullable(this.#process.stderr) ?? null; 120 | this.#stdin = ProcessWriteStream.fromNullable(this.#process.stdin) ?? null; 121 | this.#status = once(process, "exit"); 122 | } 123 | 124 | get rid(): number { 125 | // todo: useful to return something? 126 | return NaN; 127 | } 128 | 129 | get pid(): number { 130 | // only undefined when the process doesn't spawn, in which case this 131 | // will never be reached 132 | return this.#process.pid!; 133 | } 134 | 135 | get stdin() { 136 | return this.#stdin as Deno.Process["stdin"]; 137 | } 138 | 139 | get stdout() { 140 | return this.#stdout as Deno.Process["stdout"]; 141 | } 142 | 143 | get stderr() { 144 | return this.#stderr as Deno.Process["stderr"]; 145 | } 146 | 147 | async status() { 148 | const [receivedCode, signalName] = await this.#status as [ 149 | number, 150 | SignalName | null, 151 | ]; 152 | // when there is a signal, the exit code is 128 + signal code 153 | const signal = signalName 154 | ? os.constants.signals[signalName] 155 | : receivedCode > 128 156 | ? receivedCode - 128 157 | : undefined; 158 | const code = receivedCode != null 159 | ? receivedCode 160 | : signal != null 161 | ? 128 + signal 162 | : undefined; 163 | const success = code === 0; 164 | this.#receivedStatus = true; 165 | return { code, signal, success } as Deno.ProcessStatus; 166 | } 167 | 168 | async output(): Promise { 169 | if (!this.#stdout) { 170 | throw new TypeError("stdout was not piped"); 171 | } 172 | const result = await this.#stdout.readAll(); 173 | this.#stdout.close(); 174 | return result; 175 | } 176 | 177 | async stderrOutput(): Promise { 178 | if (!this.#stderr) { 179 | throw new TypeError("stderr was not piped"); 180 | } 181 | const result = await this.#stderr.readAll(); 182 | this.#stderr.close(); 183 | return result; 184 | } 185 | 186 | close() { 187 | // Deno doesn't close any stdio streams here 188 | this.#process.unref(); 189 | this.#process.kill(); 190 | } 191 | 192 | kill(signo = "SIGTERM") { 193 | if (this.#receivedStatus) { 194 | throw new errors.NotFound("entity not found"); 195 | } 196 | 197 | this.#process.kill(signo as NodeJS.Signals); 198 | } 199 | } 200 | 201 | class ProcessReadStream implements Deno.Reader, Deno.Closer { 202 | readonly #stream: NonNullable; 203 | readonly #bufferStreamReader: BufferStreamReader; 204 | #closed = false; 205 | 206 | constructor(stream: NonNullable) { 207 | this.#stream = stream; 208 | this.#bufferStreamReader = new BufferStreamReader(stream); 209 | } 210 | 211 | static fromNullable(stream: childProcess.ChildProcess["stdout"]) { 212 | return stream ? new ProcessReadStream(stream) : undefined; 213 | } 214 | 215 | readAll() { 216 | if (this.#closed) { 217 | return Promise.resolve(new Uint8Array(0)); 218 | } else { 219 | return this.#bufferStreamReader.readAll(); 220 | } 221 | } 222 | 223 | read(p: Uint8Array) { 224 | if (this.#closed) { 225 | return Promise.resolve(null); 226 | } else { 227 | return this.#bufferStreamReader.read(p); 228 | } 229 | } 230 | 231 | close() { 232 | this.#closed = true; 233 | this.#stream.destroy(); 234 | } 235 | 236 | get readable(): ReadableStream { 237 | throw new Error("Not implemented."); 238 | } 239 | 240 | get writable(): WritableStream { 241 | throw new Error("Not implemented."); 242 | } 243 | } 244 | 245 | class ProcessWriteStream implements Deno.Writer, Deno.Closer { 246 | readonly #stream: NonNullable; 247 | readonly #streamWriter: StreamWriter; 248 | #closed = false; 249 | 250 | constructor(stream: NonNullable) { 251 | this.#stream = stream; 252 | this.#streamWriter = new StreamWriter(stream); 253 | } 254 | 255 | static fromNullable(stream: childProcess.ChildProcess["stdin"]) { 256 | return stream ? new ProcessWriteStream(stream) : undefined; 257 | } 258 | 259 | write(p: Uint8Array): Promise { 260 | if (this.#closed) { 261 | return Promise.resolve(0); 262 | } else { 263 | return this.#streamWriter.write(p); 264 | } 265 | } 266 | 267 | close() { 268 | this.#closed = true; 269 | this.#stream.end(); 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/shutdown.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { Socket } from "net"; 4 | 5 | export const shutdown: typeof Deno.shutdown = async function shutdown(rid) { 6 | await new Promise((resolve) => new Socket({ fd: rid }).end(resolve)); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/stat.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { stat as nodeStat } from "fs/promises"; 4 | import type { Stats } from "fs"; 5 | import * as os from "os"; 6 | import mapError from "../../internal/errorMap.js"; 7 | 8 | const isWindows = os.platform() === "win32"; 9 | 10 | export function denoifyFileInfo(s: Stats): Deno.FileInfo { 11 | return { 12 | atime: s.atime, 13 | birthtime: s.birthtime, 14 | blksize: isWindows ? null : s.blksize, 15 | blocks: isWindows ? null : s.blocks, 16 | dev: s.dev, 17 | gid: isWindows ? null : s.gid, 18 | ino: isWindows ? null : s.ino, 19 | isDirectory: s.isDirectory(), 20 | isFile: s.isFile(), 21 | isSymlink: s.isSymbolicLink(), 22 | isBlockDevice: isWindows ? null : s.isBlockDevice(), 23 | isCharDevice: isWindows ? null : s.isCharacterDevice(), 24 | isFifo: isWindows ? null : s.isFIFO(), 25 | isSocket: isWindows ? null : s.isSocket(), 26 | mode: isWindows ? null : s.mode, 27 | mtime: s.mtime, 28 | nlink: isWindows ? null : s.nlink, 29 | rdev: isWindows ? null : s.rdev, 30 | size: s.size, 31 | uid: isWindows ? null : s.uid, 32 | }; 33 | } 34 | 35 | export const stat: typeof Deno.stat = async (path) => { 36 | try { 37 | return denoifyFileInfo(await nodeStat(path)); 38 | } catch (e) { 39 | throw mapError(e); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/statSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import { denoifyFileInfo } from "./stat.js"; 5 | import mapError from "../../internal/errorMap.js"; 6 | 7 | export const statSync: typeof Deno.statSync = (path) => { 8 | try { 9 | return denoifyFileInfo(fs.statSync(path)); 10 | } catch (err) { 11 | throw mapError(err); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/symlink.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | export const symlink: typeof Deno.symlink = async ( 6 | oldpath, 7 | newpath, 8 | options?, 9 | ) => await fs.symlink(oldpath, newpath, options?.type); 10 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/symlinkSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const symlinkSync: typeof Deno.symlinkSync = ( 6 | oldpath, 7 | newpath, 8 | options?, 9 | ) => fs.symlinkSync(oldpath, newpath, options?.type); 10 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/test.ts: -------------------------------------------------------------------------------- 1 | export { test } from "@deno/shim-deno-test"; 2 | export type { 3 | TestContext, 4 | TestDefinition, 5 | TestStepDefinition, 6 | } from "@deno/shim-deno-test"; 7 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/truncate.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | 5 | import mapError from "../../internal/errorMap.js"; 6 | import { errors } from "../variables.js"; 7 | 8 | export const truncate: typeof Deno.truncate = async (name, len) => { 9 | try { 10 | return await fs.truncate(name, len); 11 | } catch (error: any) { 12 | if (error?.code === "ENOENT") { 13 | throw new errors.NotFound( 14 | `No such file or directory (os error 2), truncate '${name}'`, 15 | ); 16 | } 17 | throw mapError(error); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/truncateSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | import mapError from "../../internal/errorMap.js"; 6 | import { errors } from "../variables.js"; 7 | 8 | export const truncateSync: typeof Deno.truncateSync = (name, len) => { 9 | try { 10 | return fs.truncateSync(name, len); 11 | } catch (error: any) { 12 | if (error?.code === "ENOENT") { 13 | throw new errors.NotFound( 14 | `No such file or directory (os error 2), truncate '${name}'`, 15 | ); 16 | } 17 | throw mapError(error); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/uid.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import ps from "process"; 4 | 5 | export const uid: typeof Deno.uid = ps.getuid ?? (() => null); 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/watchFs.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { watch } from "fs/promises"; 4 | import { resolve } from "path"; 5 | 6 | import { filterAsync, mapAsync, merge } from "../../internal/iterutil.js"; 7 | 8 | export const watchFs: typeof Deno.watchFs = function watchFs( 9 | paths, 10 | options = { recursive: true }, 11 | ) { 12 | paths = Array.isArray(paths) ? paths : [paths]; 13 | 14 | const ac = new AbortController(); 15 | const { signal } = ac; 16 | 17 | // TODO(mkr): create valid rids for watchers 18 | const rid = -1; 19 | 20 | const masterWatcher = merge( 21 | paths.map((path) => 22 | mapAsync( 23 | filterAsync( 24 | watch(path, { recursive: options?.recursive, signal }), 25 | (info) => info.filename != null, 26 | ), 27 | (info) => ({ 28 | kind: "modify" as const, 29 | paths: [resolve(path, info.filename!)], 30 | }), 31 | ) 32 | ), 33 | ); 34 | 35 | function close() { 36 | ac.abort(); 37 | } 38 | 39 | return Object.assign(masterWatcher, { 40 | rid, 41 | close, 42 | [Symbol.dispose]: close, 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/write.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import { promisify } from "util"; 5 | 6 | const nodeWrite = promisify(fs.write); 7 | 8 | export const write: typeof Deno.write = async (fd, data) => { 9 | const { bytesWritten } = await nodeWrite(fd, data); 10 | return bytesWritten; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/writeFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import { getFsFlag } from "../../internal/fs_flags.js"; 6 | 7 | export const writeFile: typeof Deno.writeFile = async function writeFile( 8 | path, 9 | data, 10 | { append = false, create = true, createNew = false, mode, signal } = {}, 11 | ) { 12 | const truncate = create && !append; 13 | const flag = getFsFlag({ append, create, createNew, truncate, write: true }); 14 | try { 15 | await fs.writeFile(path, data, { flag, signal }); 16 | if (mode != null) await fs.chmod(path, mode); 17 | } catch (error) { 18 | throw mapError(error); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/writeFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { platform } from "os"; 4 | import { openSync } from "./openSync.js"; 5 | import mapError from "../../internal/errorMap.js"; 6 | import { statSync } from "./statSync.js"; 7 | import { chmodSync } from "./chmodSync.js"; 8 | 9 | export const writeFileSync: typeof Deno.writeFileSync = function writeFileSync( 10 | path, 11 | data, 12 | options = {}, 13 | ) { 14 | try { 15 | if (options.create !== undefined) { 16 | const create = !!options.create; 17 | if (!create) { 18 | // verify that file exists 19 | statSync(path); 20 | } 21 | } 22 | 23 | const openOptions = { 24 | write: true, 25 | create: true, 26 | createNew: options.createNew, 27 | append: !!options.append, 28 | truncate: !options.append, 29 | }; 30 | const file = openSync(path, openOptions); 31 | 32 | if ( 33 | options.mode !== undefined && 34 | options.mode !== null && 35 | platform() !== "win32" 36 | ) { 37 | chmodSync(path, options.mode); 38 | } 39 | 40 | let nwritten = 0; 41 | while (nwritten < data.length) { 42 | nwritten += file.writeSync(data.subarray(nwritten)); 43 | } 44 | 45 | file.close(); 46 | } catch (e) { 47 | throw mapError(e); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/writeSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | 5 | export const writeSync: typeof Deno.writeSync = fs.writeSync; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/writeTextFile.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs/promises"; 4 | import mapError from "../../internal/errorMap.js"; 5 | import { getFsFlag } from "../../internal/fs_flags.js"; 6 | 7 | export const writeTextFile: typeof Deno.writeTextFile = 8 | async function writeTextFile( 9 | path, 10 | data, 11 | { append = false, create = true, createNew = false, mode, signal } = {}, 12 | ) { 13 | const truncate = create && !append; 14 | const flag = getFsFlag({ 15 | append, 16 | create, 17 | createNew, 18 | truncate, 19 | write: true, 20 | }); 21 | try { 22 | await fs.writeFile(path, data, { flag, mode, signal }); 23 | if (mode !== undefined) await fs.chmod(path, mode); 24 | } catch (error) { 25 | throw mapError(error); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/functions/writeTextFileSync.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as fs from "fs"; 4 | import mapError from "../../internal/errorMap.js"; 5 | 6 | export const writeTextFileSync: typeof Deno.writeTextFileSync = ( 7 | path, 8 | data, 9 | { append = false, create = true, mode } = {}, 10 | ) => { 11 | const flag = create ? (append ? "a" : "w") : "r+"; 12 | try { 13 | fs.writeFileSync(path, data, { flag, mode }); 14 | if (mode !== undefined) fs.chmodSync(path, mode); 15 | } catch (error) { 16 | throw mapError(error); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/main.ts: -------------------------------------------------------------------------------- 1 | export * from "./classes.js"; 2 | export * from "./enums.js"; 3 | export * from "./functions.js"; 4 | export * from "./types.js"; 5 | export * from "./variables.js"; 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/types.js: -------------------------------------------------------------------------------- 1 | // this file prevents ts-node from trying to emit runtime code for types.ts 2 | export {}; 3 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/types.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export type Addr = Deno.Addr; 3 | export type Closer = Deno.Closer; 4 | export type Conn = Deno.Conn; 5 | export type ConnectOptions = Deno.ConnectOptions; 6 | export type ConnectTlsOptions = Deno.ConnectTlsOptions; 7 | export type DenoTest = Deno.DenoTest; 8 | export type DirEntry = Deno.DirEntry; 9 | export type EnvPermissionDescriptor = Deno.EnvPermissionDescriptor; 10 | export type FfiPermissionDescriptor = Deno.FfiPermissionDescriptor; 11 | export type SysPermissionDescriptor = Deno.SysPermissionDescriptor; 12 | export type Env = Deno.Env; 13 | export type FileInfo = Deno.FileInfo; 14 | export type FsEvent = Deno.FsEvent; 15 | export type FsEventFlag = Deno.FsEventFlag; 16 | export type FsWatcher = Deno.FsWatcher; 17 | export type HrtimePermissionDescriptor = Deno.HrtimePermissionDescriptor; 18 | export type InspectOptions = Deno.InspectOptions; 19 | export type Listener = Deno.Listener; 20 | export type ListenOptions = Deno.ListenOptions; 21 | export type ListenTlsOptions = Deno.ListenTlsOptions; 22 | export type MakeTempOptions = Deno.MakeTempOptions; 23 | export type MemoryUsage = Deno.MemoryUsage; 24 | export type Metrics = Deno.Metrics; 25 | export type MkdirOptions = Deno.MkdirOptions; 26 | export type NetAddr = Deno.NetAddr; 27 | export type NetPermissionDescriptor = Deno.NetPermissionDescriptor; 28 | export type OpenOptions = Deno.OpenOptions; 29 | export type OpMetrics = Deno.OpMetrics; 30 | export type PermissionDescriptor = Deno.PermissionDescriptor; 31 | export type PermissionName = Deno.PermissionName; 32 | export type PermissionOptions = Deno.PermissionOptions; 33 | export type PermissionOptionsObject = Deno.PermissionOptionsObject; 34 | export type PermissionState = Deno.PermissionState; 35 | export type PermissionStatusEventMap = Deno.PermissionStatusEventMap; 36 | export type ProcessStatus = Deno.ProcessStatus; 37 | export type Reader = Deno.Reader; 38 | export type ReaderSync = Deno.ReaderSync; 39 | export type ReadFileOptions = Deno.ReadFileOptions; 40 | export type ReadPermissionDescriptor = Deno.ReadPermissionDescriptor; 41 | export type RemoveOptions = Deno.RemoveOptions; 42 | export type ResourceMap = Deno.ResourceMap; 43 | export type RunOptions = Deno.RunOptions; 44 | export type RunPermissionDescriptor = Deno.RunPermissionDescriptor; 45 | export type Seeker = Deno.Seeker; 46 | export type SeekerSync = Deno.SeekerSync; 47 | export type SetRawOptions = Deno.SetRawOptions; 48 | export type Signal = Deno.Signal; 49 | export type SymlinkOptions = Deno.SymlinkOptions; 50 | export type TestDefinition = Deno.TestDefinition; 51 | export type TestStepDefinition = Deno.TestStepDefinition; 52 | export type TestContext = Deno.TestContext; 53 | export type TcpConn = Deno.TcpConn; 54 | export type TcpListenOptions = Deno.TcpListenOptions; 55 | export type TlsConn = Deno.TlsConn; 56 | export type TlsHandshakeInfo = Deno.TlsHandshakeInfo; 57 | export type TlsListener = Deno.TlsListener; 58 | export type UnixAddr = Deno.UnixAddr; 59 | export type UnixConn = Deno.UnixConn; 60 | export type UnixConnectOptions = Deno.UnixConnectOptions; 61 | export type UnixListenOptions = Deno.UnixListenOptions; 62 | export type WriteFileOptions = Deno.WriteFileOptions; 63 | export type WritePermissionDescriptor = Deno.WritePermissionDescriptor; 64 | export type Writer = Deno.Writer; 65 | export type WriterSync = Deno.WriterSync; 66 | 67 | export type CAARecord = Deno.CAARecord; 68 | export type MXRecord = Deno.MXRecord; 69 | export type NAPTRRecord = Deno.NAPTRRecord; 70 | export type ResolveDnsOptions = Deno.ResolveDnsOptions; 71 | export type SOARecord = Deno.SOARecord; 72 | export type SRVRecord = Deno.SRVRecord; 73 | export type RecordType = Deno.RecordType; 74 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables.ts: -------------------------------------------------------------------------------- 1 | export { build } from "./variables/build.js"; 2 | export { customInspect } from "./variables/customInspect.js"; 3 | export { env } from "./variables/env.js"; 4 | export * as errors from "./variables/errors.js"; 5 | export { mainModule } from "./variables/mainModule.js"; 6 | export { metrics } from "./variables/metrics.js"; 7 | export { noColor } from "./variables/noColor.js"; 8 | export { permissions } from "./variables/permissions.js"; 9 | export { pid } from "./variables/pid.js"; 10 | export { ppid } from "./variables/ppid.js"; 11 | export { resources } from "./variables/resources.js"; 12 | export * from "./variables/std.js"; 13 | export { version } from "./variables/version.js"; 14 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/args.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const args: typeof Deno.args = process.argv.slice(2); 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/build.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import * as os from "os"; 4 | 5 | const arch = process.arch === "arm64" ? "aarch64" : "x86_64"; 6 | export const build: typeof Deno.build = { 7 | arch, 8 | os: ((p) => p === "win32" ? "windows" : p === "darwin" ? "darwin" : "linux")( 9 | os.platform(), 10 | ), 11 | vendor: "pc", 12 | target: 13 | ((p) => 14 | p === "win32" 15 | ? `${arch}-pc-windows-msvc` 16 | : p === "darwin" 17 | ? `${arch}-apple-darwin` 18 | : `${arch}-unknown-linux-gnu`)(os.platform()), 19 | }; 20 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/customInspect.ts: -------------------------------------------------------------------------------- 1 | export const customInspect = Symbol.for("nodejs.util.inspect.custom"); 2 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/env.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const env: typeof Deno.env = { 4 | get(key) { 5 | assertValidKey(key); 6 | return process.env[key]; 7 | }, 8 | set(key, value) { 9 | assertValidKey(key); 10 | assertValidValue(value); 11 | process.env[key] = value; 12 | }, 13 | has(key) { 14 | assertValidKey(key); 15 | return key in process.env; 16 | }, 17 | delete(key) { 18 | assertValidKey(key); 19 | delete process.env[key]; 20 | }, 21 | // @ts-expect-error https://github.com/denoland/deno/issues/10267 22 | toObject() { 23 | return { ...process.env }; 24 | }, 25 | }; 26 | 27 | const invalidKeyChars = ["=", "\0"].map((c) => c.charCodeAt(0)); 28 | const invalidValueChar = "\0".charCodeAt(0); 29 | 30 | function assertValidKey(key: string) { 31 | if (key.length === 0) { 32 | throw new TypeError("Key is an empty string."); 33 | } 34 | for (let i = 0; i < key.length; i++) { 35 | if (invalidKeyChars.includes(key.charCodeAt(i))) { 36 | const char = key.charCodeAt(i) === "\0".charCodeAt(0) ? "\\0" : key[i]; 37 | throw new TypeError(`Key contains invalid characters: "${char}"`); 38 | } 39 | } 40 | } 41 | 42 | function assertValidValue(value: string) { 43 | for (let i = 0; i < value.length; i++) { 44 | if (value.charCodeAt(i) === invalidValueChar) { 45 | throw new TypeError('Value contains invalid characters: "\\0"'); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/errors.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // please keep sorted 4 | export class AddrInUse extends Error {} 5 | export class AddrNotAvailable extends Error {} 6 | export class AlreadyExists extends Error {} 7 | export class BadResource extends Error {} 8 | export class BrokenPipe extends Error {} 9 | export class Busy extends Error {} 10 | export class ConnectionAborted extends Error {} 11 | export class ConnectionRefused extends Error {} 12 | export class ConnectionReset extends Error {} 13 | export class Http extends Error {} 14 | export class Interrupted extends Error {} 15 | export class InvalidData extends Error {} 16 | export class NotConnected extends Error {} 17 | export class NotFound extends Error { 18 | code = "ENOENT"; 19 | } 20 | export class PermissionDenied extends Error {} 21 | export class TimedOut extends Error {} 22 | export class UnexpectedEof extends Error {} 23 | export class WriteZero extends Error {} 24 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/mainModule.test.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert/strict"; 2 | import { fileURLToPath, pathToFileURL } from "url"; 3 | import { join, resolve } from "path"; 4 | 5 | import { mainModule } from "./mainModule.js"; 6 | 7 | Deno.test("should get entrypoint", () => { 8 | const path = resolve( 9 | join(fileURLToPath(import.meta.url), "../../../../../tools/run_tests.mjs"), 10 | ); 11 | assert.equal(mainModule, pathToFileURL(path).toString()); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/mainModule.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { join } from "path"; 3 | import { pathToFileURL } from "url"; 4 | 5 | export const mainModule: typeof Deno.mainModule = pathToFileURL( 6 | process.argv[1] ?? join(process.cwd(), "$deno$repl.ts"), 7 | ).href; 8 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/metrics.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const metrics: typeof Deno.metrics = function metrics() { 4 | return { 5 | opsDispatched: 0, 6 | opsDispatchedSync: 0, 7 | opsDispatchedAsync: 0, 8 | opsDispatchedAsyncUnref: 0, 9 | opsCompleted: 0, 10 | opsCompletedSync: 0, 11 | opsCompletedAsync: 0, 12 | opsCompletedAsyncUnref: 0, 13 | bytesSentControl: 0, 14 | bytesSentData: 0, 15 | bytesReceived: 0, 16 | ops: {}, 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/noColor.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const noColor: typeof Deno.noColor = process.env.NO_COLOR !== undefined; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/permissions.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { Permissions } from "../classes/Permissions.js"; 4 | 5 | export const permissions: typeof Deno.permissions = new Permissions(); 6 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/pid.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const pid: typeof Deno.pid = process.pid; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/ppid.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const ppid: typeof Deno.ppid = process.ppid; 4 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/resources.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export const resources: typeof Deno.resources = function resources() { 4 | console.warn( 5 | [ 6 | "Deno.resources() shim returns a dummy object that does not update.", 7 | "If you think this is a mistake, raise an issue at https://github.com/denoland/node_deno_shims/issues", 8 | ].join("\n"), 9 | ); 10 | 11 | return {}; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/std.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import stream from "stream"; 4 | import tty from "tty"; 5 | import { readSync } from "../functions/readSync.js"; 6 | import { writeSync } from "../functions/writeSync.js"; 7 | 8 | function chain Promise>( 9 | fn: T, 10 | cleanup?: () => void, 11 | ): T { 12 | let prev: Promise | undefined; 13 | return function _fn(...args) { 14 | const curr = (prev || Promise.resolve()) 15 | .then(() => fn(...args)) 16 | .finally(cleanup || (() => {})) 17 | .then((result) => { 18 | if (prev === curr) prev = undefined; 19 | return result; 20 | }); 21 | return (prev = curr); 22 | } as T; 23 | } 24 | 25 | let stdinReadable: ReadableStream | undefined; 26 | export const stdin: typeof Deno.stdin = { 27 | rid: 0, 28 | isTerminal() { 29 | return tty.isatty(this.rid); 30 | }, 31 | read: chain( 32 | (p) => { 33 | return new Promise((resolve, reject) => { 34 | process.stdin.resume(); 35 | process.stdin.on("error", onerror); 36 | process.stdin.once("readable", () => { 37 | process.stdin.off("error", onerror); 38 | const data = process.stdin.read(p.length) ?? process.stdin.read(); 39 | if (data) { 40 | p.set(data); 41 | resolve(data.length > 0 ? data.length : null); 42 | } else { 43 | resolve(null); 44 | } 45 | }); 46 | function onerror(error: Error) { 47 | reject(error); 48 | process.stdin.off("error", onerror); 49 | } 50 | }); 51 | }, 52 | () => process.stdin.pause(), 53 | ), 54 | get readable(): ReadableStream { 55 | if (stdinReadable == null) { 56 | stdinReadable = stream.Readable.toWeb(process.stdin); 57 | } 58 | return stdinReadable; 59 | }, 60 | readSync(buffer: Uint8Array) { 61 | return readSync(this.rid, buffer); 62 | }, 63 | close() { 64 | process.stdin.destroy(); 65 | }, 66 | setRaw(mode, options) { 67 | if (options?.cbreak) { 68 | throw new Error("The cbreak option is not implemented."); 69 | } 70 | process.stdin.setRawMode(mode); 71 | }, 72 | }; 73 | 74 | let stdoutWritable: WritableStream | undefined; 75 | export const stdout: typeof Deno.stdout = { 76 | rid: 1, 77 | isTerminal() { 78 | return tty.isatty(this.rid); 79 | }, 80 | write: chain((p) => { 81 | return new Promise((resolve) => { 82 | const result = process.stdout.write(p); 83 | if (!result) { 84 | process.stdout.once("drain", () => resolve(p.length)); 85 | } else { 86 | resolve(p.length); 87 | } 88 | }); 89 | }), 90 | get writable(): WritableStream { 91 | if (stdoutWritable == null) { 92 | stdoutWritable = stream.Writable.toWeb(process.stdout); 93 | } 94 | return stdoutWritable; 95 | }, 96 | writeSync(data: Uint8Array) { 97 | return writeSync(this.rid, data); 98 | }, 99 | close() { 100 | process.stdout.destroy(); 101 | }, 102 | }; 103 | let stderrWritable: WritableStream | undefined; 104 | export const stderr: typeof Deno.stderr = { 105 | rid: 2, 106 | isTerminal() { 107 | return tty.isatty(this.rid); 108 | }, 109 | write: chain((p) => { 110 | return new Promise((resolve) => { 111 | const result = process.stderr.write(p); 112 | if (!result) { 113 | process.stderr.once("drain", () => resolve(p.length)); 114 | } else { 115 | resolve(p.length); 116 | } 117 | }); 118 | }), 119 | get writable(): WritableStream { 120 | if (stderrWritable == null) { 121 | stderrWritable = stream.Writable.toWeb(process.stderr); 122 | } 123 | return stderrWritable; 124 | }, 125 | writeSync(data: Uint8Array) { 126 | return writeSync(this.rid, data); 127 | }, 128 | close() { 129 | process.stderr.destroy(); 130 | }, 131 | }; 132 | -------------------------------------------------------------------------------- /packages/shim-deno/src/deno/stable/variables/version.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { deno, typescript } from "../../internal/version.js"; 4 | 5 | export const version: typeof Deno.version = { 6 | deno, 7 | typescript, 8 | v8: process.versions.v8, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/shim-deno/src/index.ts: -------------------------------------------------------------------------------- 1 | export * as Deno from "./deno/stable/main.js"; 2 | -------------------------------------------------------------------------------- /packages/shim-deno/src/package.json: -------------------------------------------------------------------------------- 1 | { "type": "module" } 2 | -------------------------------------------------------------------------------- /packages/shim-deno/src/test-internals.ts: -------------------------------------------------------------------------------- 1 | export { testDefinitions } from "@deno/shim-deno-test"; 2 | -------------------------------------------------------------------------------- /packages/shim-deno/third_party/package.json: -------------------------------------------------------------------------------- 1 | { "type": "module" } 2 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/bundle.ts: -------------------------------------------------------------------------------- 1 | import $ from "https://deno.land/x/dax@0.38.0/mod.ts"; 2 | import { ensureSpecificDenoVersion } from "./deno_version.ts"; 3 | 4 | ensureSpecificDenoVersion(); 5 | 6 | const rootDir = $.path(import.meta).join("../../").resolve(); 7 | $.cd(rootDir); 8 | await $`deno run -A npm:esbuild@0.20.0 --bundle --platform=node --packages=external --outfile=bundle.cjs dist/script/index.js`; 9 | await $`deno run -A npm:esbuild@0.20.0 --bundle --platform=node --packages=external --outfile=bundle.mjs --format=esm dist/esm/index.js`; 10 | await $`mv bundle.cjs dist/index.cjs && mv bundle.mjs dist/index.mjs`; 11 | await $`mv dist/script/test-internals.js dist/test-internals.cjs`; 12 | await $`mv dist/esm/test-internals.js dist/test-internals.mjs`; 13 | await $`rm -rf dist/script dist/esm`; 14 | 15 | // basic mjs test 16 | { 17 | const tempFile = $.path("temp_file.mjs"); 18 | tempFile.writeText( 19 | `import { testDefinitions } from "./dist/test-internals.mjs"; 20 | import { Deno } from "./dist/index.mjs"; 21 | 22 | console.log(testDefinitions); 23 | console.log(Deno); 24 | if (Deno.writeTextFileSync) { 25 | } 26 | `, 27 | ); 28 | try { 29 | // just ensure it doesn't throw 30 | await $`node ${tempFile}`.quiet(); 31 | } finally { 32 | tempFile.removeSync(); 33 | } 34 | } 35 | 36 | // basic cjs test 37 | { 38 | const tempFile = $.path("temp_file.cjs"); 39 | tempFile.writeText( 40 | `const { testDefinitions } = require("./dist/test-internals.cjs"); 41 | const { Deno } = require("./dist/index.cjs"); 42 | 43 | console.log(testDefinitions); 44 | console.log(Deno); 45 | if (!(testDefinitions instanceof Array)) throw "NOT ARRAY"; 46 | if (Deno.writeTextFileSync == null) throw "NOT FOUND"; 47 | `, 48 | ); 49 | try { 50 | // just ensure it doesn't throw 51 | await $`node ${tempFile}`.quiet(); 52 | } finally { 53 | tempFile.removeSync(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/deno_version.ts: -------------------------------------------------------------------------------- 1 | export const version = "1.40.2"; 2 | 3 | export function ensureSpecificDenoVersion() { 4 | if (Deno.version.deno !== "1.40.2") { 5 | console.error("Wrong Deno version: " + Deno.version.deno); 6 | Deno.exit(1); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/denolib.ts: -------------------------------------------------------------------------------- 1 | // not sure why, but I needed to add this 2 | /// 3 | 4 | import { Node, Project } from "../../../scripts/ts_morph.ts"; 5 | import { ensureSpecificDenoVersion } from "./deno_version.ts"; 6 | 7 | ensureSpecificDenoVersion(); 8 | 9 | const stableTypes = await run("deno types"); 10 | const version = (await run("deno --version")).trim().split("\n").map((line) => 11 | line.split(" ") 12 | ).reduce( 13 | (acc, curr) => ({ ...acc, [curr[0]]: curr[1] }), 14 | {} as { [k: string]: string }, 15 | ); 16 | 17 | await Deno.writeTextFile( 18 | `./src/deno/internal/version.ts`, 19 | [ 20 | `export const deno = "${version.deno}";\n`, 21 | `export const typescript = "${version.typescript}";\n`, 22 | ].join(""), 23 | ); 24 | 25 | await Deno.writeTextFile( 26 | `./src/deno/stable/lib.deno.d.ts`, 27 | processDeclsFromStable(processDeclarationFileText(stableTypes)), 28 | ); 29 | 30 | async function run(cmd: string) { 31 | const parts = cmd.split(" "); 32 | return new TextDecoder().decode( 33 | (await new Deno.Command(parts[0], { 34 | args: parts.slice(1), 35 | }).output()).stdout, 36 | ); 37 | } 38 | 39 | function processDeclarationFileText(text: string) { 40 | return text.replace('/// \n', "") 41 | .replace(`/// \n`, "") 42 | .replace( 43 | `/// `, 44 | `/// `, 45 | ).replace(`/// \n`, "") 46 | .replace(`/// \n`, ""); 47 | } 48 | 49 | function processDeclsFromStable(text: string) { 50 | const project = new Project({ useInMemoryFileSystem: true }); 51 | const sourceFile = project.createSourceFile("deno.lib.d.ts", text); 52 | 53 | // these are removed because they're available in @types/node 54 | sourceFile.getVariableStatementOrThrow("AbortController").remove(); 55 | sourceFile.getInterfaceOrThrow("AbortController").remove(); 56 | sourceFile.getInterfaceOrThrow("AbortSignal").remove(); 57 | sourceFile.getInterfaceOrThrow("AbortSignalEventMap").remove(); 58 | sourceFile.getVariableStatementOrThrow("AbortSignal").remove(); 59 | 60 | [ 61 | // use web streams from @types/node 62 | "ReadableStream", 63 | "WritableStream", 64 | "ReadableStreamBYOBReader", 65 | "ReadableByteStreamController", 66 | "UnderlyingSource", 67 | "UnderlyingByteSource", 68 | "ReadableStreamBYOBRequest", 69 | "ReadableByteStreamControllerCallback", 70 | "ReadableStreamDefaultReadDoneResult", 71 | "ReadableStreamDefaultReadValueResult", 72 | "ReadableStreamBYOBReadDoneResult", 73 | "ReadableStreamBYOBReadValueResult", 74 | "ReadableStreamDefaultReader", 75 | "ReadableStreamErrorCallback", 76 | "ReadableStreamDefaultControllerCallback", 77 | "ReadableStreamDefaultController", 78 | "UnderlyingSink", 79 | "WritableStreamErrorCallback", 80 | "WritableStreamDefaultControllerCloseCallback", 81 | "WritableStreamDefaultControllerStartCallback", 82 | "WritableStreamDefaultControllerWriteCallback", 83 | "WritableStreamDefaultController", 84 | "WritableStreamDefaultWriter", 85 | "ReadableStreamBYOBReadResult", 86 | "ReadableStreamDefaultReadResult", 87 | // use fetch types from @types/node 88 | "Blob", 89 | "FormData", 90 | "Headers", 91 | "Response", 92 | "Request", 93 | "RequestInit", 94 | "URLSearchParams", 95 | "URL", 96 | // use from @types/node 97 | "BroadcastChannel", 98 | "Event", 99 | "EventTarget", 100 | "MessageChannel", 101 | "MessagePort", 102 | "TextDecoder", 103 | "TextEncoder", 104 | "performance", 105 | ].forEach((name) => { 106 | const statements = sourceFile.getStatements().filter((s) => { 107 | return Node.hasName(s) && s.getName() === name || 108 | Node.isVariableStatement(s) && 109 | s.getDeclarations().some((d) => d.getName() === name); 110 | }); 111 | if (statements.length === 0) { 112 | throw new Error(`Not found: ${name}`); 113 | } 114 | statements.forEach((s) => s.remove()); 115 | }); 116 | sourceFile.addStatements((writer) => { 117 | writer.writeLine( 118 | `type ReadableStream = import("stream/web").ReadableStream;`, 119 | ); 120 | writer.writeLine( 121 | `type WritableStream = import("stream/web").WritableStream;`, 122 | ); 123 | writer.write("interface AsyncDisposable").block(() => { 124 | writer.write("[Symbol.asyncDispose](): PromiseLike;"); 125 | }).newLine(); 126 | writer.write("interface Disposable").block(() => { 127 | writer.write("[Symbol.dispose](): void;"); 128 | }); 129 | writer.write("interface SymbolConstructor").block(() => { 130 | writer.writeLine("readonly dispose: unique symbol;"); 131 | writer.writeLine("readonly asyncDispose: unique symbol;"); 132 | }); 133 | writer.write("interface ErrorOptions").block(() => { 134 | writer.writeLine("cause?: unknown;"); 135 | }); 136 | writer.writeLine(`type MessagePort = typeof globalThis["MessagePort"];`); 137 | }); 138 | 139 | return sourceFile.getFullText(); 140 | } 141 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/generateDeclarationFile.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ExportedDeclarations, 3 | IndentationText, 4 | ModuleDeclarationKind, 5 | ModuleDeclarationStructure, 6 | Node, 7 | Project, 8 | SourceFile, 9 | Statement, 10 | StatementStructures, 11 | Structure, 12 | StructureKind, 13 | SyntaxKind, 14 | WriterFunction, 15 | } from "../../../scripts/ts_morph.ts"; 16 | import { exitIfDiagnostics } from "../../../scripts/helpers.ts"; 17 | import { ensureSpecificDenoVersion } from "./deno_version.ts"; 18 | 19 | ensureSpecificDenoVersion(); 20 | 21 | console.log("Generating declaration file..."); 22 | const statements: (StatementStructures | WriterFunction)[] = []; 23 | const declarationProject = getDeclarationProject(); 24 | 25 | const indexFile = declarationProject.getSourceFileOrThrow( 26 | `./dist/script/index.d.ts`, 27 | ); 28 | 29 | // header 30 | statements.push((writer) => { 31 | writer 32 | .writeLine( 33 | `// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.`, 34 | ) 35 | .blankLine() 36 | .writeLine(`/// `) 37 | .blankLine() 38 | .writeLine(`import { URL } from "url";`) 39 | .writeLine( 40 | `import { ReadableStream, WritableStream } from "stream/web";`, 41 | ) 42 | .blankLine(); 43 | }); 44 | 45 | statements.push(...getMainStatements()); 46 | 47 | statements.push({ 48 | kind: StructureKind.Module, 49 | name: `"@deno/shim-deno/test-internals"`, 50 | statements: [ 51 | { 52 | // to make the code below compile 53 | kind: StructureKind.TypeAlias, 54 | name: "TestDefinition", 55 | type: "Deno.TestDefinition", 56 | }, 57 | ...Array.from( 58 | fileExportsToStructures( 59 | declarationProject.getSourceFileOrThrow( 60 | `./dist/script/test-internals.d.ts`, 61 | ), 62 | ), 63 | ).map((s) => exportAndStripAmbient(s)), 64 | ], 65 | }); 66 | statements.push({ 67 | kind: StructureKind.Module, 68 | declarationKind: ModuleDeclarationKind.Global, 69 | name: "global", 70 | hasDeclareKeyword: true, 71 | statements: [{ 72 | kind: StructureKind.Interface, 73 | name: "SymbolConstructor", 74 | properties: [{ 75 | isReadonly: true, 76 | name: "asyncDispose", 77 | type: "unique symbol", 78 | }, { 79 | isReadonly: true, 80 | name: "dispose", 81 | type: "unique symbol", 82 | }], 83 | }], 84 | }); 85 | // fix up the MessagePort reference 86 | statements.push({ 87 | kind: StructureKind.TypeAlias, 88 | name: "MessagePort", 89 | type: `typeof globalThis["MessagePort"]`, 90 | }); 91 | 92 | // Create a new project with limited declarations and add the declaration 93 | // file to it. Save the file then type check. 94 | const newProject = new Project({ 95 | compilerOptions: { 96 | // limit to only node types 97 | types: ["node"], 98 | }, 99 | tsConfigFilePath: `./tsconfig.json`, 100 | skipAddingFilesFromTsConfig: true, 101 | manipulationSettings: { 102 | indentationText: IndentationText.TwoSpaces, 103 | }, 104 | }); 105 | const sourceFile = newProject.createSourceFile( 106 | `./lib/shim-deno.lib.d.ts`, 107 | { statements }, 108 | { overwrite: true }, 109 | ); 110 | 111 | sourceFile.saveSync(); 112 | sourceFile.copyImmediatelySync(`./dist/index.d.cts`, { overwrite: true }); 113 | sourceFile.copyImmediatelySync(`./dist/index.d.mts`, { overwrite: true }); 114 | 115 | exitIfDiagnostics(newProject, sourceFile.getPreEmitDiagnostics()); 116 | 117 | // create the internal declaration 118 | console.log("Generating internal test declaration file..."); 119 | const testInternalFile = newProject.addSourceFileAtPath( 120 | "src/test-internals.ts", 121 | ); 122 | newProject.compilerOptions.set({ 123 | declaration: true, 124 | }); 125 | const files = newProject.emitToMemory({ 126 | emitOnlyDtsFiles: true, 127 | targetSourceFile: testInternalFile, 128 | }).getFiles(); 129 | if (files.length !== 1) { 130 | throw new Error("Failed. Should have only generated one file."); 131 | } 132 | Deno.writeTextFileSync("./dist/test-internals.d.cts", files[0].text); 133 | Deno.writeTextFileSync("./dist/test-internals.d.mts", files[0].text); 134 | 135 | function getMainStatements() { 136 | const statements: StatementStructures[] = []; 137 | 138 | // add some types from lib.deno.d.ts to make compiling happy 139 | const denoStableDeclFile = declarationProject.getSourceFileOrThrow( 140 | `./src/deno/stable/lib.deno.d.ts`, 141 | ); 142 | statements.push( 143 | ...[ 144 | "EventListenerOptions", 145 | "AddEventListenerOptions", 146 | "EventListener", 147 | "EventListenerObject", 148 | "EventListenerOrEventListenerObject", 149 | "Disposable", 150 | "AsyncDisposable", 151 | ].map((name) => { 152 | const statements = denoStableDeclFile 153 | .getStatements() 154 | .filter((s) => 155 | Node.hasName(s) && s.getName() === name || 156 | Node.isVariableStatement(s) && 157 | s.getDeclarations().some((d) => d.getName() === name) 158 | ); 159 | if (statements.length === 0) { 160 | throw new Error(`Not found: ${name}`); 161 | } 162 | return statements.map((statement) => { 163 | if (!Node.hasStructure(statement)) { 164 | throw new Error("Unhandled"); 165 | } 166 | return statement.getStructure() as StatementStructures; 167 | }); 168 | }).flat(), 169 | ); 170 | 171 | // re-export the export declarations from the index file that aren't relative 172 | for (const exportDecl of indexFile.getExportDeclarations()) { 173 | if (!exportDecl.getModuleSpecifierValue()?.startsWith("./")) { 174 | statements.push(exportDecl.getStructure()); 175 | } 176 | } 177 | 178 | // inline any non-Deno namespace exports in the src directory 179 | const exportedDeclarations = indexFile.getExportedDeclarations(); 180 | for (const [name, decls] of exportedDeclarations) { 181 | const isInSrcDir = indexFile.getDirectory() 182 | .isAncestorOf(decls[0].getSourceFile()); 183 | if (name !== "Deno" && isInSrcDir) { 184 | statements.push( 185 | ...Array.from(declsToStructures(name, decls)) 186 | .map((s) => ensureExported(s)), 187 | ); 188 | } 189 | } 190 | 191 | statements.push(getDenoNamespace()); 192 | 193 | return statements; 194 | } 195 | 196 | function getDenoNamespace(): ModuleDeclarationStructure { 197 | return { 198 | kind: StructureKind.Module, 199 | name: "Deno", 200 | hasDeclareKeyword: true, 201 | isExported: true, 202 | statements: [ 203 | ...Array.from( 204 | fileExportsToStructures(declarationProject.getSourceFileOrThrow( 205 | `./dist/script/deno/stable/main.d.ts`, 206 | )), 207 | ), 208 | ].map((s) => exportAndStripAmbient(s)), 209 | }; 210 | } 211 | 212 | function exportAndStripAmbient(structure: TStructure) { 213 | return ensureExported(stripAmbient(structure)); 214 | } 215 | 216 | function ensureExported(structure: TStructure) { 217 | if (Structure.isExportable(structure)) { 218 | const isInternal = hasRemoveExportKeywordJsDocTag(structure); 219 | structure.isExported = !isInternal; 220 | 221 | // remove the jsdocs if its internal 222 | if (isInternal && Structure.isJSDocable(structure)) { 223 | delete structure.docs; 224 | } 225 | } 226 | return structure; 227 | } 228 | 229 | function hasRemoveExportKeywordJsDocTag(structure: unknown) { 230 | if (!Structure.isJSDocable(structure)) { 231 | return false; 232 | } 233 | if (!structure.docs || !(structure.docs instanceof Array)) { 234 | return false; 235 | } 236 | 237 | return structure.docs.some((d) => { 238 | if (!d || typeof d === "string") { 239 | return false; 240 | } 241 | return d.tags?.some((t) => t.tagName === "removeExportKeyword") ?? false; 242 | }); 243 | } 244 | 245 | function stripAmbient(structure: TStructure) { 246 | if (Structure.isAmbientable(structure)) { 247 | structure.hasDeclareKeyword = false; 248 | } 249 | return structure; 250 | } 251 | 252 | function* fileExportsToStructures(file: SourceFile) { 253 | for (const [name, decls] of file.getExportedDeclarations()) { 254 | yield* declsToStructures(name, decls); 255 | } 256 | } 257 | 258 | function* declsToStructures( 259 | name: string, 260 | decls: (ExportedDeclarations | Statement)[], 261 | ) { 262 | for (const decl of decls) { 263 | yield* declToStructures(name, decl); 264 | } 265 | } 266 | 267 | function* declToStructures( 268 | name: string, 269 | decl: ExportedDeclarations | Statement, 270 | ): Iterable { 271 | // Check for a qualified name in a type alias... 272 | // export type Alias = Deno.Alias; 273 | // ...or in a variable declaration... 274 | // export const alias: Deno.alias; 275 | // ...and if so, inline to the original declaration. 276 | const qualifiedName = decl.asKind(SyntaxKind.TypeAliasDeclaration) 277 | ?.getTypeNode() 278 | ?.asKind(SyntaxKind.TypeReference) 279 | ?.getTypeName() ?? decl.asKind(SyntaxKind.VariableDeclaration) 280 | ?.getTypeNode() 281 | ?.asKind(SyntaxKind.TypeQuery) 282 | ?.getExprName(); 283 | 284 | if (Node.hasName(decl) && Node.isQualifiedName(qualifiedName)) { 285 | const symbol = qualifiedName.getRight().getSymbolOrThrow(); 286 | const declarations = symbol.getDeclarations() as ExportedDeclarations[]; 287 | yield* declsToStructures(name, declarations); 288 | } else if (Node.isVariableDeclaration(decl)) { 289 | const varStmt = decl.getVariableStatementOrThrow(); 290 | if (decl.getName() !== name) { 291 | throw new Error("Unhandled."); 292 | } 293 | if (varStmt.getDeclarations().length > 1) { 294 | throw new Error("Unhandled."); 295 | } 296 | yield varStmt.getStructure(); 297 | } else if (Node.isSourceFile(decl)) { 298 | const statements: StatementStructures[] = []; 299 | for (const [name, declarations] of decl.getExportedDeclarations()) { 300 | statements.push( 301 | ...Array.from(declsToStructures(name, declarations)) 302 | .map(exportAndStripAmbient), 303 | ); 304 | } 305 | yield { 306 | kind: StructureKind.Module, 307 | name, 308 | statements, 309 | }; 310 | } else { 311 | if (Node.isExpression(decl)) { 312 | console.error(decl.getFullText()); 313 | throw new Error("Unhandled."); 314 | } 315 | if (!Node.hasName(decl) || decl.getName() !== name) { 316 | console.error(decl.getFullText()); 317 | throw new Error("Unhandled."); 318 | } 319 | 320 | if (Node.hasStructure(decl)) { 321 | yield decl.getStructure() as StatementStructures; 322 | } else { 323 | console.error(decl.getFullText()); 324 | throw new Error("Unhandled."); 325 | } 326 | } 327 | } 328 | 329 | /** Gets a project containing the emitted declaration files. */ 330 | function getDeclarationProject() { 331 | const project = new Project({ 332 | compilerOptions: { 333 | declaration: true, 334 | }, 335 | tsConfigFilePath: `./tsconfig.json`, 336 | }); 337 | 338 | exitIfDiagnostics(project, project.getPreEmitDiagnostics()); 339 | 340 | const dtsEmitResult = project.emitToMemory({ 341 | emitOnlyDtsFiles: true, 342 | }); 343 | 344 | const declarationProject = new Project({ 345 | tsConfigFilePath: `./tsconfig.json`, 346 | skipAddingFilesFromTsConfig: true, 347 | }); 348 | for (const item of dtsEmitResult.getFiles()) { 349 | declarationProject.createSourceFile(item.filePath, item.text, { 350 | overwrite: true, 351 | }); 352 | } 353 | declarationProject.addSourceFileAtPath( 354 | `./src/deno/stable/lib.deno.d.ts`, 355 | ); 356 | 357 | return declarationProject; 358 | } 359 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/missing.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S deno run --allow-read='.' 2 | 3 | import { Project, Symbol, SymbolFlags } from "../../../scripts/ts_morph.ts"; 4 | 5 | const project = new Project({ 6 | tsConfigFilePath: `./tsconfig.json`, 7 | }); 8 | 9 | const diagnostics = project.getPreEmitDiagnostics(); 10 | if (diagnostics.length !== 0) { 11 | console.error(); 12 | console.error(project.formatDiagnosticsWithColorAndContext(diagnostics)); 13 | console.error(`Found ${diagnostics.length} errors.`); 14 | Deno.exit(1); 15 | } 16 | 17 | const typeChecker = project.getTypeChecker().compilerObject; 18 | const entryPoint = project.getSourceFileOrThrow(`./src/deno.ts`); 19 | const implemented = new Set(entryPoint.getExportedDeclarations().keys()); 20 | 21 | const stableMembers = getDenoMembersFromFile(`./src/deno/stable/lib.deno.d.ts`); 22 | const unstableMembers = getDenoMembersFromFile( 23 | `./src/deno/unstable/lib.deno.unstable.d.ts`, 24 | ); 25 | 26 | outputInfo({ 27 | categoryName: "Stable", 28 | members: stableMembers, 29 | includeUnstableInCount: false, 30 | }); 31 | console.log(""); 32 | outputInfo({ 33 | categoryName: "Unstable", 34 | members: unstableMembers, 35 | includeUnstableInCount: false, 36 | }); 37 | 38 | function getDenoMembersFromFile(filePath: string) { 39 | return project 40 | .addSourceFileAtPath(filePath) 41 | .getModuleOrThrow("Deno") 42 | .getSymbolOrThrow() 43 | .getExports() 44 | .map(processExport) 45 | .sort((a, b) => Number(a.name > b.name) - Number(a.name < b.name)); 46 | } 47 | 48 | function processExport(symbol: Symbol) { 49 | const deprecated = symbol.getJsDocTags().some((tag) => 50 | tag.getName() === "deprecated" 51 | ); 52 | const unstable = symbol.compilerSymbol.getDocumentationComment(typeChecker)[0] 53 | ?.text.includes("UNSTABLE"); 54 | const typeOnly = symbol.hasFlags(SymbolFlags.Interface) || 55 | symbol.hasFlags(SymbolFlags.TypeAlias); 56 | return { 57 | deprecated, 58 | implemented: implemented.has(symbol.getName()), 59 | name: symbol.getName(), 60 | stable: !(unstable || deprecated), 61 | typeOnly, 62 | unstable, 63 | }; 64 | } 65 | 66 | function outputInfo(opts: { 67 | categoryName: string; 68 | members: ReturnType[]; 69 | includeUnstableInCount: boolean; 70 | }) { 71 | const filteredMembers = opts.includeUnstableInCount 72 | ? opts.members 73 | : opts.members.filter((m) => m.stable); 74 | const membersImpl = filteredMembers.filter((member) => member.implemented); 75 | const percentage = Math.floor( 76 | membersImpl.length * 100 / filteredMembers.length, 77 | ); 78 | const toGo = filteredMembers.length - membersImpl.length; 79 | console.info(`# ${opts.categoryName} Progress\n`); 80 | console.info( 81 | `${percentage}%. ${toGo} ${opts.categoryName.toLowerCase()} members to go:\n`, 82 | ); 83 | 84 | const onlyToGo = Deno.stdout.isTerminal(); 85 | for (const member of opts.members) { 86 | const toGo = !(member.implemented || member.deprecated); 87 | if (onlyToGo && !toGo) continue; 88 | const ghost = member.typeOnly ? " 👻" : ""; 89 | const flask = member.unstable ? " 🧪" : ""; 90 | const down = member.deprecated ? " 👎" : ""; 91 | const checkmark = member.implemented ? `[x]` : "[ ]"; 92 | console.log(`- ${checkmark}${down}${flask}${ghost} **\`${member.name}\`**`); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/run_tests.mjs: -------------------------------------------------------------------------------- 1 | // This script runs the unit tests under third_party/deno directory 2 | 3 | import fs from "fs"; 4 | import { createRequire } from "module"; 5 | 6 | // rq = requires 7 | const testsToSkip = new Set([ 8 | // abort_controller_test 9 | "abortReason", // reason is not supported yet in node.js 10 | 11 | // blob_test 12 | "blobBuffer", // experimental native Blob 13 | "blobCustomInspectFunction", // experimental native Blob 14 | 15 | // copy_file_test 16 | "copyFileSyncPerm1", // permissions 17 | "copyFileSyncPerm2", // permissions 18 | "copyFilePerm1", // permissions 19 | "copyFilePerm2", // permissions 20 | 21 | // dir_test 22 | "dirCwdError", // fails on Linux, reason unknown 23 | "dirCwdPermError", // permissions 24 | 25 | // event_target_test 26 | "eventTargetThisShouldDefaultToWindow", // window 27 | "eventTargetAddEventListenerGlobalAbort", // global addEventListener 28 | 29 | // files_test 30 | "filesIter", // deprecated 31 | "filesIterCustomBufSize", // deprecated 32 | "filesIterSync", // deprecated 33 | "filesIterSyncCustomBufSize", // deprecated 34 | "fsFileSyncSyncSuccess", // not implemented 35 | "fsFileSyncSuccess", // not implemented 36 | "fsFileUtimeSyncSuccess", // not implemented 37 | "fsFileUtimeSuccess", // not implemented 38 | "futimeSyncSuccess", // not implemented 39 | "futimeSuccess", // not implemented 40 | "readerIter", // deprecated 41 | "readerIterSync", // deprecated 42 | "writePermFailure", // permissions 43 | "openOptions", // todo 44 | "openMode", // depends on umask 45 | "openSyncMode", // depends on umask 46 | "openSyncUrl", // depends on umask 47 | "openUrl", // depends on umask 48 | "readPermFailure", // permissions 49 | "readWritePermFailure", // permissions 50 | "openSyncNotFound", // includes full path in node.js 51 | "openNotFound", // includes full path in node.js 52 | "openModeWriteRead", // not implemented 53 | "readFileIsDirectoryErrorCode", // todo(https://github.com/denoland/deno/issues/18629): re-enable 54 | "seekStart", // not implemented 55 | "seekSyncStart", // not implemented 56 | "seekCurrent", // not implemented 57 | "seekStartBigInt", // not implemented 58 | "seekSyncCurrent", // not implemented 59 | "seekEnd", // not implemented 60 | "seekSyncEnd", // not implemented 61 | "seekMode", // not implemented 62 | 63 | // mkdir_test 64 | "mkdirMode", // depends on Deno.umask 65 | "mkdirRecursiveIfExists", // depends on Deno.umask 66 | "mkdirRecursiveMode", // depends on Deno.umask 67 | "mkdirSyncMode", // depends on Deno.umask 68 | "mkdirSyncRecursiveIfExists", // depends on Deno.umask 69 | "mkdirSyncRecursiveMode", // depends on Deno.umask 70 | "mkdirSyncErrors", // getCreationFlag throws 71 | "mkdirSyncPerm", // permissions 72 | 73 | // os_test 74 | "envPermissionDenied1", // permissions 75 | "envPermissionDenied2", // permissions 76 | "envCaseInsensitive", // needs Deno.Command 77 | "osPpidIsEqualToPidOfParentProcess", // needs Deno.Command 78 | "execPathPerm", // permissions 79 | "loadavgPerm", // permissions 80 | "hostnameWithoutOtherNetworkUsages", // needs Deno.Command 81 | "hostnamePerm", // permissions 82 | "releasePerm", // permissions 83 | "osUptimePerm", // permissions 84 | "systemMemoryInfo", // not implemented 85 | "getUid", // not implemented 86 | "getGid", // not implemented 87 | 88 | // process_test 89 | "runPermissions", // permissions 90 | "killPermissions", // permissions 91 | "uid", // permissions 92 | "gid", // permissions 93 | 94 | // stat_test 95 | "statSyncPerm", // permissions 96 | "statSyncNotFound", // todo: includes full path in node.js 97 | "lstatSyncPerm", // permissions 98 | "lstatSyncNotFound", // todo: includes full path in node.js 99 | "statPerm", // permissions 100 | "statNotFound", // todo: includes full path in node.js 101 | "lstatPerm", // permissions 102 | "lstatNotFound", // todo: includes full path in node.js 103 | 104 | // read_file_test 105 | "readFileSyncPerm", // permissions 106 | "readFilePerm", // permissions 107 | "readFileDoesNotLeakResources", //TODO, rq: Deno.resources 108 | "readFileSyncDoesNotLeakResources", //TODO, rq: Deno.resources 109 | "readFileWithAbortSignal", //TODO, rq: issue #64 110 | "readFileWithAbortSignalReason", //TODO, rq: issue #64 111 | "readFileWithAbortSignalPrimitiveReason", //TODO, rq: issue #64 112 | 113 | // read_text_file_test 114 | "readTextFileSyncPerm", // permissions 115 | "readTextFilePerm", // permissions 116 | "readTextFileDoesNotLeakResources", //TODO, rq: Deno.resources 117 | "readTextFileSyncDoesNotLeakResources", //TODO, rq: Deno.resources 118 | "readTextFileWithAbortSignal", //TODO, rq: issue #64 119 | "readTextFileWithAbortSignalReason", //TODO, rq: issue #64 120 | "readTextFileWithAbortSignalPrimitiveReason", //TODO, rq: issue #64 121 | "readTextFileSyncV8LimitError", // edge case 122 | "readTextFileV8LimitError", // edge case 123 | 124 | // read_dir_test 125 | "readDirSyncPerm", // permissions 126 | "readDirPerm", // permissions 127 | 128 | // testing_test 129 | "invalidStepArguments", // no test runner in shim-deno 130 | "nameOnTextContext", // no test runner in shim-deno 131 | "originOnTextContext", // no test runner in shim-deno 132 | "parentOnTextContext", // no test runner in shim-deno 133 | 134 | // timers_test 135 | "clearTimeoutShouldConvertToNumber", // Timeout is an object, not a number 136 | "clearTimeoutShouldThrowWithBigint", // Timeout is an object, not a number 137 | "callbackTakesLongerThanInterval", // Deno.sleepSync works differently than Atomics.wait unfortunately 138 | "sleepSyncShorterPromise", // Deno.sleepSync works differently than Atomics.wait unfortunately 139 | "sleepSyncLongerPromise", // Deno.sleepSync works differently than Atomics.wait unfortunately 140 | "AbortSignal.timeout() with listeners", // can't use execCode 141 | "AbortSignal.timeout() with removed listeners", // can't use execCode 142 | "AbortSignal.timeout() with no listeners", // Deno.Command is not implemented yet 143 | "AbortSignal.timeout() with listener for a non-abort event", // Deno.Command is not implemented yet 144 | "evalPrimordial", // Timeout is an object, not a number 145 | "unrefTimer", // can't use execCode 146 | "unrefTimer - mix ref and unref 1", // can't use execCode 147 | "unrefTimer - mix ref and unref 2", // can't use execCode 148 | "unrefTimer - unref interval", // can't use execCode 149 | "unrefTimer - unref then ref 1", // can't use execCode 150 | "unrefTimer - unref then ref", // can't use execCode 151 | "unrefTimer - invalid calls do nothing", // todo: add unrefTimer 152 | "timerMaxCpuBug", // uses metrics 153 | "stringifyAndEvalNonFunctions", 154 | "testFunctionParamsLength", 155 | "timeoutBindThis", 156 | "timeoutCallbackThis", 157 | "timeoutEvalNoScopeLeak", 158 | "regression for #20367", // interestingly, node.js seems flaky on this 159 | 160 | // truncate_test 161 | "truncateSyncPerm", // permissions 162 | "truncatePerm", // permissions 163 | 164 | // url_test 165 | "customInspectFunction", 166 | "emptyUrl", // deno includes more details in the error messages 167 | "urlHostnameParsing", // failing only on ci for some reason 168 | "urlDriveLetter", 169 | "urlPathRepeatedSlashes", 170 | "urlProtocolParsing", // deno includes more details in the error messages 171 | 172 | // write_file_test 173 | "writeFileAbortSignalPreAborted", // implementation detail 174 | "writeFileSyncPerm", // permissions 175 | "writeFilePerm", // permissions 176 | "writeFileAbortSignalReason", // TODO, rq: issue #65 177 | "writeFileAbortSignalPrimitiveReason", // TODO, rq: issue #65 178 | "writeFileAbortSignalReasonPreAborted", // TODO, rq: issue #65 179 | "writeFileAbortSignalPrimitiveReasonPreAborted", // TODO, rq: issue #65 180 | 181 | // write_text_file_test 182 | "writeTextFileSyncPerm", // permissions 183 | "writeTextFilePerm", // permissions 184 | 185 | // utime_test 186 | "utimeSyncLargeNumberSuccess", // node.js cannot handle such a large value 187 | "utimeSyncPerm", // permissions 188 | ]); 189 | const testFiles = fs.readFileSync("tools/working_test_files.txt", "utf8") 190 | .trim().split(/\s/); 191 | 192 | const testDefinitions = (await import("../src/test-internals.ts")) 193 | .testDefinitions; 194 | const filter = getFilter(); 195 | 196 | await setupTests(); 197 | 198 | for (const testFile of testFiles) { 199 | await import("../" + testFile); 200 | const definitions = testDefinitions.splice(0) 201 | .filter((definition) => { 202 | if (testsToSkip.has(definition.name) || definition.ignore) { 203 | return false; 204 | } 205 | if (filter && !definition.name.includes(filter)) { 206 | return false; 207 | } 208 | 209 | return true; 210 | }); 211 | 212 | if (definitions.length === 0) { 213 | continue; 214 | } 215 | 216 | console.log(`\nRunning tests in ${testFile}...\n`); 217 | 218 | for (const definition of definitions) { 219 | try { 220 | process.stdout.write(`test ${definition.name} ...`); 221 | await definition.fn(); 222 | process.stdout.write(" ok\n"); 223 | } catch (err) { 224 | process.stdout.write("\n"); 225 | process.stdout.write((err.stack ?? err).toString() + "\n"); 226 | process.stdout.write("\nfailed\n"); 227 | process.exit(1); 228 | } 229 | } 230 | } 231 | 232 | function getFilter() { 233 | const args = process.argv.slice(2); 234 | const filterIndex = args.indexOf("--filter"); 235 | return filterIndex >= 0 ? args[filterIndex + 1] : undefined; 236 | } 237 | 238 | async function setupTests() { 239 | // set missing CJS globals to dummy values 240 | // required by Deno.mainModule 241 | globalThis.require = createRequire(import.meta.url); 242 | globalThis.__dirname = ""; 243 | 244 | // let Deno tests access third_party/deno/cli/tests/fixture.json 245 | process.chdir("third_party/deno/"); 246 | 247 | globalThis.Deno = (await import("../src/index.ts")).Deno; 248 | if (!("Blob" in globalThis)) { 249 | globalThis.Blob = (await import("buffer")).Blob; 250 | } 251 | await webStreamHack(); 252 | 253 | if (!("crypto" in globalThis)) { 254 | globalThis.crypto = (await import("crypto")).webcrypto; 255 | } 256 | 257 | if (Promise.withResolvers === undefined) { 258 | // https://github.com/tc39/proposal-promise-with-resolvers/blob/3a78801e073e99217dbeb2c43ba7212f3bdc8b83/polyfills.js#L1C1-L9C2 259 | Promise.withResolvers = () => { 260 | const out = {}; 261 | out.promise = new Promise((resolve_, reject_) => { 262 | out.resolve = resolve_; 263 | out.reject = reject_; 264 | }); 265 | return out; 266 | }; 267 | } 268 | } 269 | 270 | async function webStreamHack() { 271 | // https://github.com/node-fetch/fetch-blob/blob/c5c2b5215446334bf496733d4cdb48a981b4c440/streams.cjs 272 | // 64 KiB (same size chrome slice theirs blob into Uint8array's) 273 | const POOL_SIZE = 65536; 274 | 275 | try { 276 | if (!globalThis.ReadableStream) { 277 | Object.assign(globalThis, await import("stream/web")); 278 | } 279 | const { Blob } = await import("buffer"); 280 | if (Blob && !Blob.prototype.stream) { 281 | Blob.prototype.stream = function name() { 282 | let position = 0; 283 | //deno-lint-ignore no-this-alias 284 | const blob = this; 285 | 286 | return new ReadableStream({ 287 | type: "bytes", 288 | async pull(ctrl) { 289 | const chunk = blob.slice( 290 | position, 291 | Math.min(blob.size, position + POOL_SIZE), 292 | ); 293 | const buffer = await chunk.arrayBuffer(); 294 | position += buffer.byteLength; 295 | ctrl.enqueue(new Uint8Array(buffer)); 296 | 297 | if (position === blob.size) { 298 | ctrl.close(); 299 | } 300 | }, 301 | }); 302 | }; 303 | } 304 | } catch (_error) { 305 | // ignore 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/untested.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | ls third_party/deno/cli/tests/unit/*_test.ts | comm -3 - tools/working_test_files.txt 5 | -------------------------------------------------------------------------------- /packages/shim-deno/tools/working_test_files.txt: -------------------------------------------------------------------------------- 1 | src/deno/internal/streams.test.ts 2 | src/deno/stable/functions/open.test.ts 3 | src/deno/stable/functions/resolveDns.test.ts 4 | src/deno/stable/functions/run.test.ts 5 | src/deno/stable/variables/mainModule.test.ts 6 | third_party/deno/cli/tests/unit/abort_controller_test.ts 7 | third_party/deno/cli/tests/unit/blob_test.ts 8 | third_party/deno/cli/tests/unit/build_test.ts 9 | third_party/deno/cli/tests/unit/copy_file_test.ts 10 | third_party/deno/cli/tests/unit/dir_test.ts 11 | third_party/deno/cli/tests/unit/error_stack_test.ts 12 | third_party/deno/cli/tests/unit/event_target_test.ts 13 | third_party/deno/cli/tests/unit/files_test.ts 14 | third_party/deno/cli/tests/unit/get_random_values_test.ts 15 | third_party/deno/cli/tests/unit/io_test.ts 16 | third_party/deno/cli/tests/unit/message_channel_test.ts 17 | third_party/deno/cli/tests/unit/mkdir_test.ts 18 | third_party/deno/cli/tests/unit/os_test.ts 19 | third_party/deno/cli/tests/unit/process_test.ts 20 | third_party/deno/cli/tests/unit/read_file_test.ts 21 | third_party/deno/cli/tests/unit/read_text_file_test.ts 22 | third_party/deno/cli/tests/unit/stat_test.ts 23 | third_party/deno/cli/tests/unit/sync_test.ts 24 | third_party/deno/cli/tests/unit/testing_test.ts 25 | third_party/deno/cli/tests/unit/timers_test.ts 26 | third_party/deno/cli/tests/unit/truncate_test.ts 27 | third_party/deno/cli/tests/unit/url_search_params_test.ts 28 | third_party/deno/cli/tests/unit/url_test.ts 29 | third_party/deno/cli/tests/unit/utime_test.ts 30 | third_party/deno/cli/tests/unit/version_test.ts 31 | third_party/deno/cli/tests/unit/write_file_test.ts 32 | third_party/deno/cli/tests/unit/write_text_file_test.ts 33 | -------------------------------------------------------------------------------- /packages/shim-deno/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "outDir": "dist/esm" 5 | }, 6 | "extends": "./tsconfig.json" 7 | } 8 | -------------------------------------------------------------------------------- /packages/shim-deno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2022", 6 | "lib": ["ES2019"], // no DOM types 7 | "esModuleInterop": true, 8 | "declaration": false, 9 | "outDir": "dist/script", 10 | "stripInternal": true 11 | }, 12 | "ts-node": { 13 | "transpileOnly": true, 14 | "files": true, 15 | "compilerOptions": { 16 | "module": "ES2020" 17 | } 18 | }, 19 | "files": ["src/index.ts", "src/test-internals.ts"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/shim-prompts/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/shim-prompts/README.md: -------------------------------------------------------------------------------- 1 | # @deno/shim-prompts 2 | 3 | Shims for `alert`, `confirm`, and `prompt` that work in Node.js. 4 | -------------------------------------------------------------------------------- /packages/shim-prompts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/shim-prompts", 3 | "version": "0.1.1", 4 | "description": "alert, confirm, and prompt for Node.js", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "tsc", 9 | "test": "echo \"No tests yet\"" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/denoland/node_deno_shims.git" 17 | }, 18 | "keywords": [ 19 | "shim", 20 | "deno", 21 | "node.js", 22 | "prompts" 23 | ], 24 | "author": "The Deno authors", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/denoland/node_deno_shims/issues" 28 | }, 29 | "homepage": "https://github.com/denoland/node_deno_shims#readme", 30 | "devDependencies": { 31 | "@types/node": "^20.9.0", 32 | "typescript": "^5.2.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/shim-prompts/src/index.ts: -------------------------------------------------------------------------------- 1 | import { writeSync } from "fs"; 2 | import { readlineSync } from "./readlineSync.js"; 3 | 4 | export const alert: typeof globalThis extends { alert: infer T } ? T 5 | : (message?: any) => void = (globalThis as any)["alert"] ?? 6 | function alert(message) { 7 | writeSync( 8 | process.stdout.fd, 9 | new TextEncoder().encode(`${message} [Enter] `), 10 | ); 11 | readlineSync(); 12 | }; 13 | 14 | export const confirm: typeof globalThis extends { confirm: infer T } ? T 15 | : (message?: string) => boolean = (globalThis as any)["confirm"] ?? 16 | function confirm(message) { 17 | writeSync( 18 | process.stdout.fd, 19 | new TextEncoder().encode(`${message} [y/N] `), 20 | ); 21 | const result = readlineSync(); 22 | return ["y", "Y"].includes(result); 23 | }; 24 | 25 | export const prompt: typeof globalThis extends { prompt: infer T } ? T 26 | : (message?: string, _default?: string) => string | null = 27 | (globalThis as any)["prompt"] ?? 28 | function prompt( 29 | message = "Prompt", 30 | defaultValue, 31 | ) { 32 | writeSync( 33 | process.stdout.fd, 34 | new TextEncoder().encode( 35 | `${message}${defaultValue ? ` [${defaultValue}]` : ""} `, 36 | ), 37 | ); 38 | const result = readlineSync(); 39 | return result.length > 0 ? result : defaultValue ?? null; 40 | }; 41 | -------------------------------------------------------------------------------- /packages/shim-prompts/src/readlineSync.ts: -------------------------------------------------------------------------------- 1 | import { readSync } from "fs"; 2 | 3 | export function readlineSync() { 4 | let line = ""; 5 | let char = ""; 6 | const buf = Buffer.alloc(1); 7 | while (char !== "\r" && char !== "\n") { 8 | line += char; 9 | try { 10 | const bytesRead = readSync(process.stdin.fd, buf); 11 | if (bytesRead === 0) { 12 | return line; 13 | } 14 | } catch (err: any) { 15 | if (err.code === "EOF") { 16 | return line; 17 | } 18 | continue; 19 | } 20 | char = String(buf); 21 | } 22 | if (char === "\r") { 23 | readSync(process.stdin.fd, buf); 24 | } 25 | return line; 26 | } 27 | -------------------------------------------------------------------------------- /packages/shim-prompts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2019", 6 | "declaration": true, 7 | "outDir": "dist", 8 | "stripInternal": true 9 | }, 10 | "ts-node": { 11 | "transpileOnly": true, 12 | "files": true, 13 | "compilerOptions": { 14 | "module": "ES2015" 15 | } 16 | }, 17 | "files": ["src/index.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /packages/shim-timers/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2021-2022 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /packages/shim-timers/README.md: -------------------------------------------------------------------------------- 1 | # @deno/shim-timers 2 | 3 | Shims for `setTimeout` and `setInterval` that will work in the browser and 4 | Node.js. 5 | -------------------------------------------------------------------------------- /packages/shim-timers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deno/shim-timers", 3 | "version": "0.1.0", 4 | "description": "Web compatible shim for setTimeout and setInterval.", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "tsc", 9 | "test": "ts-node --project tsconfig.json src/index.test.ts" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/denoland/node_deno_shims.git" 17 | }, 18 | "keywords": [ 19 | "shim", 20 | "deno", 21 | "node.js", 22 | "timers" 23 | ], 24 | "author": "The Deno authors", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/denoland/node_deno_shims/issues" 28 | }, 29 | "homepage": "https://github.com/denoland/node_deno_shims#readme", 30 | "devDependencies": { 31 | "typescript": "^5.2.2", 32 | "ts-node": "^10.9.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/shim-timers/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { setInterval, setTimeout } from "./index"; 2 | import * as assert from "assert/strict"; 3 | 4 | console.log("should get setTimeout result that's a number..."); 5 | const timeoutId = setTimeout(() => {}, 100); 6 | assert.equal(typeof timeoutId, "number"); 7 | clearTimeout(timeoutId); 8 | 9 | console.log("should get setInterval result that's a number"); 10 | const intervalId = setInterval(() => {}, 100); 11 | assert.equal(typeof intervalId, "number"); 12 | clearInterval(intervalId); 13 | -------------------------------------------------------------------------------- /packages/shim-timers/src/index.ts: -------------------------------------------------------------------------------- 1 | const originalSetTimeout = globalThis.setTimeout; 2 | export function setTimeout( 3 | cb: (...args: any[]) => void, 4 | delay?: number, 5 | ...args: any[] 6 | ): number { 7 | const result = originalSetTimeout(cb, delay, ...args); 8 | // node may return a Timeout object, but return the primitive instead 9 | return typeof result === "number" 10 | ? result 11 | : (result as any)[Symbol.toPrimitive](); 12 | } 13 | 14 | const originalSetInterval = globalThis.setInterval; 15 | export function setInterval( 16 | cb: (...args: any[]) => void, 17 | delay?: number, 18 | ...args: any[] 19 | ): number { 20 | const result = originalSetInterval(cb, delay, ...args); 21 | // node may return a Timeout object, but return the primitive instead 22 | return typeof result === "number" 23 | ? result 24 | : (result as any)[Symbol.toPrimitive](); 25 | } 26 | -------------------------------------------------------------------------------- /packages/shim-timers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "strict": true, 5 | "target": "ES2019", 6 | "lib": ["ES2019"], 7 | "declaration": true, 8 | "outDir": "dist", 9 | "stripInternal": true 10 | }, 11 | "ts-node": { 12 | "transpileOnly": true, 13 | "files": true 14 | }, 15 | "files": ["src/index.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/extract_types_from_symbol.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { 4 | ClassDeclaration, 5 | FunctionDeclaration, 6 | InterfaceDeclaration, 7 | Node, 8 | StatementStructures, 9 | Structure, 10 | Symbol, 11 | TypeAliasDeclaration, 12 | VariableStatement, 13 | } from "./ts_morph.ts"; 14 | 15 | export function extractTypesFromSymbol(opts: { 16 | symbol: Symbol; 17 | /** If this declaration should be included and analyzed. */ 18 | isContainedDeclaration: (node: Node) => boolean; 19 | }) { 20 | const visitedSymbols = new Set(); 21 | const visitedNodes = new Set(); 22 | const statements: (StatementStructures | string)[] = []; 23 | 24 | visitSymbol(opts.symbol); 25 | 26 | return statements; 27 | 28 | function visitSymbol(symbol: Symbol) { 29 | if (visitedSymbols.has(symbol)) { 30 | return; 31 | } 32 | visitedSymbols.add(symbol); 33 | 34 | for (const declaration of symbol.getDeclarations()) { 35 | if ( 36 | !opts.isContainedDeclaration(declaration) || 37 | visitedNodes.has(declaration) 38 | ) { 39 | continue; 40 | } 41 | 42 | visitedNodes.add(declaration); 43 | 44 | if ( 45 | Node.isInterfaceDeclaration(declaration) || 46 | Node.isTypeAliasDeclaration(declaration) || 47 | Node.isClassDeclaration(declaration) || 48 | Node.isFunctionDeclaration(declaration) 49 | ) { 50 | writeDeclaration(declaration); 51 | } else if (Node.isVariableDeclaration(declaration)) { 52 | writeDeclaration(declaration.getVariableStatementOrThrow()); 53 | } 54 | 55 | for (const descendant of declaration.getDescendants()) { 56 | const symbol = descendant.getSymbol(); 57 | if (symbol != null) { 58 | visitSymbol(symbol); 59 | } 60 | } 61 | } 62 | 63 | function writeDeclaration( 64 | declaration: 65 | | VariableStatement 66 | | InterfaceDeclaration 67 | | TypeAliasDeclaration 68 | | ClassDeclaration 69 | | FunctionDeclaration, 70 | ) { 71 | const structure = declaration.getStructure(); 72 | structure.isExported = true; 73 | if (Structure.isFunctionDeclarationOverload(structure)) { 74 | throw new Error("Not implemented."); 75 | } 76 | 77 | if (Structure.isFunction(structure)) { 78 | structure.hasDeclareKeyword = true; 79 | } 80 | statements.push(structure); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /scripts/helpers.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. 2 | 3 | import { Diagnostic, Project } from "./ts_morph.ts"; 4 | 5 | export function exitIfDiagnostics(project: Project, diagnostics: Diagnostic[]) { 6 | if (diagnostics.length > 0) { 7 | console.error(project.formatDiagnosticsWithColorAndContext(diagnostics)); 8 | console.error(`Had ${diagnostics.length} diagnostic(s).`); 9 | Deno.exit(1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scripts/mod.ts: -------------------------------------------------------------------------------- 1 | export * from "./helpers.ts"; 2 | export * from "./extract_types_from_symbol.ts"; 3 | export * as tsMorph from "./ts_morph.ts"; 4 | -------------------------------------------------------------------------------- /scripts/ts_morph.ts: -------------------------------------------------------------------------------- 1 | export * from "https://deno.land/x/ts_morph@20.0.0/mod.ts"; 2 | --------------------------------------------------------------------------------