Skip to content

feat(http-client-python): migrate eng scripts from tsx to native Node.js TypeScript - #11425

Draft
timotheeguerin with Copilot wants to merge 6 commits into
mainfrom
copilot/migrate-to-native-node-typescript
Draft

feat(http-client-python): migrate eng scripts from tsx to native Node.js TypeScript#11425
timotheeguerin with Copilot wants to merge 6 commits into
mainfrom
copilot/migrate-to-native-node-typescript

Conversation

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Mirrors the change from Azure/typespec-azure#5068: replace tsx as the TypeScript script runner with Node.js native TypeScript support (Node 22+ strips types natively).

Changes

  • package.json: Replace all tsx ./eng/scripts/... invocations with node ./eng/scripts/...; remove tsx from dependencies
  • eng/scripts/setup/*.ts and eng/scripts/ci/regenerate.ts: Change relative imports from .js.ts extensions (required for native Node TS resolution)
  • Help text / comments: Update tsx <script>.ts usage examples to node <script>.ts

…js TypeScript

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:python Issue for the Python client emitter: @typespec/http-client-python label Jul 28, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Comment thread packages/http-client-python/package.json
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Python emitter diff

Baseline gh:c2bcc2bf54a3dab270948b8b5dc843b729149994 vs this PR.

No changes to generated output.

Rendered diff: inline on the run summary, or the emitter-diff-html artifact.

Informational check (eng/emitter-diff); does not block the PR.

@timotheeguerin

Copy link
Copy Markdown
Member

@copilot the build is failing did you check it was passing?

Installing npm dependencies...
> npm ci

> @typespec/http-client-python@0.35.0 install
> node ./eng/scripts/setup/install.ts

file:///mnt/vss/_work/1/s/packages/http-client-python/eng/scripts/setup/system-requirements.ts:1
import { ChildProcess, spawn, SpawnOptions } from "child_process";
                              ^^^^^^^^^^^^
SyntaxError: The requested module 'child_process' does not provide an export named 'SpawnOptions'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:226:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:335:5)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)

Node.js v22.23.1
npm error code 1
npm error path /mnt/vss/_work/1/s/packages/http-client-python
npm error command failed
npm error command sh -c node ./eng/scripts/setup/install.ts
npm error A complete log of this run can be found in: /home/cloudtest/.npm/_logs/2026-07-28T17_42_30_653Z-debug-0.log
Invoke-LoggedCommand: /mnt/vss/_work/1/s/packages/http-client-python/eng/scripts/Initialize-Repository.ps1:42

…atibility

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot the build is failing did you check it was passing?

Installing npm dependencies...

...

Fixed in the latest commit. The root cause: Node.js native type stripping doesn't do import elision — it strips type annotations but leaves import statements untouched. SpawnOptions (an interface in child_process) and RegenerateContext/RegenerateFlags (interfaces in regenerate-common.ts) were imported as values, which fails at runtime since they have no runtime representation. Added the type keyword inline on those imports:

  • system-requirements.ts: import { ChildProcess, spawn, type SpawnOptions }
  • regenerate.ts: type RegenerateContext, type RegenerateFlags

@timotheeguerin

Copy link
Copy Markdown
Member

@copilot still failing

pm install typespec-http-client-python-0.35.0.tgz
npm error code 1
npm error path /mnt/vss/_work/1/s/packages/http-client-python/node_modules/@typespec/http-client-python
npm error command failed
npm error command sh -c node ./eng/scripts/setup/install.ts
npm error node:internal/modules/typescript:183
npm error throw new ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING(filename);
npm error ^
npm error
npm error Error [ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING]: Stripping types is currently unsupported for files under node_modules, for "file:///mnt/vss/_work/1/s/packages/http-client-python/node_modules/@typespec/http-client-python/eng/scripts/setup/install.ts"
npm error at stripTypeScriptModuleTypes (node:internal/modules/typescript:183:11)
npm error at ModuleLoader. (node:internal/modules/esm/translators:680:29)
npm error at #translate (node:internal/modules/esm/loader:434:20)
npm error at afterLoad (node:internal/modules/esm/loader:502:29)
npm error at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:507:12)
npm error at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:560:36)
npm error at afterResolve (node:internal/modules/esm/loader:607:52)
npm error at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:613:12)
npm error at node:internal/modules/esm/loader:632:32
npm error at TracingChannel.tracePromise (node:diagnostics_channel:362:14) {
npm error code: 'ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING'
npm error }
npm error
npm error Node.js v24.18.0
npm error A complete log of this run can be found in: /home

…modules type stripping

- Create eng/scripts/setup/install-runner.js and prepare-runner.js as plain
  JavaScript bootstrappers that work in any Node.js context (including under
  node_modules where type stripping is not allowed)
- Create eng/scripts/setup/tsconfig.build.json to compile setup scripts to
  dist/scripts/setup/ using rewriteRelativeImportExtensions so .ts imports
  become .js in the compiled output
- Update package.json: install/prepare lifecycle scripts use the .js runners;
  build step now also compiles setup scripts to dist/

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot still failing

pm install typespec-http-client-python-0.35.0.tgz
...

Fixed in the latest commit.

Root cause: Node.js 22+ native TypeScript type stripping is explicitly disabled for files under node_modules — even though the .ts source and .ts-extension imports work fine in the repo's own dev context, they fail when the package is installed as a dependency.

Fix:

  1. eng/scripts/setup/tsconfig.build.json — new TypeScript config that compiles all eng/scripts/setup/*.tsdist/scripts/setup/*.js, using rewriteRelativeImportExtensions: true (TS 5.7+) so .ts import specifiers become .js in the compiled output.

  2. install-runner.js / prepare-runner.js — small plain-JavaScript bootstrappers (no TypeScript syntax) that:

    • Use the pre-compiled dist/scripts/setup/install.js when available (i.e., when installed from npm/tgz — the dist/** is already in files)
    • Fall back to native TS stripping on ./install.ts in the dev/repo context (not under node_modules)
  3. package.json:

    • install: now node ./eng/scripts/setup/install-runner.js
    • prepare: now node ./eng/scripts/setup/prepare-runner.js
    • build: appends && tsc -p ./eng/scripts/setup/tsconfig.build.json so the compiled JS is always present in the tgz

@timotheeguerin

Copy link
Copy Markdown
Member

@copilot still failing the build

29:5 warning Unexpected console statement no-console

/mnt/vss/_work/1/s/packages/http-client-python/eng/scripts/setup/prepare-runner.js
29:5 warning Unexpected console statement no-console

✖ 2 problems (0 errors, 2 warnings)

ESLint found too many warnings (maximum: 0).
[FAIL] eslint emitter/ eng/scripts/ --max-warnings=0 failed with code 1

=== Linting Python Generator (pygen) ===

[RUN] /mnt/vss/_work/1/s/packages/http-client-python/venv/bin/python -m pylint generator/pygen --rcfile=eng/scripts/ci/config/pylintrc --recursive=y --py-version=3.10


Your code has been rated at 10.00/10

[PASS] /mnt/vss/_work/1/s/packages/http-client-python/venv/bin/python completed successfully
Invoke-LoggedCommand: /mnt/vss/_work/1/s/packages/http-client-python/eng/scripts/Build-Packages.ps1:87
Line |
87 | Invoke-LoggedCommand "npm run lint" -GroupOutput
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ##[error]Command completed with exit code 1 (00:00:15.6450394): npm run
| lint

##[error]PowerShell e

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot still failing the build

29:5 warning Unexpected console statement no-console
...

Fixed — added // eslint-disable-line no-console to the console.log statements in both install-runner.js and prepare-runner.js, matching the convention used throughout the other scripts in the package.

@pkg-pr-new

pkg-pr-new Bot commented Jul 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-python@11425

commit: 9c9118b

@timotheeguerin

Copy link
Copy Markdown
Member

@copilot still failing


=== Creating npm package ===
> npm pack

> @typespec/http-client-python@0.35.0 prepare
> node ./eng/scripts/setup/prepare-runner.js

node:internal/modules/esm/load:199
    throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, schemes);
          ^

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'd:'
    at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:199:11)
    at defaultLoadSync (node:internal/modules/esm/load:146:3)
    at ModuleLoader.load (node:internal/modules/esm/loader:831:12)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:609:31)
    at #createModuleJob (node:internal/modules/esm/loader:640:36)
    at #getJobFromResolveResult (node:internal/modules/esm/loader:353:34)
    at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:321:41)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:680:25) {
  code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}

Node.js v22.23.1
npm error code 1
npm error path D:\a\_work\1\s\packages\http-client-python
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c node ./eng/scripts/setup/prepare-runner.js
npm error A complete log of this run can be found in: C:\npm\cache\_logs\2026-07-28T20_38_06_518Z-debug-0.log
Invoke-LoggedCommand : ##[error]Command completed with exit code 1 (00:00:00.9767322): npm pack


DO test the FULL build locally and make sure it passes

also pull main and merge conflicts

…tive-node-typescript

# Conflicts:
#	packages/http-client-python/package.json

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot still failing


...

Fixed in the latest commits. The Windows failure was ERR_UNSUPPORTED_ESM_URL_SCHEME because ESM import() requires file:// URLs — passing a raw D:\... path fails. Both runner files now use pathToFileURL(compiledPath).href before the dynamic import. Also merged main (which added the check-unstaged script to ci).

@timotheeguerin

Copy link
Copy Markdown
Member

@copilot run formatter

Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com>

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run formatter

Done — sorted the node:url/node:path imports into alphabetical order in both install-runner.js and prepare-runner.js (the only files that had out-of-order imports after the prettier-plugin-organize-imports check).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:python Issue for the Python client emitter: @typespec/http-client-python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants