CodeSampleX

示例

@babel/plugin-transform-block-scoped-functions 8.0.1: default

已验证示例 — npm @babel/plugin-transform-block-scoped-functions 8.0.1: default. contract 在 node 22 · linux alpine/x64 · docker 上运行并通过.

sha256:398597f60ccb4e48c720f27fbcd2aad47ffe8872d758d252a83789f9634fe316

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
1
构建过它的签名密钥
1
声明的环境 linux 24 · ubuntu · glibc 2.39 x64 npm

验证运行环境

环境 契约 阶段 运行日期
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-08-27

案例

HOW
目标
verify pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1
包
符号
  • default
创建时间
2026-08-27T20:42:48Z

契约

  1. Plugin default export is a function factory asserting Babel 7 or 8 compatibility range
  2. Plugin factory returns an object named transform-block-scoped-functions with BlockStatement, SwitchStatement, and Loop visitor methods
  3. BlockStatement visitor transforms function declarations in strict-mode block scopes into let variable declarations with blockHoist 2
  4. BlockStatement visitor transforms function declarations in non-strict block scopes into var variable declarations
  5. BlockStatement visitor transforms async or generator function declarations in non-strict block scopes into let variable declarations
  6. BlockStatement visitor preserves non-function statements and ignores direct function body blocks or export declarations
  7. SwitchStatement visitor hoists nested function declarations from case consequents into an enclosing block statement
  8. Loop visitor traverses child blocks within loop structures
  9. Module helpers transform block-scoped function statements using the plugin and Babel core integration

文件

  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • src/index.mjs
  • test/contract.mjs

下载源代码构件 (tar.gz)

源代码

PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: verify pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1
Demonstrate these symbols/APIs:
  - default

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:edc2c92258f5eee741390351acfca2dfc864d9adb3940189f56839b12c634a70","contract":["Plugin default export is a function factory asserting Babel 7 or 8 compatibility range","Plugin factory returns an object named transform-block-scoped-functions with BlockStatement, SwitchStatement, and Loop visitor methods","BlockStatement visitor transforms function declarations in strict-mode block scopes into let variable declarations with blockHoist 2","BlockStatement visitor transforms function declarations in non-strict block scopes into var variable declarations","BlockStatement visitor transforms async or generator function declarations in non-strict block scopes into let variable declarations","BlockStatement visitor preserves non-function statements and ignores direct function body blocks or export declarations","SwitchStatement visitor hoists nested function declarations from case consequents into an enclosing block statement","Loop visitor traverses child blocks within loop structures","Module helpers transform block-scoped function statements using the plugin and Babel core integration"],"goal":"verify pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1","kind":"HOW","packages":["pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1"],"schemaVersion":1,"symbols":["default"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1"],"schemaVersion":1,"subject":"pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1","symbols":["default"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "sample-babel-plugin-transform-block-scoped-functions",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample-babel-plugin-transform-block-scoped-functions",
      "version": "1.0.0",
      "dependencies": {
        "@babel/plugin-transform-block-scoped-functions": "8.0.1"
      }
    },
    "node_modules/@babel/code-frame": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0.tgz",
      "integrity": "sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/helper-validator-identifier": "^8.0.0",
        "js-tokens": "^10.0.0"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/compat-data": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-8.0.0.tgz",
      "integrity": "sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/core": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/@babel/core/-/core-8.0.1.tgz",
      "integrity": "sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/code-frame": "^8.0.0",
        "@babel/generator": "^8.0.0",
        "@babel/helper-compilation-targets": "^8.0.0",
        "@babel/helpers": "^8.0.0",
        "@babel/parser": "^8.0.0",
        "@babel/template": "^8.0.0",
        "@babel/traverse": "^8.0.0",
        "@babel/types": "^8.0.0",
        "@types/gensync": "^1.0.5",
        "convert-source-map": "^2.0.0",
        "empathic": "^2.0.1",
        "gensync": "^1.0.0-beta.2",
        "import-meta-resolve": "^4.2.0",
        "json5": "^2.2.3",
        "obug": "^2.1.1",
        "semver": "^7.7.3"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/babel"
      }
    },
    "node_modules/@babel/generator": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.0.tgz",
      "integrity": "sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/parser": "^8.0.0",
        "@babel/types": "^8.0.0",
        "@jridgewell/gen-mapping": "^0.3.12",
        "@jridgewell/trace-mapping": "^0.3.28",
        "@types/jsesc": "^2.5.0",
        "jsesc": "^3.0.2"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helper-compilation-targets": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-8.0.0.tgz",
      "integrity": "sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/compat-data": "^8.0.0",
        "@babel/helper-validator-option": "^8.0.0",
        "browserslist": "^4.24.0",
        "lru-cache": "^11.0.0",
        "semver": "^7.7.3"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helper-globals": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-8.0.0.tgz",
      "integrity": "sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helper-plugin-utils": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-8.0.1.tgz",
      "integrity": "sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==",
      "license": "MIT",
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      },
      "peerDependencies": {
        "@babel/core": "^8.0.0"
      }
    },
    "node_modules/@babel/helper-string-parser": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.0.tgz",
      "integrity": "sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helper-validator-identifier": {
      "version": "8.0.4",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.4.tgz",
      "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helper-validator-option": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-8.0.0.tgz",
      "integrity": "sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/helpers": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-8.0.0.tgz",
      "integrity": "sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/template": "^8.0.0",
        "@babel/types": "^8.0.0"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/parser": {
      "version": "8.0.4",
      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.4.tgz",
      "integrity": "sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/types": "^8.0.4"
      },
      "bin": {
        "parser": "bin/babel-parser.js"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/plugin-transform-block-scoped-functions": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-8.0.1.tgz",
      "integrity": "sha512-0V97/gcf7LIgPieEiK1YT0eXa18XJFSLOTZjzEZhA9SJIqZhD/IwGUrCitBzXSmnGCP7hchwC6svHtJ/Eidcpg==",
      "license": "MIT",
      "dependencies": {
        "@babel/helper-plugin-utils": "^8.0.1"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      },
      "peerDependencies": {
        "@babel/core": "^8.0.0"
      }
    },
    "node_modules/@babel/template": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-8.0.0.tgz",
      "integrity": "sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/code-frame": "^8.0.0",
        "@babel/parser": "^8.0.0",
        "@babel/types": "^8.0.0"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/traverse": {
      "version": "8.0.4",
      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-8.0.4.tgz",
      "integrity": "sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/code-frame": "^8.0.0",
        "@babel/generator": "^8.0.0",
        "@babel/helper-globals": "^8.0.0",
        "@babel/parser": "^8.0.4",
        "@babel/template": "^8.0.0",
        "@babel/types": "^8.0.4",
        "obug": "^2.1.1"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@babel/types": {
      "version": "8.0.4",
      "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.4.tgz",
      "integrity": "sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@babel/helper-string-parser": "^8.0.0",
        "@babel/helper-validator-identifier": "^8.0.4"
      },
      "engines": {
        "node": "^22.18.0 || >=24.11.0"
      }
    },
    "node_modules/@jridgewell/gen-mapping": {
      "version": "0.3.13",
      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@jridgewell/sourcemap-codec": "^1.5.0",
        "@jridgewell/trace-mapping": "^0.3.24"
      }
    },
    "node_modules/@jridgewell/resolve-uri": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@jridgewell/sourcemap-codec": {
      "version": "1.5.5",
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
      "license": "MIT",
      "peer": true
    },
    "node_modules/@jridgewell/trace-mapping": {
      "version": "0.3.31",
      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "@jridgewell/resolve-uri": "^3.1.0",
        "@jridgewell/sourcemap-codec": "^1.4.14"
      }
    },
    "node_modules/@types/gensync": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.5.tgz",
      "integrity": "sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==",
      "license": "MIT",
      "peer": true
    },
    "node_modules/@types/jsesc": {
      "version": "2.5.1",
      "resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz",
      "integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==",
      "license": "MIT",
      "peer": true
    },
    "node_modules/baseline-browser-mapping": {
      "version": "2.11.19",
      "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz",
      "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==",
      "license": "Apache-2.0",
      "peer": true,
      "bin": {
        "baseline-browser-mapping": "dist/cli.cjs"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/browserslist": {
      "version": "4.28.8",
      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz",
      "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==",
      "funding": [
        {
          "type": "opencollective",
          "url": "https://opencollective.com/browserslist"
        },
        {
          "type": "tidelift",
          "url": "https://tidelift.com/funding/github/npm/browserslist"
        },
        {
          "type": "github",
          "url": "https://github.com/sponsors/ai"
        }
      ],
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "baseline-browser-mapping": "^2.11.12",
        "caniuse-lite": "^1.0.30001809",
        "electron-to-chromium": "^1.5.402",
        "node-releases": "^2.0.53",
        "update-browserslist-db": "^1.3.0"
      },
      "bin": {
        "browserslist": "cli.js"
      },
      "engines": {
        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
      }
    },
    "node_modules/caniuse-lite": {
      "version": "1.0.30001810",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
      "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
      "funding": [
        {
          "type": "opencollective",
          "url": "https://opencollective.com/browserslist"
        },
        {
          "type": "tidelift",
          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
        },
        {
          "type": "github",
          "url": "https://github.com/sponsors/ai"
        }
      ],
      "license": "CC-BY-4.0",
      "peer": true
    },
    "node_modules/convert-source-map": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
      "license": "MIT",
      "peer": true
    },
    "node_modules/electron-to-chromium": {
      "version": "1.5.415",
      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz",
      "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==",
      "license": "ISC",
      "peer": true
    },
    "node_modules/empathic": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz",
      "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=14"
      }
    },
    "node_modules/escalade": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/gensync": {
      "version": "1.0.0-beta.2",
      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/import-meta-resolve": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
      "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
      "license": "MIT",
      "peer": true,
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/wooorm"
      }
    },
    "node_modules/js-tokens": {
      "version": "10.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
      "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
      "license": "MIT",
      "peer": true
    },
    "node_modules/jsesc": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
      "license": "MIT",
      "peer": true,
      "bin": {
        "jsesc": "bin/jsesc"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/json5": {
      "version": "2.2.3",
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
      "license": "MIT",
      "peer": true,
      "bin": {
        "json5": "lib/cli.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/lru-cache": {
      "version": "11.5.2",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
      "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
      "license": "BlueOak-1.0.0",
      "peer": true,
      "engines": {
        "node": "20 || >=22"
      }
    },
    "node_modules/node-releases": {
      "version": "2.0.54",
      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz",
      "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/obug": {
      "version": "2.1.4",
      "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz",
      "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==",
      "funding": [
        "https://github.com/sponsors/sxzz",
        "https://opencollective.com/debug"
      ],
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": ">=12.20.0"
      }
    },
    "node_modules/picocolors": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
      "license": "ISC",
      "peer": true
    },
    "node_modules/semver": {
      "version": "7.8.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
      "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
      "license": "ISC",
      "peer": true,
      "bin": {
        "semver": "bin/semver.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/update-browserslist-db": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz",
      "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==",
      "funding": [
        {
          "type": "opencollective",
          "url": "https://opencollective.com/browserslist"
        },
        {
          "type": "tidelift",
          "url": "https://tidelift.com/funding/github/npm/browserslist"
        },
        {
          "type": "github",
          "url": "https://github.com/sponsors/ai"
        }
      ],
      "license": "MIT",
      "peer": true,
      "dependencies": {
        "escalade": "^3.2.0",
        "picocolors": "^1.1.1"
      },
      "bin": {
        "update-browserslist-db": "cli.js"
      },
      "peerDependencies": {
        "browserslist": ">= 4.21.0"
      }
    }
  }
}
package.json
{
  "name": "sample-babel-plugin-transform-block-scoped-functions",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "@babel/plugin-transform-block-scoped-functions": "8.0.1"
  }
}
spec.json
{
  "schemaVersion": 1,
  "goal": "verify pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1",
  "kind": "HOW",
  "packages": [
    "pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1"
  ],
  "symbols": [
    "default"
  ]
}
src/index.mjs
import blockScopedFunctionsPlugin from '@babel/plugin-transform-block-scoped-functions';
import { transformSync } from '@babel/core';

/**
 * Creates and initializes the block-scoped-functions plugin instance.
 * @param {object} [api] - Optional Babel API object.
 * @param {object} [options] - Optional plugin options.
 * @returns {object} Plugin instance object with name and visitor.
 */
export function createBlockScopedFunctionsPlugin(api, options = {}) {
  const plugin = blockScopedFunctionsPlugin.default || blockScopedFunctionsPlugin;
  const babelApi = api || {
    assertVersion: (range) => Boolean(range)
  };
  return plugin(babelApi, options);
}

/**
 * Transforms JavaScript code using the block-scoped-functions plugin.
 * @param {string} code - Source code to transform.
 * @param {object} [options] - Optional Babel transform options.
 * @returns {string} Transformed code.
 */
export function transformBlockScopedCode(code, options = {}) {
  const plugin = blockScopedFunctionsPlugin.default || blockScopedFunctionsPlugin;
  const result = transformSync(code, {
    plugins: [plugin],
    configFile: false,
    babelrc: false,
    ...options
  });
  return result ? result.code : '';
}

/**
 * Transforms an AST path using the block-scoped-functions visitor methods directly.
 * @param {object} pluginInstance - Plugin instance returned by createBlockScopedFunctionsPlugin.
 * @param {'BlockStatement'|'SwitchStatement'|'Loop'} nodeType - The AST node type to process.
 * @param {object} path - Mock or real Babel AST path.
 */
