fix(task): set npm lifecycle env vars when running package.json scripts (#35252)
Fixes #35251
When running a `package.json` script (via `deno task`/`deno run
<script>`), Deno did not set the npm lifecycle environment variables
that npm sets. This meant scripts relying on `npm_package_*` /
`npm_lifecycle_*` vars behaved differently under Deno than under npm.
## What
When executing a package.json script, Deno now sets, to match npm v11:
- `npm_package_name`
- `npm_package_version`
- `npm_package_json` — absolute path to the `package.json`
- `npm_package_config_<key>` — flattened from the package.json
`"config"` object (nested objects/arrays are flattened with `_`, scalar
leaves stringified)
- `npm_lifecycle_event` — the script name being executed (e.g. `preenv`,
`env`, `postenv`)
- `npm_lifecycle_script` — the script command string
These are only set for package.json scripts — `deno.json` tasks are
unaffected, since these variables carry npm-package semantics.
### Example
```jsonc
{
"name": "env-var-test",
"version": "1.0.0",
"config": { "myvar": "myval" },
"scripts": { "env": "env | grep npm_package" }
}
```
now prints `npm_package_config_myvar=myval`,
`npm_package_name=env-var-test`, `npm_package_json=…/package.json`,
etc., matching npm.
## How
- `libs/package_json/lib.rs`: added a `config` field to `PackageJson`
and parsed it in the manual `load_from_value` deserializer.
- `cli/tools/task.rs`: `run_npm_script` looks up the script folder's
`PackageJson` and threads npm env vars (via a new `extra_env_vars` on
`RunSingleOptions`) into the script's environment;
`npm_lifecycle_event`/`npm_lifecycle_script` are set per pre/post/main
iteration.
## Test
Added a cross-platform spec test under
`tests/specs/task/package_json_env_vars/` covering name, version, json
path, flattened config (scalar/nested/array/boolean), and the pre/post
lifecycle event names.
---------
Co-authored-by: Nathan Whitaker <nathan@deno.com>