chore: Upgrade to TypeScript 6.0.3 and API Extractor 7.x - #3315
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 1774427. Configure here.
Move from TypeScript 5.8 to 6.0.3 (via a 5.9 checkpoint) and migrate the declaration rollup from api-extractor 6.3.0 to 7.58.9. Adjustments for TS 6.0 breaking changes: - tsconfig.base.json: set "ignoreDeprecations": "6.0" (baseUrl, moduleResolution node10, target es5) and "types": ["*"] to restore the pre-6.0 automatic @types global inclusion. - ts-loader now uses an explicit configFile with onlyCompileBundledFiles so the webpack build type-checks only bundled files, not the whole repo. - build-dts passes --rootDir .. (TS 6.0 no longer infers rootDir) and strips api-extractor 7.x "export { }" markers so consumers can import the SDK's bare-declared types, matching the long-standing published .d.ts shape. - Migrated 6 api-extractor configs and the auto-export generator to the 7.x schema. - .npmrc legacy-peer-deps=true works around @bigcommerce/eslint-config's stale optional typescript peer (^4 || ^5); added @bigcommerce/eslint-plugin as a direct devDep so ESLint resolves it.
The two api-extractor runs were joined with a single "&", leaving the iframe-content rollup backgrounded with no "wait". The following declaration strip and "rm -rf ../../temp" could run before it finished, risking an unstripped hosted-form-v2-iframe-content.d.ts or removing temp mid-read. Add a trailing "& wait" to match the core build-dts target.
1aedde4 to
6e96f5e
Compare
bc-maxy
left a comment
There was a problem hiding this comment.
Looks good to me overall, thanks for doing it, just curious about the es5 comment
es5 is deprecated in TypeScript 6.0. The target is inert for API Extractor's .d.ts-only analysis (explicit lib is set), so the rolled-up public type surface is unchanged; switching to es6 aligns with the base tsconfig and removes the deprecated option.
richapatel1510
left a comment
There was a problem hiding this comment.
Since dist/ typings only get regenerated at release, I built this branch locally to see the v7 output before it ships. Everything's green, and the diff vs. committed typings is ~1,700 lines of harmless alias-renaming churn — the upgrade itself looks good. The only real issues are the two inline comments (perl strip deleting real exports, and & wait swallowing extractor failures). With the anchored regex, the output comes out correct.
| "tsc --outDir ../../temp --rootDir .. --declaration --emitDeclarationOnly", | ||
| "api-extractor run --config api-extractor/checkout-sdk.json & api-extractor run --config api-extractor/checkout-button.json & api-extractor run --config api-extractor/embedded-checkout.json & api-extractor run --config api-extractor/internal-mappers.json & wait", | ||
| "find src/generated/integrations -name 'api-extractor.json' | xargs -I {} -P 8 sh -c 'cd \"$(dirname \"{}\")\" && npx api-extractor run --config api-extractor.json'", | ||
| "find ../../dist/types -name '*.d.ts' -type f -exec perl -i -ne 'print unless /^export \\{.*\\}\\s*$/' {} +", |
There was a problem hiding this comment.
I ran build-dts on this branch to check the new output — the regex here catches more than the trailing export { }. API Extractor 7 also emits real exports in this form (no semicolon), and the raw output has export { createTimeout } in both checkout-sdk.d.ts and checkout-button.d.ts. The perl step deletes those too, so createTimeout disappears from the published typings. Funnily enough, v7 was actually fixing this — the current typings have the import but no export, and this strip reverts the fix.
Anchoring it to the empty marker fixes it:
perl -i -ne 'print unless /^export \{\s*\}\s*$/'
Same change needed in hosted-form-v2's project.json.
There was a problem hiding this comment.
@richapatel1510 I think I need a bit of guidance on this one.
When I try your suggestion perl -i -ne 'print unless /^export \{\s*\}\s*$/', only 20 typedoc files are output vs 590 - any export { … } block (even export { createTimeout }) flips the entry file into explicit-export mode, so typedoc stops documenting the bare declares.
If I apply the narrow strip to the types only (a hybrid), createTimeout() gets exported and the docs stay at 590. Consumer imports are unaffected either way.
If I keep the broad strip as-is, createTimeout() isn't exported - but am I wrong in saying it's also not exported on main today?
So I'm leaning toward the hybrid. Does that work for you, or would you rather handle it differently?
There was a problem hiding this comment.
Hey @bc-0dp ,
Dug into this properly and you're right — keeping the broad strip is correct. Any surviving export { ... } statement (even from my suggested regex) flips the .d.ts out of implicit-export mode, and I confirmed with tsc that the narrow version breaks imports of most public types, while your version matches the exact surface published today. So: as-is is right, withdrawing my suggestion.
On createTimeout — confirmed it's already missing on main, so nothing for this PR. (For a follow-up: "bundledPackages": ["@bigcommerce/request-sender"] in checkout-sdk.json makes API Extractor inline it and would fix it properly.)
build-dts: capture api-extractor PIDs and wait per-PID so a failing run surfaces a non-zero exit; previously `& wait` always exited 0 and masked extractor failures. Applies to core and hosted-form-v2. deps: replace .npmrc legacy-peer-deps with a scoped @bigcommerce/eslint-config typescript override, which cascades to the nested eslint-plugin; drop the now-unneeded direct @bigcommerce/eslint-plugin devDep and regenerate the lockfile.
richapatel1510
left a comment
There was a problem hiding this comment.
Nice work! 👏 👏
Thanks for doing this 🙇