export function applyBlockScopedTransform(pluginInstance, nodeType, path) {
  if (pluginInstance.visitor && typeof pluginInstance.visitor[nodeType] === 'function') {
    pluginInstance.visitor[nodeType](path);
  }
}
test/contract.mjs
import assert from 'node:assert/strict';
import blockScopedFunctionsPlugin from '@babel/plugin-transform-block-scoped-functions';
import {
  createBlockScopedFunctionsPlugin,
  transformBlockScopedCode,
  applyBlockScopedTransform
} from '../src/index.mjs';

// 1. Verify default export is the plugin factory function and asserts version compatibility
const plugin = blockScopedFunctionsPlugin.default || blockScopedFunctionsPlugin;
assert.equal(typeof plugin, 'function', 'Default export must be a plugin factory function');

let assertedVersion = null;
const mockApi = {
  assertVersion(version) {
    assertedVersion = version;
  }
};
const instance = plugin(mockApi, {});
assert.equal(assertedVersion, '^7.0.0-0 || ^8.0.0', 'Plugin must assert Babel 7 or 8 compatibility range');

// 2. Verify plugin name and visitor structure
assert.equal(typeof instance, 'object', 'Plugin factory must return an object');
assert.equal(instance.name, 'transform-block-scoped-functions', 'Plugin name must be transform-block-scoped-functions');
assert.equal(typeof instance.visitor, 'object', 'Plugin must provide a visitor object');
assert.equal(typeof instance.visitor.BlockStatement, 'function', 'Visitor must provide BlockStatement method');
assert.equal(typeof instance.visitor.SwitchStatement, 'function', 'Visitor must provide SwitchStatement method');
assert.equal(typeof instance.visitor.Loop, 'function', 'Visitor must provide Loop method');

// Helper to construct a mock FunctionDeclaration path
function createMockFunctionPath(name, options = {}) {
  const funcNode = {
    type: 'FunctionDeclaration',
    id: { type: 'Identifier', name },
    params: [],
    body: { type: 'BlockStatement', body: [] },
    async: Boolean(options.async),
    generator: Boolean(options.generator)
  };
  let replacedWith = null;
  const path = {
    node: funcNode,
    isFunctionDeclaration: () => true,
    getData: (key) => (options.data ? options.data[key] : undefined),
    replaceWith: (newNode) => {
      replacedWith = newNode;
    },
    getReplacedNode: () => replacedWith
  };
  return path;
}

