Files
zeekayandHanzo Dev 69c6e860d7 transplant onto tamagui v2.6.0, brand as a re-runnable transform
This repo could never sync. There was NO merge-base with tamagui — 372 commits
here against 15,791 there, unrelated histories — because it began as a
copy-paste rebrand with a flattened layout. Every "sync" since was a hand
re-application that drifted, which is why the tree sat on 7.3.1 while upstream
shipped fixes we then rediscovered by hand.

This commit's PARENT IS TAMAGUI. A future sync is `git merge tama/main` then
`node scripts/rebrand.mjs` — a real merge, because the history is now shared.

174 packages: 166 upstream, our 8 restored (chrome, shell, telemetry, recipes,
get, font-geist-{sans,mono}, @hanzo/booker), bento-get gained. 170/170 build.

Our patches to files UPSTREAM ALSO OWNS are carried, which the package-level
delta missed and which was where the value actually was:
  - useMedia's server snapshot (`initState ?? getMedia()`). Upstream still
    returns undefined there, so every Tamagui Dialog kills a prerender — the
    exact crash hanzo.app spent a day on.
  - data-slot on web host nodes, absent upstream entirely.
Both applied ONTO upstream's newer files (it rewrote useMedia +150/-63 and
createComponent +160/-55), marked `PATCH (ours, carried across the transplant)`.

Seven traps are encoded in scripts/rebrand.mjs, each found by a gate:
skip itself and lockfiles; special-case the double-branded names in BOTH scoped
and bare form; map path strings, not just paths; drop a level for the flattened
group; check disk rather than a stale index.

Rust build artifacts are NOT committed. An earlier draft of this commit swept
apps/desktop/src-tauri/target/debug in via `git add -A` — 3,859 files including
a 272MB .a, over GitHub's 100MB cap, so the push could never have landed. They
are gitignored now.

Co-Authored-By: Hanzo Dev <[email protected]>
2026-07-30 18:25:06 -07:00

234 lines
6.3 KiB
TypeScript

import { join } from 'node:path'
import { mkdtempSync, readFileSync, rmSync, writeFileSync, existsSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
import { clearFormatCache, detectModuleFormat } from '@hanzogui/static'
import esbuild from 'esbuild'
let tempDir: string
beforeEach(() => {
clearFormatCache()
tempDir = mkdtempSync(join(tmpdir(), 'hanzogui-moduleformat-'))
})
afterEach(() => {
rmSync(tempDir, { recursive: true, force: true })
})
const componentSource = `
import { styled, View } from '@hanzogui/core'
export const MyButton = styled(View, {
name: 'MyButton',
backgroundColor: 'red',
})
`
describe('esbuild format based on detected module type', () => {
test('cjs project produces require() calls in output', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'commonjs' }))
const srcFile = join(tempDir, 'comp.tsx')
writeFileSync(srcFile, componentSource)
const format = detectModuleFormat(srcFile)
expect(format).toBe('cjs')
const outFile = join(tempDir, 'out.js')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format,
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
const output = readFileSync(outFile, 'utf-8')
expect(output).toContain('require(')
expect(output).toContain('module.exports')
expect(output).not.toMatch(/^export /m)
})
test('esm project produces import/export in output', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'module' }))
const srcFile = join(tempDir, 'comp.tsx')
writeFileSync(srcFile, componentSource)
const format = detectModuleFormat(srcFile)
expect(format).toBe('esm')
const outFile = join(tempDir, 'out.mjs')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format,
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
const output = readFileSync(outFile, 'utf-8')
expect(output).toMatch(/^import /m)
expect(output).not.toContain('require(')
expect(output).not.toContain('module.exports')
})
test('.mjs file produces esm output', () => {
const srcFile = join(tempDir, 'comp.mjs')
writeFileSync(
srcFile,
`
import { styled, View } from '@hanzogui/core'
export const Box = styled(View, { name: 'Box' })
`
)
const format = detectModuleFormat(srcFile)
expect(format).toBe('esm')
const outFile = join(tempDir, 'out.mjs')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format,
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
const output = readFileSync(outFile, 'utf-8')
expect(output).toMatch(/^import /m)
})
test('.cjs file produces cjs output even in type:module project', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'module' }))
const srcFile = join(tempDir, 'comp.cjs')
writeFileSync(
srcFile,
`
const { styled, View } = require('@hanzogui/core')
exports.Box = styled(View, { name: 'Box' })
`
)
const format = detectModuleFormat(srcFile)
expect(format).toBe('cjs')
const outFile = join(tempDir, 'out.cjs')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format,
bundle: true,
packages: 'external',
platform: 'node',
target: 'es2022',
})
const output = readFileSync(outFile, 'utf-8')
expect(output).toContain('require(')
})
test('esm output uses .mjs extension for temp file', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'module' }))
const srcFile = join(tempDir, 'MyComp.tsx')
writeFileSync(srcFile, componentSource)
const format = detectModuleFormat(srcFile)
const outExt = format === 'esm' ? '.mjs' : '.tsx'
expect(outExt).toBe('.mjs')
const outFile = join(tempDir, `out${outExt}`)
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format,
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
expect(existsSync(outFile)).toBe(true)
expect(outFile.endsWith('.mjs')).toBe(true)
})
test('cjs output uses .tsx extension for temp file', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'commonjs' }))
const srcFile = join(tempDir, 'MyComp.tsx')
writeFileSync(srcFile, componentSource)
const format = detectModuleFormat(srcFile)
const outExt = format === 'esm' ? '.mjs' : '.tsx'
expect(outExt).toBe('.tsx')
})
test('esm output contains valid export syntax', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'module' }))
const srcFile = join(tempDir, 'simple.tsx')
writeFileSync(
srcFile,
`
export const value = 42
export const name = 'test'
`
)
const outFile = join(tempDir, 'simple-out.mjs')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format: 'esm',
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
const output = readFileSync(outFile, 'utf-8')
// esm output uses export statements
expect(output).toMatch(/export\s*\{/)
expect(output).toContain('value')
expect(output).toContain('name')
expect(output).not.toContain('module.exports')
})
test('cjs output can be loaded via require()', () => {
writeFileSync(join(tempDir, 'package.json'), JSON.stringify({ type: 'commonjs' }))
const srcFile = join(tempDir, 'simple.tsx')
writeFileSync(
srcFile,
`
export const value = 99
export const greeting = 'hello'
`
)
const outFile = join(tempDir, 'simple-out.cjs')
esbuild.buildSync({
entryPoints: [srcFile],
outfile: outFile,
format: 'cjs',
bundle: true,
packages: 'external',
platform: 'node',
jsx: 'automatic',
target: 'es2022',
})
const mod = require(outFile)
expect(mod.value).toBe(99)
expect(mod.greeting).toBe('hello')
})
})