@tamagui/static 3.0.0-beta.922.1 → 3.0.0

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 (54) 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 +3 -0
  4. package/dist/cjs/extractor/esbuildTsconfigPaths.cjs +81 -45
  5. package/dist/cjs/extractor/generateConfigMarkdown.cjs +492 -0
  6. package/dist/cjs/extractor/loadTamagui.cjs +28 -20
  7. package/dist/cjs/extractor/regenerateConfig.cjs +30 -20
  8. package/dist/cjs/zero/islands.cjs +2 -1
  9. package/dist/cjs/zero/theme.cjs +6 -3
  10. package/dist/esm/compilerHost.mjs +242 -76
  11. package/dist/esm/compilerHost.mjs.map +1 -1
  12. package/dist/esm/exports.mjs +3 -1
  13. package/dist/esm/extractor/bundle.mjs +3 -0
  14. package/dist/esm/extractor/bundle.mjs.map +1 -1
  15. package/dist/esm/extractor/esbuildTsconfigPaths.mjs +80 -45
  16. package/dist/esm/extractor/esbuildTsconfigPaths.mjs.map +1 -1
  17. package/dist/esm/extractor/generateConfigMarkdown.mjs +472 -0
  18. package/dist/esm/extractor/generateConfigMarkdown.mjs.map +1 -0
  19. package/dist/esm/extractor/loadTamagui.mjs +28 -20
  20. package/dist/esm/extractor/loadTamagui.mjs.map +1 -1
  21. package/dist/esm/extractor/regenerateConfig.mjs +30 -20
  22. package/dist/esm/extractor/regenerateConfig.mjs.map +1 -1
  23. package/dist/esm/zero/islands.mjs +2 -1
  24. package/dist/esm/zero/islands.mjs.map +1 -1
  25. package/dist/esm/zero/theme.mjs +7 -4
  26. package/dist/esm/zero/theme.mjs.map +1 -1
  27. package/package.json +23 -20
  28. package/src/compilerHost.ts +387 -160
  29. package/src/exports.ts +3 -0
  30. package/src/extractor/bundle.ts +13 -6
  31. package/src/extractor/esbuildTsconfigPaths.ts +106 -78
  32. package/src/extractor/generateConfigMarkdown.ts +610 -0
  33. package/src/extractor/loadTamagui.ts +55 -24
  34. package/src/extractor/regenerateConfig.ts +36 -35
  35. package/src/zero/islands.ts +2 -1
  36. package/src/zero/options.ts +8 -3
  37. package/src/zero/theme.ts +29 -4
  38. package/types/compilerHost.d.ts.map +1 -1
  39. package/types/exports.d.ts +2 -0
  40. package/types/exports.d.ts.map +1 -1
  41. package/types/extractor/bundle.d.ts.map +1 -1
  42. package/types/extractor/esbuildTsconfigPaths.d.ts +5 -7
  43. package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -1
  44. package/types/extractor/generateConfigMarkdown.d.ts +5 -0
  45. package/types/extractor/generateConfigMarkdown.d.ts.map +1 -0
  46. package/types/extractor/loadTamagui.d.ts +13 -1
  47. package/types/extractor/loadTamagui.d.ts.map +1 -1
  48. package/types/extractor/regenerateConfig.d.ts.map +1 -1
  49. package/types/zero/identity.d.ts +1 -1
  50. package/types/zero/islands.d.ts.map +1 -1
  51. package/types/zero/options.d.ts +8 -3
  52. package/types/zero/options.d.ts.map +1 -1
  53. package/types/zero/theme.d.ts +2 -0
  54. 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'
@@ -282,13 +282,20 @@ export async function esbundleTamaguiConfig(
282
282
  // build to memory first, then write atomically (temp file + rename)
283
283
  // to prevent other threads from reading partially-written files.
284
284
  // 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.
285
+ // one process (or one worker thread) shared a temp path, and whichever
286
+ // renamed first left the other renaming a file that no longer existed.
287
287
  const tmpFile = `${props.outfile}.tmp.${process.pid}-${randomBytes(6).toString('hex')}`
288
- const result = await esbuild.build({
289
- ...config,
290
- outfile: tmpFile,
291
- })
288
+
289
+ const result = await esbuild
290
+ .build({
291
+ ...config,
292
+ outfile: tmpFile,
293
+ })
294
+ .catch(async (err) => {
295
+ // a failed build can still leave a partial temp file behind
296
+ await FS.remove(tmpFile).catch(() => {})
297
+ throw err
298
+ })
292
299
 
293
300
  // atomic rename prevents other threads from reading partial files
294
301
  await FS.rename(tmpFile, props.outfile)
@@ -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
- }