// 3. Verify BlockStatement transforms function declarations in strict mode into let declarations with blockHoist 2
{
  const funcPath = createMockFunctionPath('strictFunc');
  const blockPath = {
    node: { type: 'BlockStatement', body: [funcPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => true,
    get: (prop) => (prop === 'body' ? [funcPath] : [])
  };

  instance.visitor.BlockStatement(blockPath);

  const replaced = funcPath.getReplacedNode();
  assert.ok(replaced, 'Function declaration in strict block must be replaced');
  assert.equal(replaced.type, 'VariableDeclaration', 'Replacement must be a VariableDeclaration');
  assert.equal(replaced.kind, 'let', 'Replacement declaration kind must be let in strict mode');
  assert.equal(replaced._blockHoist, 2, 'Replacement declaration must have _blockHoist set to 2');
  assert.equal(replaced.declarations.length, 1, 'Replacement must have one declarator');
  assert.equal(replaced.declarations[0].id.name, 'strictFunc', 'Declarator id must preserve original function name');
  assert.equal(funcPath.node.id, null, 'Original function node id must be anonymized to null');
  assert.equal(replaced.declarations[0].init.type, 'FunctionExpression', 'Declarator init must be a FunctionExpression');
}

// 4. Verify BlockStatement transforms function declarations in non-strict mode into var declarations
{
  const funcPath = createMockFunctionPath('nonStrictFunc');
  const blockPath = {
    node: { type: 'BlockStatement', body: [funcPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => false,
    get: (prop) => (prop === 'body' ? [funcPath] : [])
  };

  instance.visitor.BlockStatement(blockPath);

  const replaced = funcPath.getReplacedNode();
  assert.ok(replaced, 'Function declaration in non-strict block must be replaced');
  assert.equal(replaced.type, 'VariableDeclaration');
  assert.equal(replaced.kind, 'var', 'Replacement declaration kind must be var in non-strict mode');
  assert.equal(replaced._blockHoist, 2);
  assert.equal(replaced.declarations[0].id.name, 'nonStrictFunc');
  assert.equal(funcPath.node.id, null);
}

// 5. Verify BlockStatement transforms async and generator functions in non-strict mode into let declarations
{
  const asyncFuncPath = createMockFunctionPath('asyncFunc', { async: true });
  const blockPathAsync = {
    node: { type: 'BlockStatement', body: [asyncFuncPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => false,
    get: (prop) => (prop === 'body' ? [asyncFuncPath] : [])
  };

  instance.visitor.BlockStatement(blockPathAsync);
  const replacedAsync = asyncFuncPath.getReplacedNode();
  assert.ok(replacedAsync);
  assert.equal(replacedAsync.kind, 'let', 'Async functions in block must use let even in non-strict mode');

  const genFuncPath = createMockFunctionPath('genFunc', { generator: true });
  const blockPathGen = {
    node: { type: 'BlockStatement', body: [genFuncPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => false,
    get: (prop) => (prop === 'body' ? [genFuncPath] : [])
  };

  instance.visitor.BlockStatement(blockPathGen);
  const replacedGen = genFuncPath.getReplacedNode();
  assert.ok(replacedGen);
  assert.equal(replacedGen.kind, 'let', 'Generator functions in block must use let even in non-strict mode');
}

// 6. Verify BlockStatement preserves non-function statements and ignores direct function body blocks or export declarations
{
  let replaced = false;
  const exprPath = {
    node: { type: 'ExpressionStatement' },
    isFunctionDeclaration: () => false,
    replaceWith: () => {
      replaced = true;
    }
  };
  const blockPath = {
    node: { type: 'BlockStatement', body: [exprPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => true,
    get: (prop) => (prop === 'body' ? [exprPath] : [])
  };

  instance.visitor.BlockStatement(blockPath);
  assert.equal(replaced, false, 'Non-function statements must not be replaced');

  const funcPath = createMockFunctionPath('inFunctionBody');
  const blockNode = { type: 'BlockStatement', body: [funcPath.node] };
  const parentFunction = { type: 'FunctionDeclaration', body: blockNode };

  const functionBodyBlockPath = {
    node: blockNode,
    parent: parentFunction,
    isInStrictMode: () => true,
    get: (prop) => (prop === 'body' ? [funcPath] : [])
  };

  instance.visitor.BlockStatement(functionBodyBlockPath);
  assert.equal(funcPath.getReplacedNode(), null, 'Direct function body block must not be transformed');

  const exportFuncPath = createMockFunctionPath('inExport');
  const exportBlockNode = { type: 'BlockStatement', body: [exportFuncPath.node] };
  const parentExport = { type: 'ExportNamedDeclaration' };

  const exportBlockPath = {
    node: exportBlockNode,
    parent: parentExport,
    isInStrictMode: () => true,
    get: (prop) => (prop === 'body' ? [exportFuncPath] : [])
  };

  instance.visitor.BlockStatement(exportBlockPath);
  assert.equal(exportFuncPath.getReplacedNode(), null, 'Block inside export declaration must not be transformed');
}

// 7. Verify SwitchStatement hoists function declarations into an enclosing block statement
{
  const caseFuncNode = {
    type: 'FunctionDeclaration',
    id: { type: 'Identifier', name: 'caseFunc' },
    params: [],
    body: { type: 'BlockStatement', body: [] }
  };
  const switchNode = {
    type: 'SwitchStatement',
    discriminant: { type: 'Identifier', name: 'x' },
    cases: [
      {
        type: 'SwitchCase',
        test: null,
        consequent: [caseFuncNode]
      }
    ]
  };

  let replacedSwitchNode = null;
  const switchPath = {
    node: switchNode,
    replaceWith: (newNode) => {
      replacedSwitchNode = newNode;
    }
  };

  instance.visitor.SwitchStatement(switchPath);

  assert.ok(replacedSwitchNode, 'SwitchStatement with functions must be replaced with enclosing block');
  assert.equal(replacedSwitchNode.type, 'BlockStatement', 'Replacement must be a BlockStatement');
  assert.equal(replacedSwitchNode.body.length, 2, 'Enclosing block must contain hoisted let declaration and switch statement');
  assert.equal(replacedSwitchNode.body[0].type, 'VariableDeclaration');
  assert.equal(replacedSwitchNode.body[0].kind, 'let');
  assert.equal(replacedSwitchNode.body[0].declarations[0].id.name, 'caseFunc');
  assert.equal(replacedSwitchNode.body[1], switchNode, 'Original switch statement must follow hoisted declaration');
  assert.equal(switchNode.cases[0].consequent.length, 0, 'Function declaration must be removed from case consequent');
}

// 8. Verify Loop visitor traverses loop AST subtrees
{
  let traversedWith = null;
  const mockLoopPath = {
    traverse: (vis) => {
      traversedWith = vis;
    }
  };
  instance.visitor.Loop(mockLoopPath);
  assert.ok(traversedWith, 'Loop visitor must call traverse with visitor');
  assert.equal(typeof traversedWith.BlockStatement, 'function', 'Traversed visitor must include BlockStatement');
}

// 9. Verify end-to-end code transformation using Babel core integration
{
  const strictCode = '"use strict";\n{\n  function scoped() { return 42; }\n}';
  const transformedStrict = transformBlockScopedCode(strictCode);
  assert.match(transformedStrict, /let\s+scoped\s*=\s*function/, 'Strict block should transform to let declaration');

  const switchCode = 'switch (x) {\n  case 1:\n    function switchFn() {}\n    break;\n}';
  const transformedSwitch = transformBlockScopedCode(switchCode);
  assert.match(transformedSwitch, /let\s+switchFn\s*=\s*function/, 'Switch statement should hoist function as let declaration');

  const helperPlugin = createBlockScopedFunctionsPlugin();
  assert.equal(helperPlugin.name, 'transform-block-scoped-functions');

  let applyReplaced = null;
  const mockApplyPath = {
    node: {
      type: 'FunctionDeclaration',
      id: { type: 'Identifier', name: 'appliedFn' },
      params: [],
      body: { type: 'BlockStatement', body: [] }
    },
    isFunctionDeclaration: () => true,
    replaceWith: (n) => {
      applyReplaced = n;
    }
  };
  const mockApplyBlock = {
    node: { type: 'BlockStatement', body: [mockApplyPath.node] },
    parent: { type: 'Program' },
    isInStrictMode: () => true,
    get: (prop) => (prop === 'body' ? [mockApplyPath] : [])
  };
  applyBlockScopedTransform(helperPlugin, 'BlockStatement', mockApplyBlock);
  assert.ok(applyReplaced, 'applyBlockScopedTransform should execute visitor method');
}

console.log('All contract assertions passed successfully.');

原始种子者

匿名