What/Why?
Upgrade the SDK from TypeScript 5.8 to 6.0.3 (via a 5.9 checkpoint), ahead of the eventual TypeScript 7 (native) move. TS 6.0 is a transitional release; its breaking changes are handled here. Also migrates the declaration rollup from
@microsoft/api-extractor6.3.0 (bundled TS 3.1) to 7.58.9.Key changes:
tsconfig.base.json:"ignoreDeprecations": "6.0"(silencesbaseUrl,moduleResolutionnode10, andtargetes5 pending the TS 7 migration) and"types": ["*"]to restore the pre-6.0 automatic@typesglobal inclusion.configFilewithonlyCompileBundledFiles, so the webpack build type-checks only bundled files, not the whole repo (TS 6.0 defaultsstrict: trueandtypes: []).build-dtspasses--rootDir ..(TS 6.0 no longer infers rootDir for the multi-package emit) and strips api-extractor 7.xexport { }markers, so consumers keep importing the SDK's bare-declared types, matching the long-standing published.d.tsshape.auto-exportgenerator to the 7.x schema..npmrclegacy-peer-deps=trueworks around@bigcommerce/eslint-config's stale optionaltypescriptpeer (^4 || ^5); added@bigcommerce/eslint-pluginas a direct devDep so ESLint resolves it.Reviewer note: the
docs/diff includes api-extractor 7.x numeric disambiguation renames (e.g.Omit.mdbecomesOmit_2.md,PaymentProviderCustomerTypebecomesPaymentProviderCustomer_2). Content is unchanged; only the internal collision labels differ.Rollout/Rollback
Tooling and build-config change only. No runtime feature flags, experiments, or migrations. The published JS bundles are behavior-equivalent (Babel still targets the existing browserslist); only the
.d.tsstructure and build config change. Rollback is a straight revert of this branch.Testing
lint(52 projects),test(core 2478 tests plus 51 other projects),build,bundle-dts,docs(587 files),build-cdn.typecheckoutput is byte-identical to the published-SDK baseline (214 pre-existing errors on itsmaster, 0 new).TS2459"declared locally but not exported" count is 0, confirming theexport { }strip.buildpasses; the test suite reports 1324 pass with 2 pre-existing failures unrelated to the SDK.Note
Medium Risk
Changes affect the published
.d.tspipeline and monorepo typecheck scope; consumer typecheck was validated against checkout-js but any downstream relying on exact declaration formatting could still be sensitive.Overview
Upgrades the monorepo from TypeScript 5.8 to 6.0.3 (with a 5.9 checkpoint) and @microsoft/api-extractor from 6.x to 7.58.9, as prep for a future TypeScript 7 move. Runtime JS is unchanged (Babel/browserslist); impact is build tooling and published
.d.tsshape.TypeScript 6 defaults (
strict, emptytypes) are offset intsconfig.base.jsonviaignoreDeprecations: "6.0"andtypes: ["*"]. Webpack ts-loader now uses an explicitconfigFileandonlyCompileBundledFilesso the bundle build type-checks only entry graphs, not the whole repo.Declaration rollup passes
--rootDir ..ontsc(TS 6 no longer infers rootDir for multi-package emit), updates six api-extractor configs plus theauto-exportgenerator to the 7.x schema, and strips api-extractor 7’sexport { }markers so consumers keep the same bare-declared import surface. hosted-form-v2 follows the samebuild-dtspattern.npm/ESLint:
legacy-peer-depsand a direct@bigcommerce/eslint-plugindevDep address stale TypeScript peer ranges on@bigcommerce/eslint-config. Generated docs only rename collision suffixes (e.g.Omit_2.md); content is unchanged.Reviewed by Cursor Bugbot for commit eb1229f. Bugbot is set up for automated code reviews on this repo. Configure here.