@tamagui/static 3.0.0-beta.924.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/cjs/compilerHost.cjs +241 -75
  2. package/dist/cjs/exports.cjs +5 -1
  3. package/dist/cjs/extractor/bundle.cjs +14 -9
  4. package/dist/cjs/extractor/bundleConfig.cjs +0 -1
  5. package/dist/cjs/extractor/esbuildTsconfigPaths.cjs +81 -45
  6. package/dist/cjs/extractor/generateConfigMarkdown.cjs +492 -0
  7. package/dist/cjs/extractor/loadTamagui.cjs +28 -20
  8. package/dist/cjs/extractor/regenerateConfig.cjs +30 -20
  9. package/dist/cjs/zero/islands.cjs +2 -1
  10. package/dist/cjs/zero/theme.cjs +6 -3
  11. package/dist/esm/compilerHost.mjs +242 -76
  12. package/dist/esm/compilerHost.mjs.map +1 -1
  13. package/dist/esm/exports.mjs +3 -1
  14. package/dist/esm/extractor/bundle.mjs +14 -9
  15. package/dist/esm/extractor/bundle.mjs.map +1 -1
  16. package/dist/esm/extractor/bundleConfig.mjs +0 -1
  17. package/dist/esm/extractor/bundleConfig.mjs.map +1 -1
  18. package/dist/esm/extractor/esbuildTsconfigPaths.mjs +80 -45
  19. package/dist/esm/extractor/esbuildTsconfigPaths.mjs.map +1 -1
  20. package/dist/esm/extractor/generateConfigMarkdown.mjs +472 -0
  21. package/dist/esm/extractor/generateConfigMarkdown.mjs.map +1 -0
  22. package/dist/esm/extractor/loadTamagui.mjs +28 -20
  23. package/dist/esm/extractor/loadTamagui.mjs.map +1 -1
  24. package/dist/esm/extractor/regenerateConfig.mjs +30 -20
  25. package/dist/esm/extractor/regenerateConfig.mjs.map +1 -1
  26. package/dist/esm/zero/islands.mjs +2 -1
  27. package/dist/esm/zero/islands.mjs.map +1 -1
  28. package/dist/esm/zero/theme.mjs +7 -4
  29. package/dist/esm/zero/theme.mjs.map +1 -1
  30. package/package.json +23 -20
  31. package/src/compilerHost.ts +387 -160
  32. package/src/exports.ts +3 -0
  33. package/src/extractor/bundle.ts +19 -7
  34. package/src/extractor/bundleConfig.ts +0 -1
  35. package/src/extractor/esbuildTsconfigPaths.ts +106 -78
  36. package/src/extractor/generateConfigMarkdown.ts +610 -0
  37. package/src/extractor/loadTamagui.ts +55 -24
  38. package/src/extractor/regenerateConfig.ts +36 -35
  39. package/src/zero/islands.ts +2 -1
  40. package/src/zero/options.ts +8 -3
  41. package/src/zero/theme.ts +29 -4
  42. package/types/compilerHost.d.ts.map +1 -1
  43. package/types/exports.d.ts +2 -0
  44. package/types/exports.d.ts.map +1 -1
  45. package/types/extractor/bundle.d.ts.map +1 -1
  46. package/types/extractor/bundleConfig.d.ts.map +1 -1
  47. package/types/extractor/esbuildTsconfigPaths.d.ts +5 -7
  48. package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -1
  49. package/types/extractor/generateConfigMarkdown.d.ts +5 -0
  50. package/types/extractor/generateConfigMarkdown.d.ts.map +1 -0
  51. package/types/extractor/loadTamagui.d.ts +13 -1
  52. package/types/extractor/loadTamagui.d.ts.map +1 -1
  53. package/types/extractor/regenerateConfig.d.ts.map +1 -1
  54. package/types/zero/identity.d.ts +1 -1
  55. package/types/zero/islands.d.ts.map +1 -1
  56. package/types/zero/options.d.ts +8 -3
  57. package/types/zero/options.d.ts.map +1 -1
  58. package/types/zero/theme.d.ts +2 -0
  59. package/types/zero/theme.d.ts.map +1 -1
