Skip to content

Commit d6a1686

Browse files
authored
feat(target): add support for baseline-widely-available target (#896)
1 parent c8f5c71 commit d6a1686

12 files changed

Lines changed: 129 additions & 33 deletions

File tree

dts.snapshot.json

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"config-!~{00c}~.d.mts": {
2+
"config-!~{00d}~.d.mts": {
33
"defineConfig": "declare function defineConfig(_: UserConfigExport): UserConfigExport",
44
"mergeConfig": "declare function mergeConfig(_: InlineConfig, ...overrides: InlineConfig[]): InlineConfig",
55
"resolveUserConfig": "declare function resolveUserConfig(_: UserConfig, _: InlineConfig): Promise<ResolvedConfig[]>"
@@ -13,6 +13,29 @@
1313
"mergeConfig"
1414
]
1515
},
16+
"index-!~{00b}~.d.mts": {
17+
"Arrayable": "type Arrayable<T> = T | T[]",
18+
"Awaitable": "type Awaitable<T> = T | Promise<T>",
19+
"globalLogger": "Logger",
20+
"Logger": "interface Logger {\n level: LogLevel\n options?: LoggerOptions\n info: (...args: any[]) => void\n warn: (...args: any[]) => void\n warnOnce: (...args: any[]) => void\n error: (...args: any[]) => void\n success: (...args: any[]) => void\n clearScreen: (_: LogType) => void\n}",
21+
"LoggerOptions": "interface LoggerOptions {\n allowClearScreen?: boolean\n customLogger?: Logger\n console?: Console\n failOnWarn?: boolean\n}",
22+
"LogLevel": "type LogLevel = LogType | 'silent'",
23+
"LogType": "type LogType = 'error' | 'warn' | 'info'",
24+
"MarkPartial": "type MarkPartial<T, K extends keyof T> = Omit<Required<T>, K> & Partial<Pick<T, K>>",
25+
"Overwrite": "type Overwrite<T, U> = Omit<T, keyof U> & U",
26+
"PackageJson": "interface PackageJson {\n name?: string\n version?: string\n description?: string\n keywords?: string[]\n homepage?: string\n bugs?: string | { url?: string; email?: string }\n license?: string\n repository?: string | { type: string; url: string; directory?: string }\n scripts?: PackageJsonScripts\n private?: boolean\n author?: PackageJsonPerson\n contributors?: PackageJsonPerson[]\n funding?: PackageJsonFunding | PackageJsonFunding[]\n files?: string[]\n main?: string\n browser?: string | Record<string, string | false>\n unpkg?: string\n bin?: string | Record<string, string>\n man?: string | string[]\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n types?: string\n typings?: string\n module?: string\n type?: 'module' | 'commonjs'\n exports?: PackageJsonExports\n imports?: Record<string, string | Record<string, string>>\n workspaces?: string[] | { packages?: string[]; nohoist?: string[] }\n typesVersions?: Record<string, Record<string, string[]>>\n os?: string[]\n cpu?: string[]\n publishConfig?: { registry?: string; tag?: string; access?: 'public' | 'restricted'; executableFiles?: string[]; directory?: string; linkDirectory?: boolean } & Pick<PackageJson, 'bin' | 'main' | 'exports' | 'types' | 'typings' | 'module' | 'browser' | 'unpkg' | 'typesVersions' | 'os' | 'cpu'>\n packageManager?: string\n [key: string]: any\n}",
27+
"PackageJsonCommonScripts": "type PackageJsonCommonScripts = 'build' | 'coverage' | 'deploy' | 'dev' | 'format' | 'lint' | 'preview' | 'release' | 'typecheck' | 'watch'",
28+
"PackageJsonExportKey": "type PackageJsonExportKey = '.' | 'import' | 'require' | 'types' | 'node' | 'browser' | 'default' | (string & {})",
29+
"PackageJsonExports": "type PackageJsonExports = string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject>",
30+
"PackageJsonExportsObject": "type PackageJsonExportsObject = { [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject> }",
31+
"PackageJsonFunding": "type PackageJsonFunding = string | { url: string; type?: string }",
32+
"PackageJsonNpmLifeCycleScripts": "type PackageJsonNpmLifeCycleScripts = 'dependencies' | 'prepublishOnly' | PackageJsonScriptWithPreAndPost<'install' | 'pack' | 'prepare' | 'publish' | 'restart' | 'start' | 'stop' | 'test' | 'version'>",
33+
"PackageJsonPerson": "type PackageJsonPerson = string | { name: string; email?: string; url?: string }",
34+
"PackageJsonPnpmLifeCycleScripts": "type PackageJsonPnpmLifeCycleScripts = 'pnpm:devPreinstall'",
35+
"PackageJsonScriptName": "type PackageJsonScriptName = PackageJsonCommonScripts | PackageJsonNpmLifeCycleScripts | PackageJsonPnpmLifeCycleScripts | (string & {})",
36+
"PackageJsonScripts": "type PackageJsonScripts = { [P in PackageJsonScriptName]?: string }",
37+
"PackageJsonScriptWithPreAndPost": "type PackageJsonScriptWithPreAndPost<S extends string> = S | `${'pre' | 'post'}${S}`"
38+
},
1639
"index.d.mts": {
1740
"build": "declare function build(_: InlineConfig): Promise<TsdownBundle[]>",
1841
"buildWithConfigs": "declare function buildWithConfigs(_: ResolvedConfig[], _: string[], _: () => void): Promise<TsdownBundle[]>",
@@ -71,6 +94,7 @@
7194
]
7295
},
7396
"internal.d.mts": {
97+
"expandBaselineTarget": "declare function expandBaselineTarget(_: string[]): string[]",
7498
"fsExists": "declare function fsExists(_: string): Promise<boolean>",
7599
"fsRemove": "declare function fsRemove(_: string): Promise<void>",
76100
"importWithError": "declare function importWithError<T>(_: string): Promise<T>",
@@ -80,24 +104,14 @@
80104
"Logger",
81105
"MarkPartial",
82106
"Overwrite",
107+
"expandBaselineTarget",
83108
"fsExists",
84109
"fsRemove",
85110
"importWithError",
86111
"resolveComma",
87112
"toArray"
88113
]
89114
},
90-
"logger-!~{00a}~.d.mts": {
91-
"Arrayable": "type Arrayable<T> = T | T[]",
92-
"Awaitable": "type Awaitable<T> = T | Promise<T>",
93-
"globalLogger": "Logger",
94-
"Logger": "interface Logger {\n level: LogLevel\n options?: LoggerOptions\n info: (...args: any[]) => void\n warn: (...args: any[]) => void\n warnOnce: (...args: any[]) => void\n error: (...args: any[]) => void\n success: (...args: any[]) => void\n clearScreen: (_: LogType) => void\n}",
95-
"LoggerOptions": "interface LoggerOptions {\n allowClearScreen?: boolean\n customLogger?: Logger\n console?: Console\n failOnWarn?: boolean\n}",
96-
"LogLevel": "type LogLevel = LogType | 'silent'",
97-
"LogType": "type LogType = 'error' | 'warn' | 'info'",
98-
"MarkPartial": "type MarkPartial<T, K extends keyof T> = Omit<Required<T>, K> & Partial<Pick<T, K>>",
99-
"Overwrite": "type Overwrite<T, U> = Omit<T, keyof U> & U"
100-
},
101115
"plugins.d.mts": {
102116
"NodeProtocolPlugin": "declare function NodeProtocolPlugin(_: 'strip' | true): Plugin",
103117
"ShebangPlugin": "declare function ShebangPlugin(_: Logger, _: string, _: string, _: boolean): Plugin",
@@ -113,7 +127,7 @@
113127
"run.d.mts": {
114128
"#exports": []
115129
},
116-
"types-!~{00b}~.d.mts": {
130+
"types-!~{00c}~.d.mts": {
117131
"AttwOptions": "interface AttwOptions extends CheckPackageOptions {\n module?: typeof _$_arethetypeswrong_core0\n profile?: 'strict' | 'node16' | 'esm-only'\n level?: 'error' | 'warn'\n ignoreRules?: ('no-resolution' | 'untyped-resolution' | 'false-cjs' | 'false-esm' | 'cjs-resolves-to-esm' | 'fallback-condition' | 'cjs-only-exports-default' | 'named-exports' | 'false-export-default' | 'missing-export-equals' | 'unexpected-module-syntax' | 'internal-resolution-error' | (string & {}))[]\n}",
118132
"BuildContext": "interface BuildContext {\n options: ResolvedConfig\n hooks: Hookable<TsdownHooks>\n}",
119133
"ChunkAddon": "type ChunkAddon = ChunkAddonObject | ChunkAddonFunction | string",
@@ -137,18 +151,6 @@
137151
"OutExtensionContext": "interface OutExtensionContext {\n options: InputOptions\n format: NormalizedFormat\n pkgType?: PackageType\n}",
138152
"OutExtensionFactory": "type OutExtensionFactory = (_: OutExtensionContext) => OutExtensionObject | undefined",
139153
"OutExtensionObject": "interface OutExtensionObject {\n js?: string\n dts?: string\n}",
140-
"PackageJson": "interface PackageJson {\n name?: string\n version?: string\n description?: string\n keywords?: string[]\n homepage?: string\n bugs?: string | { url?: string; email?: string }\n license?: string\n repository?: string | { type: string; url: string; directory?: string }\n scripts?: PackageJsonScripts\n private?: boolean\n author?: PackageJsonPerson\n contributors?: PackageJsonPerson[]\n funding?: PackageJsonFunding | PackageJsonFunding[]\n files?: string[]\n main?: string\n browser?: string | Record<string, string | false>\n unpkg?: string\n bin?: string | Record<string, string>\n man?: string | string[]\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n types?: string\n typings?: string\n module?: string\n type?: 'module' | 'commonjs'\n exports?: PackageJsonExports\n imports?: Record<string, string | Record<string, string>>\n workspaces?: string[] | { packages?: string[]; nohoist?: string[] }\n typesVersions?: Record<string, Record<string, string[]>>\n os?: string[]\n cpu?: string[]\n publishConfig?: { registry?: string; tag?: string; access?: 'public' | 'restricted'; executableFiles?: string[]; directory?: string; linkDirectory?: boolean } & Pick<PackageJson, 'bin' | 'main' | 'exports' | 'types' | 'typings' | 'module' | 'browser' | 'unpkg' | 'typesVersions' | 'os' | 'cpu'>\n packageManager?: string\n [key: string]: any\n}",
141-
"PackageJsonCommonScripts": "type PackageJsonCommonScripts = 'build' | 'coverage' | 'deploy' | 'dev' | 'format' | 'lint' | 'preview' | 'release' | 'typecheck' | 'watch'",
142-
"PackageJsonExportKey": "type PackageJsonExportKey = '.' | 'import' | 'require' | 'types' | 'node' | 'browser' | 'default' | (string & {})",
143-
"PackageJsonExports": "type PackageJsonExports = string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject>",
144-
"PackageJsonExportsObject": "type PackageJsonExportsObject = { [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject> }",
145-
"PackageJsonFunding": "type PackageJsonFunding = string | { url: string; type?: string }",
146-
"PackageJsonNpmLifeCycleScripts": "type PackageJsonNpmLifeCycleScripts = 'dependencies' | 'prepublishOnly' | PackageJsonScriptWithPreAndPost<'install' | 'pack' | 'prepare' | 'publish' | 'restart' | 'start' | 'stop' | 'test' | 'version'>",
147-
"PackageJsonPerson": "type PackageJsonPerson = string | { name: string; email?: string; url?: string }",
148-
"PackageJsonPnpmLifeCycleScripts": "type PackageJsonPnpmLifeCycleScripts = 'pnpm:devPreinstall'",
149-
"PackageJsonScriptName": "type PackageJsonScriptName = PackageJsonCommonScripts | PackageJsonNpmLifeCycleScripts | PackageJsonPnpmLifeCycleScripts | (string & {})",
150-
"PackageJsonScripts": "type PackageJsonScripts = { [P in PackageJsonScriptName]?: string }",
151-
"PackageJsonScriptWithPreAndPost": "type PackageJsonScriptWithPreAndPost<S extends string> = S | `${'pre' | 'post'}${S}`",
152154
"PackageJsonWithPath": "interface PackageJsonWithPath extends PackageJson {\n packageJsonPath: string\n}",
153155
"PackageType": "type PackageType = 'module' | 'commonjs' | undefined",
154156
"PublintOptions": "interface PublintOptions extends Omit<Options, 'pack' | 'pkgDir'> {\n module?: [typeof _$publint, typeof _$publint_utils0]\n}",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
"@vitest/coverage-v8": "catalog:dev",
157157
"@vitest/ui": "catalog:dev",
158158
"@vueuse/core": "catalog:docs",
159+
"baseline-browser-mapping": "catalog:dev",
159160
"bumpp": "catalog:dev",
160161
"dedent": "catalog:dev",
161162
"eslint": "catalog:dev",

packages/css/src/options.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
expandBaselineTarget,
23
resolveComma,
34
toArray,
45
type MarkPartial,
@@ -213,7 +214,7 @@ export function resolveCssOptions(
213214
} else if (options.target == null) {
214215
cssTarget = topLevelTarget
215216
} else {
216-
cssTarget = resolveComma(toArray(options.target))
217+
cssTarget = expandBaselineTarget(resolveComma(toArray(options.target)))
217218
}
218219

219220
return {

pnpm-lock.yaml

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ catalogs:
2121
'@typescript/native-preview': 7.0.0-dev.20260405.1
2222
'@vitest/coverage-v8': ^4.1.2
2323
'@vitest/ui': ^4.1.2
24+
baseline-browser-mapping: ^2.10.16
2425
bumpp: ^11.0.1
2526
dedent: ^1.7.2
2627
eslint: ^10.2.0

scripts/generate-target.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { getCompatibleVersions } from 'baseline-browser-mapping'
2+
3+
// Update on each major release
4+
const targetDate = '2026-01-01'
5+
6+
// https://oxc.rs/docs/guide/usage/transformer/lowering#target
7+
const baselineToOxcTargetMap: Record<string, string> = {
8+
chrome: 'chrome',
9+
edge: 'edge',
10+
firefox: 'firefox',
11+
safari: 'safari',
12+
safari_ios: 'ios',
13+
}
14+
15+
const oxcSupportedBrowsers = new Set([
16+
'chrome',
17+
'edge',
18+
'firefox',
19+
'safari',
20+
'ios',
21+
])
22+
23+
const results = getCompatibleVersions({
24+
widelyAvailableOnDate: targetDate,
25+
})
26+
27+
const oxcTargets = results
28+
.map((target) => ({
29+
browser: baselineToOxcTargetMap[target.browser],
30+
version: target.version,
31+
}))
32+
.filter((target) => oxcSupportedBrowsers.has(target.browser))
33+
.map((target) => `${target.browser}${target.version}`)
34+
35+
console.log('Baseline Widely Available Targets:', oxcTargets)

src/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export interface UserConfig {
215215
* If not set, defaults to the value of `engines.node` in your project's `package.json`.
216216
* If no `engines.node` field exists, no syntax transformations are applied.
217217
*
218-
* Accepts a single target (e.g., `'es2020'`, `'node18'`), an array of targets, or `false` to disable all transformations.
218+
* Accepts a single target (e.g., `'es2020'`, `'node18'`, `'baseline-widely-available'`), an array of targets, or `false` to disable all transformations.
219219
*
220220
* @see {@link https://tsdown.dev/options/target#supported-targets} for a list of valid targets and more details.
221221
*

src/features/target.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
import { expect, test } from 'vitest'
2-
import { resolvePackageTarget } from './target.ts'
2+
import { expandBaselineTarget, resolvePackageTarget } from './target.ts'
3+
4+
test('expandBaselineTarget', () => {
5+
expect(expandBaselineTarget(['baseline-widely-available'])).toEqual([
6+
'chrome111',
7+
'edge111',
8+
'firefox114',
9+
'safari16.4',
10+
'ios16.4',
11+
])
12+
13+
expect(expandBaselineTarget(['es2020'])).toEqual(['es2020'])
14+
15+
expect(expandBaselineTarget(['node18', 'baseline-widely-available'])).toEqual(
16+
['node18', 'chrome111', 'edge111', 'firefox114', 'safari16.4', 'ios16.4'],
17+
)
18+
})
319

420
test('resolvePackageTarget', () => {
521
expect(testVersion('>= 14')).toMatchInlineSnapshot(`"node14.0.0"`)

src/features/target.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import type { Logger } from '../utils/logger.ts'
44
import type { Ansis } from 'ansis'
55
import type { PackageJson } from 'pkg-types'
66

7+
// Generated by `scripts/generate-target.ts`
8+
const BASELINE_WIDELY_AVAILABLE_TARGET: string[] = [
9+
'chrome111',
10+
'edge111',
11+
'firefox114',
12+
'safari16.4',
13+
'ios16.4',
14+
]
15+
16+
export function expandBaselineTarget(targets: string[]): string[] {
17+
return targets.flatMap((t) =>
18+
t === 'baseline-widely-available' ? BASELINE_WIDELY_AVAILABLE_TARGET : t,
19+
)
20+
}
21+
722
export function resolveTarget(
823
logger: Logger,
924
target: string | string[] | false | undefined,
@@ -24,7 +39,7 @@ export function resolveTarget(
2439
if (typeof target === 'number') {
2540
throw new TypeError(`Invalid target: ${target}`)
2641
}
27-
const targets = resolveComma(toArray(target))
42+
const targets = expandBaselineTarget(resolveComma(toArray(target)))
2843
if (targets.length)
2944
logger.info(
3045
nameLabel,

src/internal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { expandBaselineTarget } from './features/target.ts'
12
export { fsExists, fsRemove } from './utils/fs.ts'
23
export { importWithError, resolveComma, toArray } from './utils/general.ts'
34
export type { Logger } from './utils/logger.ts'

0 commit comments

Comments
 (0)