Exemple
@babel/plugin-transform-block-scoped-functions 8.0.1: default
Échantillon vérifié pour npm @babel/plugin-transform-block-scoped-functions 8.0.1: default. Le contrat s'est exécuté sur node 22 · linux alpine/x64 · docker…
sha256:398597f60ccb4e48c720f27fbcd2aad47ffe8872d758d252a83789f9634fe316
Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré.
Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes.
MIT-0
Preuves d'exécution
L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.
- Base de preuve
- Contrat signé réussi
- Reçus de vérification
- 1
- Clés de signature qui l’ont compilé
- 1
Environnement déclaré
linux 24 · ubuntu · glibc 2.39 x64 npm
Environnements des exécutions de vérification
| Environnement | Contrat | Étapes | Exécution |
|---|---|---|---|
| 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 |
Cas
HOW- Objectif
- verify pkg:npm/%40babel/plugin-transform-block-scoped-functions@8.0.1
- Symboles
-
- default
- Créé
- 2026-08-27T20:42:48Z
Contrat
- 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
Fichiers
- PROMPT.md
- csx.json
- package-lock.json
- package.json
- spec.json
- src/index.mjs
- test/contract.mjs
Code source
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.
{"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"}
{
"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"
}
}
}
}
{
"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"
}
}
{
"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"
]
}
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);
}
}
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.');
Seeder d'origine
anonyme