package/src/exports.ts CHANGED
@@ -11,5 +11,8 @@ export * from './extractor/watchTamaguiConfig'
11
11
  export * from './registerRequire'
12
12
  export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat'
13
13
  export { esbundleTamaguiConfig } from './extractor/bundle'
14
+ export { createTsconfigPathsMatcher } from './extractor/esbuildTsconfigPaths'
14
15
  export * from './getPragmaOptions'
15
16
  export * from './zero'
17
+
18
+ export { generateConfigMarkdown } from './extractor/generateConfigMarkdown'
@@ -65,6 +65,7 @@ function getESBuildConfig(
65
65
  resolvePlatformSpecificEntries,
66
66
  dangerouslyIgnoreStaticEvaluationModules = [],
67
67
  define: callerDefine,
68
+ conditions: callerConditions = [],
68
69
  ...options
69
70
  }: Props,
70
71
  platform: TamaguiPlatform,
@@ -109,9 +110,13 @@ function getESBuildConfig(
109
110
  ...platformDefines,
110
111
  ...callerDefine,
111
112
  },
113
+ conditions: [
114
+ 'tamagui-compiler',
115
+ ...(platform === 'native' ? ['react-native'] : []),
116
+ ...callerConditions,
117
+ ],
112
118
  ...(platform === 'native'
113
119
  ? {
114
- conditions: ['react-native'],
115
120
  mainFields: ['react-native', 'module', 'main'],
116
121
  }
117
122
  : {}),
