Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions dts.snapshot.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"config-!~{00c}~.d.mts": {
"config-!~{00d}~.d.mts": {
"defineConfig": "declare function defineConfig(_: UserConfigExport): UserConfigExport",
"mergeConfig": "declare function mergeConfig(_: InlineConfig, ...overrides: InlineConfig[]): InlineConfig",
"resolveUserConfig": "declare function resolveUserConfig(_: UserConfig, _: InlineConfig): Promise<ResolvedConfig[]>"
Expand All @@ -13,6 +13,29 @@
"mergeConfig"
]
},
"index-!~{00b}~.d.mts": {
"Arrayable": "type Arrayable<T> = T | T[]",
"Awaitable": "type Awaitable<T> = T | Promise<T>",
"globalLogger": "Logger",
"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}",
"LoggerOptions": "interface LoggerOptions {\n allowClearScreen?: boolean\n customLogger?: Logger\n console?: Console\n failOnWarn?: boolean\n}",
"LogLevel": "type LogLevel = LogType | 'silent'",
"LogType": "type LogType = 'error' | 'warn' | 'info'",
"MarkPartial": "type MarkPartial<T, K extends keyof T> = Omit<Required<T>, K> & Partial<Pick<T, K>>",
"Overwrite": "type Overwrite<T, U> = Omit<T, keyof U> & U",
"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}",
"PackageJsonCommonScripts": "type PackageJsonCommonScripts = 'build' | 'coverage' | 'deploy' | 'dev' | 'format' | 'lint' | 'preview' | 'release' | 'typecheck' | 'watch'",
"PackageJsonExportKey": "type PackageJsonExportKey = '.' | 'import' | 'require' | 'types' | 'node' | 'browser' | 'default' | (string & {})",
"PackageJsonExports": "type PackageJsonExports = string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject>",
"PackageJsonExportsObject": "type PackageJsonExportsObject = { [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject> }",
"PackageJsonFunding": "type PackageJsonFunding = string | { url: string; type?: string }",
"PackageJsonNpmLifeCycleScripts": "type PackageJsonNpmLifeCycleScripts = 'dependencies' | 'prepublishOnly' | PackageJsonScriptWithPreAndPost<'install' | 'pack' | 'prepare' | 'publish' | 'restart' | 'start' | 'stop' | 'test' | 'version'>",
"PackageJsonPerson": "type PackageJsonPerson = string | { name: string; email?: string; url?: string }",
"PackageJsonPnpmLifeCycleScripts": "type PackageJsonPnpmLifeCycleScripts = 'pnpm:devPreinstall'",
"PackageJsonScriptName": "type PackageJsonScriptName = PackageJsonCommonScripts | PackageJsonNpmLifeCycleScripts | PackageJsonPnpmLifeCycleScripts | (string & {})",
"PackageJsonScripts": "type PackageJsonScripts = { [P in PackageJsonScriptName]?: string }",
"PackageJsonScriptWithPreAndPost": "type PackageJsonScriptWithPreAndPost<S extends string> = S | `${'pre' | 'post'}${S}`"
},
"index.d.mts": {
"build": "declare function build(_: InlineConfig): Promise<TsdownBundle[]>",
"buildWithConfigs": "declare function buildWithConfigs(_: ResolvedConfig[], _: string[], _: () => void): Promise<TsdownBundle[]>",
Expand Down Expand Up @@ -71,6 +94,7 @@
]
},
"internal.d.mts": {
"expandBaselineTarget": "declare function expandBaselineTarget(_: string[]): string[]",
"fsExists": "declare function fsExists(_: string): Promise<boolean>",
"fsRemove": "declare function fsRemove(_: string): Promise<void>",
"importWithError": "declare function importWithError<T>(_: string): Promise<T>",
Expand All @@ -80,24 +104,14 @@
"Logger",
"MarkPartial",
"Overwrite",
"expandBaselineTarget",
"fsExists",
"fsRemove",
"importWithError",
"resolveComma",
"toArray"
]
},
"logger-!~{00a}~.d.mts": {
"Arrayable": "type Arrayable<T> = T | T[]",
"Awaitable": "type Awaitable<T> = T | Promise<T>",
"globalLogger": "Logger",
"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}",
"LoggerOptions": "interface LoggerOptions {\n allowClearScreen?: boolean\n customLogger?: Logger\n console?: Console\n failOnWarn?: boolean\n}",
"LogLevel": "type LogLevel = LogType | 'silent'",
"LogType": "type LogType = 'error' | 'warn' | 'info'",
"MarkPartial": "type MarkPartial<T, K extends keyof T> = Omit<Required<T>, K> & Partial<Pick<T, K>>",
"Overwrite": "type Overwrite<T, U> = Omit<T, keyof U> & U"
},
"plugins.d.mts": {
"NodeProtocolPlugin": "declare function NodeProtocolPlugin(_: 'strip' | true): Plugin",
"ShebangPlugin": "declare function ShebangPlugin(_: Logger, _: string, _: string, _: boolean): Plugin",
Expand All @@ -113,7 +127,7 @@
"run.d.mts": {
"#exports": []
},
"types-!~{00b}~.d.mts": {
"types-!~{00c}~.d.mts": {
"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}",
"BuildContext": "interface BuildContext {\n options: ResolvedConfig\n hooks: Hookable<TsdownHooks>\n}",
"ChunkAddon": "type ChunkAddon = ChunkAddonObject | ChunkAddonFunction | string",
Expand All @@ -137,18 +151,6 @@
"OutExtensionContext": "interface OutExtensionContext {\n options: InputOptions\n format: NormalizedFormat\n pkgType?: PackageType\n}",
"OutExtensionFactory": "type OutExtensionFactory = (_: OutExtensionContext) => OutExtensionObject | undefined",
"OutExtensionObject": "interface OutExtensionObject {\n js?: string\n dts?: string\n}",
"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}",
"PackageJsonCommonScripts": "type PackageJsonCommonScripts = 'build' | 'coverage' | 'deploy' | 'dev' | 'format' | 'lint' | 'preview' | 'release' | 'typecheck' | 'watch'",
"PackageJsonExportKey": "type PackageJsonExportKey = '.' | 'import' | 'require' | 'types' | 'node' | 'browser' | 'default' | (string & {})",
"PackageJsonExports": "type PackageJsonExports = string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject>",
"PackageJsonExportsObject": "type PackageJsonExportsObject = { [P in PackageJsonExportKey]?: string | PackageJsonExportsObject | Array<string | PackageJsonExportsObject> }",
"PackageJsonFunding": "type PackageJsonFunding = string | { url: string; type?: string }",
"PackageJsonNpmLifeCycleScripts": "type PackageJsonNpmLifeCycleScripts = 'dependencies' | 'prepublishOnly' | PackageJsonScriptWithPreAndPost<'install' | 'pack' | 'prepare' | 'publish' | 'restart' | 'start' | 'stop' | 'test' | 'version'>",
"PackageJsonPerson": "type PackageJsonPerson = string | { name: string; email?: string; url?: string }",
"PackageJsonPnpmLifeCycleScripts": "type PackageJsonPnpmLifeCycleScripts = 'pnpm:devPreinstall'",
"PackageJsonScriptName": "type PackageJsonScriptName = PackageJsonCommonScripts | PackageJsonNpmLifeCycleScripts | PackageJsonPnpmLifeCycleScripts | (string & {})",
"PackageJsonScripts": "type PackageJsonScripts = { [P in PackageJsonScriptName]?: string }",
"PackageJsonScriptWithPreAndPost": "type PackageJsonScriptWithPreAndPost<S extends string> = S | `${'pre' | 'post'}${S}`",
"PackageJsonWithPath": "interface PackageJsonWithPath extends PackageJson {\n packageJsonPath: string\n}",
"PackageType": "type PackageType = 'module' | 'commonjs' | undefined",
"PublintOptions": "interface PublintOptions extends Omit<Options, 'pack' | 'pkgDir'> {\n module?: [typeof _$publint, typeof _$publint_utils0]\n}",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
"@vitest/coverage-v8": "catalog:dev",
"@vitest/ui": "catalog:dev",
"@vueuse/core": "catalog:docs",
"baseline-browser-mapping": "catalog:dev",
"bumpp": "catalog:dev",
"dedent": "catalog:dev",
"eslint": "catalog:dev",
Expand Down
3 changes: 2 additions & 1 deletion packages/css/src/options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
expandBaselineTarget,
resolveComma,
toArray,
type MarkPartial,
Expand Down Expand Up @@ -213,7 +214,7 @@ export function resolveCssOptions(
} else if (options.target == null) {
cssTarget = topLevelTarget
} else {
cssTarget = resolveComma(toArray(options.target))
cssTarget = expandBaselineTarget(resolveComma(toArray(options.target)))
}

return {
Expand Down
14 changes: 10 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ catalogs:
'@typescript/native-preview': 7.0.0-dev.20260405.1
'@vitest/coverage-v8': ^4.1.2
'@vitest/ui': ^4.1.2
baseline-browser-mapping: ^2.10.16
bumpp: ^11.0.1
dedent: ^1.7.2
eslint: ^10.2.0
Expand Down
35 changes: 35 additions & 0 deletions scripts/generate-target.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getCompatibleVersions } from 'baseline-browser-mapping'

// Update on each major release
const targetDate = '2026-01-01'

// https://oxc.rs/docs/guide/usage/transformer/lowering#target
const baselineToOxcTargetMap: Record<string, string> = {
chrome: 'chrome',
edge: 'edge',
firefox: 'firefox',
safari: 'safari',
safari_ios: 'ios',
}

const oxcSupportedBrowsers = new Set([
'chrome',
'edge',
'firefox',
'safari',
'ios',
])

const results = getCompatibleVersions({
widelyAvailableOnDate: targetDate,
})

const oxcTargets = results
.map((target) => ({
browser: baselineToOxcTargetMap[target.browser],
version: target.version,
}))
.filter((target) => oxcSupportedBrowsers.has(target.browser))
.map((target) => `${target.browser}${target.version}`)

console.log('Baseline Widely Available Targets:', oxcTargets)
2 changes: 1 addition & 1 deletion src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export interface UserConfig {
* If not set, defaults to the value of `engines.node` in your project's `package.json`.
* If no `engines.node` field exists, no syntax transformations are applied.
*
* Accepts a single target (e.g., `'es2020'`, `'node18'`), an array of targets, or `false` to disable all transformations.
* Accepts a single target (e.g., `'es2020'`, `'node18'`, `'baseline-widely-available'`), an array of targets, or `false` to disable all transformations.
*
* @see {@link https://tsdown.dev/options/target#supported-targets} for a list of valid targets and more details.
*
Expand Down
18 changes: 17 additions & 1 deletion src/features/target.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import { expect, test } from 'vitest'
import { resolvePackageTarget } from './target.ts'
import { expandBaselineTarget, resolvePackageTarget } from './target.ts'

test('expandBaselineTarget', () => {
expect(expandBaselineTarget(['baseline-widely-available'])).toEqual([
'chrome111',
'edge111',
'firefox114',
'safari16.4',
'ios16.4',
])

expect(expandBaselineTarget(['es2020'])).toEqual(['es2020'])

expect(expandBaselineTarget(['node18', 'baseline-widely-available'])).toEqual(
['node18', 'chrome111', 'edge111', 'firefox114', 'safari16.4', 'ios16.4'],
)
})

test('resolvePackageTarget', () => {
expect(testVersion('>= 14')).toMatchInlineSnapshot(`"node14.0.0"`)
Expand Down
17 changes: 16 additions & 1 deletion src/features/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ import type { Logger } from '../utils/logger.ts'
import type { Ansis } from 'ansis'
import type { PackageJson } from 'pkg-types'

// Generated by `scripts/generate-target.ts`
const BASELINE_WIDELY_AVAILABLE_TARGET: string[] = [
'chrome111',
'edge111',
'firefox114',
'safari16.4',
'ios16.4',
]

export function expandBaselineTarget(targets: string[]): string[] {
return targets.flatMap((t) =>
t === 'baseline-widely-available' ? BASELINE_WIDELY_AVAILABLE_TARGET : t,
)
}

export function resolveTarget(
logger: Logger,
target: string | string[] | false | undefined,
Expand All @@ -24,7 +39,7 @@ export function resolveTarget(
if (typeof target === 'number') {
throw new TypeError(`Invalid target: ${target}`)
}
const targets = resolveComma(toArray(target))
const targets = expandBaselineTarget(resolveComma(toArray(target)))
if (targets.length)
logger.info(
nameLabel,
Expand Down
1 change: 1 addition & 0 deletions src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { expandBaselineTarget } from './features/target.ts'
export { fsExists, fsRemove } from './utils/fs.ts'
export { importWithError, resolveComma, toArray } from './utils/general.ts'
export type { Logger } from './utils/logger.ts'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## index.mjs

```mjs
//#region index.ts
const foo = a?.b?.();
//#endregion
export { foo };

```
9 changes: 9 additions & 0 deletions tests/target.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ describe('target', () => {
expect(snapshot).contain('?.')
})

test('baseline-widely-available target', async (context) => {
const { snapshot } = await testBuild({
context,
files: { 'index.ts': 'export const foo: number = a?.b?.()' },
options: { target: 'baseline-widely-available' },
})
expect(snapshot).contain('?.')
})

test('target: false disables all syntax transformations', async (context) => {
const { snapshot } = await testBuild({
context,
Expand Down
Loading