@@ -282,13 +287,20 @@ export async function esbundleTamaguiConfig(
282
287
  // build to memory first, then write atomically (temp file + rename)
283
288
  // to prevent other threads from reading partially-written files.
284
289
  // The suffix is per call, not per process: two bundles of the same config in
285
- // one process shared a temp path, and whichever renamed first left the other
286
- // renaming a file that no longer existed.
290
+ // one process (or one worker thread) shared a temp path, and whichever
291
+ // renamed first left the other renaming a file that no longer existed.
287
292
  const tmpFile = `${props.outfile}.tmp.${process.pid}-${randomBytes(6).toString('hex')}`
288
- const result = await esbuild.build({
289
- ...config,
290
- outfile: tmpFile,
291
- })
293
+
294
+ const result = await esbuild
295
+ .build({
296
+ ...config,
297
+ outfile: tmpFile,
298
+ })
299
+ .catch(async (err) => {
300
+ // a failed build can still leave a partial temp file behind
301
+ await FS.remove(tmpFile).catch(() => {})
302
+ throw err
303
+ })
292
304
 
293
305
  // atomic rename prevents other threads from reading partial files
294
306
  await FS.rename(tmpFile, props.outfile)
@@ -504,7 +504,6 @@ export async function bundleConfig(props: TamaguiOptions, rebuild = false) {
504
504
  props.platform !== 'native' ||
505
505
  componentModule.startsWith('.') ||
506
506
  isAbsolute(componentModule),
507
- conditions: props.platform === 'native' ? ['react-native'] : undefined,
508
507
  external,
509
508
  outfile: componentOutPaths[i],
510
509
  target: 'node24',
@@ -1,103 +1,131 @@
1
1
  import type { Plugin } from 'esbuild'
2
+ import {
3
+ createPathsMatcher,
4
+ getTsconfig,
5
+ parseTsconfig,
6
+ type TsConfigJsonResolved,
7
+ type TsConfigResult,
8
+ } from 'get-tsconfig'
2
9
  import fs from 'node:fs'
3
10
  import path from 'node:path'
4
- import {
5
- findConfigFile,
6
- nodeModuleNameResolver,
7
- parseJsonConfigFileContent,
8
- readConfigFile,
9
- sys,
10
- } from 'typescript'
11
11
 
12
12
  const name = 'tsconfig-paths'
13
13
 
14
- interface Tsconfig {
15
- compilerOptions?: {
16
- baseUrl?: string
17
- paths?: Record<string, string[]>
14
+ type Tsconfig = Pick<TsConfigJsonResolved, 'compilerOptions'>
15
+ type TsconfigPathMatcher = (specifier: string) => string[]
16
+
17
+ function loadTsconfig(
18
+ tsconfig?: Tsconfig | string,
19
+ cwd = process.cwd()
20
+ ): TsConfigResult | null {
21
+ if (!tsconfig) {
22
+ return getTsconfig(cwd) || getTsconfig(cwd, 'jsconfig.json')
18
23
  }
19
- }
20
24
 
21
- export function TsconfigPathsPlugin(): Plugin {
22
- const compilerOptions = loadCompilerOptionsFromTsconfig()
25
+ if (typeof tsconfig === 'string') {
26
+ const configPath = path.resolve(cwd, tsconfig)
27
+ if (!fs.existsSync(configPath)) {
28
+ throw new Error(`Specified tsconfig file not found: ${configPath}`)
29
+ }
30
+ return { path: configPath, config: parseTsconfig(configPath) }
31
+ }
23
32
 
24
33
  return {
25
- name,
26
- setup({ onResolve }) {
27
- onResolve({ filter: /.*/ }, (args) => {
28
- // skip @tamagui packages - they should be externalized, not resolved via tsconfig
29
- if (args.path.startsWith('@tamagui/')) {
30
- return null
31
- }
34
+ path: path.join(cwd, 'tsconfig.json'),
35
+ config: tsconfig,
36
+ }
37
+ }
32
38
 
33
- const paths = compilerOptions.paths || {}
34
- const hasMatchingPath = Object.keys(paths).some((p) =>
35
- new RegExp(p.replace('*', '\\w*')).test(args.path)
36
- )
39
+ export function createTsconfigPathsMatcher(
40
+ tsconfig?: Tsconfig | string,
41
+ cwd = process.cwd()
42
+ ): ((specifier: string) => string[]) | null {
43
+ const loaded = loadTsconfig(tsconfig, cwd)
44
+ return loaded ? createPathsMatcher(loaded) : null
45
+ }
37
46
 
38
- if (!hasMatchingPath) {
39
- return null
40
- }
47
+ export function loadTsconfigPathMatcher(
48
+ tsconfig?: TsConfigJsonResolved | string
49
+ ): TsconfigPathMatcher {
50
+ let result: TsConfigResult | null
51
+ if (!tsconfig) {
52
+ result = getTsconfig(process.cwd()) || getTsconfig(process.cwd(), 'jsconfig.json')
53
+ } else if (typeof tsconfig === 'string') {
54
+ if (fs.existsSync(tsconfig)) {
55
+ const configPath = path.resolve(tsconfig)
56
+ result = { config: parseTsconfig(configPath), path: configPath }
57
+ } else {
58
+ throw new Error(`Specified tsconfig file not found: ${tsconfig}`)
59
+ }
60
+ } else {
61
+ result = { config: tsconfig, path: path.join(process.cwd(), 'tsconfig.json') }
62
+ }
41
63
 
42
- const { resolvedModule } = nodeModuleNameResolver(
43
- args.path,
44
- args.importer,
45
- compilerOptions,
46
- sys
47
- )
64
+ if (!result) return () => []
65
+ const matchPaths = createPathsMatcher(result)
66
+ const patterns = Object.keys(result.config.compilerOptions?.paths || {})
67
+ if (!matchPaths || patterns.length === 0) return () => []
68
+
69
+ return (specifier) => {
70
+ const matchesExplicitPath = patterns.some((pattern) => {
71
+ const wildcardIndex = pattern.indexOf('*')
72
+ if (wildcardIndex === -1) return pattern === specifier
73
+ return (
74
+ specifier.startsWith(pattern.slice(0, wildcardIndex)) &&
75
+ specifier.endsWith(pattern.slice(wildcardIndex + 1))
76
+ )
77
+ })
78
+ return matchesExplicitPath ? matchPaths(specifier) : []
79
+ }
80
+ }
48
81
 
49
- if (!resolvedModule) {
82
+ export function TsconfigPathsPlugin(): Plugin {
83
+ const matchTsconfigPath = loadTsconfigPathMatcher()
84
+
85
+ return {
86
+ name,
87
+ setup(build) {
88
+ build.onResolve({ filter: /.*/ }, async (args) => {
89
+ const pluginData = args.pluginData as
90
+ | { tamaguiTsconfigPaths?: boolean; tamaguiTsconfigPathsResolved?: boolean }
91
+ | undefined
92
+ if (
93
+ pluginData?.tamaguiTsconfigPaths ||
94
+ pluginData?.tamaguiTsconfigPathsResolved
95
+ ) {
50
96
  return null
51
97
  }
52
98
 
53
- const { resolvedFileName } = resolvedModule
54
-
55
- if (!resolvedFileName || resolvedFileName.endsWith('.d.ts')) {
99
+ // skip @tamagui packages - they should be externalized, not resolved via tsconfig
100
+ if (args.path.startsWith('@tamagui/')) {
56
101
  return null
57
102
  }
58
103
 
59
- return {
60
- path: resolvedFileName,
104
+ for (const candidate of matchTsconfigPath(args.path)) {
105
+ const resolved = await build.resolve(candidate, {
106
+ importer: args.importer,
107
+ kind: args.kind,
108
+ namespace: args.namespace,
109
+ pluginData: {
110
+ ...(args.pluginData && typeof args.pluginData === 'object'
111
+ ? args.pluginData
112
+ : {}),
113
+ tamaguiTsconfigPaths: true,
114
+ tamaguiTsconfigPathsResolved: true,
115
+ },
116
+ resolveDir: args.resolveDir,
117
+ })
118
+ if (
119
+ resolved.path &&
120
+ !resolved.path.endsWith('.d.ts') &&
121
+ resolved.errors.length === 0
122
+ ) {
123
+ return resolved
124
+ }
61
125
  }
126
+
127
+ return null
62
128
  })
63
129
  },
64
130
  }
65
131
  }
66
-
67
- export function loadCompilerOptionsFromTsconfig(tsconfig?: Tsconfig | string) {
68
- if (!tsconfig) {
69
- const configPath =
70
- findConfigFile(process.cwd(), sys.fileExists, 'tsconfig.json') ||
71
- findConfigFile(process.cwd(), sys.fileExists, 'jsconfig.json')
72
-
73
- if (configPath) {
74
- return parseTsconfig(configPath)
75
- }
76
- return {}
77
- }
78
-
79
- if (typeof tsconfig === 'string') {
80
- if (fs.existsSync(tsconfig)) {
81
- return parseTsconfig(tsconfig)
82
- } else {
83
- throw new Error(`Specified tsconfig file not found: ${tsconfig}`)
84
- }
85
- }
86
-
87
- const baseDir = process.cwd()
88
- const parsed = parseJsonConfigFileContent(tsconfig, sys, baseDir)
89
- return parsed.options
90
- }
91
-
92
- function parseTsconfig(configFilePath: string) {
93
- const configFile = readConfigFile(configFilePath, sys.readFile)
94
- if (configFile.error) {
95
- throw new Error(
96
- `Error reading tsconfig file '${configFilePath}': ${configFile.error.messageText}`
97
- )
98
- }
99
-
100
- const baseDir = path.dirname(configFilePath)
101
- const parsed = parseJsonConfigFileContent(configFile.config, sys, baseDir)
102
- return parsed.options
103
- }