Build every package with the TypeScript compiler alone

Babel and esbuild were never here for TypeScript. Babel carried the static
optimizing compiler and one plugin that appended extensions to esbuild's
emitted imports; source now names its own extensions and the compiler rewrites
them on emit. A sixty-line runner replaces the tool: an ESM emit with
declarations, a CommonJS emit where a manifest states a require entry, and a
native emit where a .native sibling takes its sibling's name. The compiler
packages keep Babel as their own substrate; nothing else runs over the code.
Eighteen packages still carry type errors the previous tool never checked.
This commit is contained in:
2026-09-03 17:14:57 -07:00
parent 6ad5a7f8fd
commit 77e8398deb
1182 changed files with 28123 additions and 19904 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ RUN bun install
# Merge bento dependencies into root package.json and reinstall (only if bento was cloned)
RUN if [ -d "../bento" ]; then node scripts/with-bento.mjs && bun install; fi
RUN bun run build:js
RUN bun run build
RUN bun run build:app
EXPOSE 3000
+1 -1
View File
@@ -60,7 +60,7 @@ RUN bun install
RUN node scripts/with-bento.mjs && bun install
# build
RUN bun run build:js
RUN bun run build
RUN bun run build:app
EXPOSE 3000
+3441 -888
View File
File diff suppressed because it is too large Load Diff
+15 -17
View File
@@ -6,27 +6,28 @@
"url": "git+https://github.com/hanzoai/gui.git"
},
"workspaces": [
"./pkgs/compiler/**/*",
"./pkgs/core/**/*",
"./pkgs/compiler/*",
"./pkgs/compiler/*/*",
"./pkgs/core/*",
"./pkgs/core/*/*",
"./apps/demos",
"./apps/kitchen-sink",
"./apps/kitchen-sink-go",
"./apps/kitchen-sink-shared",
"./apps/starters/*",
"./apps/tests/**/*",
"./apps/tests/*",
"./apps/tests/*/*",
"./apps/sandbox",
"./pkgs/**/*",
"./pkgs/*",
"./pkgs/*/*",
"./apps/gui.hanzo.ai",
"./pkgs/ui/**/*",
"./pkgs/ui/*",
"./pkgs/ui/*/*",
"./apps/team"
],
"scripts": {
"postinstall": "bun ./scripts/postinstall.ts",
"build:app": "./scripts/ci-build-app.sh",
"build:force": "bun run clean:build && bun run build -- --force",
"build:js": "SKIP_TYPES=1 bun run build --force",
"build:pre": "cd pkgs/babel-plugin-fully-specified && bun run build",
"build:types": "SKIP_JS=1 bun run build",
"build:verbose": "bun run build -vvv",
"build": "turbo run build",
"check:deps": "manypkg check",
@@ -83,8 +84,8 @@
"repair": "bun ./scripts/repair.ts",
"reset-package-json": "RESET_PACKAGE_JSON=true node -e \"require('./scripts/multi-react-version-tests.js').resetPackageJson()\"",
"sandbox": "./scripts/bun-run.sh sandbox dev",
"scripts:format": "node -r esbuild-register ./scripts/format.ts",
"scripts:setup": "node -r esbuild-register ./scripts/setup.ts",
"scripts:format": "bun ./scripts/format.ts",
"scripts:setup": "bun ./scripts/setup.ts",
"starter:native": "./scripts/bun-run.sh @hanzogui/starter native",
"starter:prod": "./scripts/bun-run.sh @hanzogui/starter web:prod && ./scripts/bun-run.sh @hanzogui/starter web:prod:serve",
"starter": "./scripts/bun-run.sh @hanzogui/starter web",
@@ -107,9 +108,9 @@
"up": "tko up",
"upgrade:starters:expo-router": "cd apps/starters/expo-router && bun install && bun run upgrade:hanzogui",
"upgrade:starters": "bun run upgrade:starters:expo-router",
"vercel:build": "bun run build:js && cd code/old-site && bun run ci:build",
"watch:js": "SKIP_TYPES=1 bun run watch:packages",
"watch:packages": "SKIP_INITIAL_BUILD=1 SKIP_TYPES_INITIAL=1 ./scripts/run.sh watch",
"vercel:build": "bun run build && cd code/old-site && bun run ci:build",
"watch:js": "bun run watch:packages",
"watch:packages": "./scripts/run.sh watch",
"watch:ts": "bun ./scripts/watch-ts.ts",
"watch": "npm-run-all --parallel watch:ts watch:packages",
"repair:exports": "node scripts/repair-exports.js"
@@ -121,8 +122,6 @@
"@testing-library/dom": "^10.4.1",
"@typescript/native-preview": "^7.0.0-dev.20260707.2",
"dotenv-cli": "^11.0.0",
"esbuild": "^0.28.2",
"esbuild-register": "^3.6.0",
"fs-extra": "^11.4.0",
"glob": "^13.0.6",
"knip": "^6.33.0",
@@ -138,7 +137,6 @@
"ultra-runner": "^3.10.5"
},
"overrides": {
"@babel/core": "^8.0.1",
"@discordjs/rest": "2.6.1",
"@grpc/grpc-js": "1.14.4",
"@hono/node-server": "1.19.13",
@@ -1 +0,0 @@
!dist
@@ -1,6 +0,0 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`transforming actual files > multiple extensions exists 1`] = `
"// Expected to be transformed to use the \`.mjs\` extension, which is same as this file.
import { foo, bar } from "./modules/module.mjs";"
`;
@@ -1,2 +0,0 @@
# node_modules in the fixtures directory are part of the mocked project and should not be ignored
!node_modules
@@ -1 +0,0 @@
export * from './modules/hanzogui.dev.config'
@@ -1 +0,0 @@
export const bar = 'bar'
@@ -1 +0,0 @@
import { bar } from './bar'
@@ -1,2 +0,0 @@
exports.foo = 'foo'
exports.bar = 'bar'
@@ -1,2 +0,0 @@
exports.foo = 'foo'
exports.bar = 'bar'
@@ -1,4 +0,0 @@
export const foo = 'foo'
export const bar = 'bar'
export default foo
@@ -1,2 +0,0 @@
// Expected to be transformed to use the `.mjs` extension, which is same as this file.
import { foo, bar } from './modules/module'
@@ -1 +0,0 @@
export const createComponent = true
@@ -1 +0,0 @@
export const useNativeHook = true
@@ -1,2 +0,0 @@
export * from './createComponent'
export * from './hooks'
@@ -1,2 +0,0 @@
exports.foo = 'foo'
exports.bar = 'bar'
@@ -1,4 +0,0 @@
export const foo = 'foo'
export const bar = 'bar'
export default foo
@@ -1,13 +0,0 @@
import foo, { bar } from './modules/module'
import { foo as foo2 } from './modules/module'
import * as someModule from './modules/module'
import { foo as cjsFoo } from './modules/cjs-module'
// Will not be transformed
import { foo as packageFoo } from '@my-org/my-pkg'
// These will be transformed if `includePackages` includes `@my-org/my-pkg`.
import { someStuff } from '@my-org/my-pkg/lib'
// import { someOtherStuff } from '@my-org/my-pkg/lib/index' // TODO: Fix me
import { exampleFunction } from '@my-org/my-pkg/lib/exampleFunction'
@@ -1,148 +0,0 @@
import path from 'node:path'
import { describe, expect, test } from 'vitest'
import { type TransformOptions, transform, transformFileSync } from '@babel/core'
import plugin, { type FullySpecifiedOptions } from '../src'
/** A helper function to get the default transform options for the plugin to test. */
const getTransformOptions = ({
pluginOptions,
}: { pluginOptions?: Partial<FullySpecifiedOptions> } = {}) => ({
plugins: [[plugin, { ensureFileExists: false, ...pluginOptions }]],
})
/** A test helper for calling Babel transform with the plugin to test and some default options. */
function getTransformResult(
input,
{
transformOptions,
pluginOptions,
}: {
transformOptions?: TransformOptions
pluginOptions?: Partial<FullySpecifiedOptions>
} = {}
) {
return transform(input, {
filename: 'myFile.js',
configFile: false,
...transformOptions,
...getTransformOptions({ pluginOptions }),
})
}
describe('local imports', () => {
test('named import', () => {
const example1 = "import { foo } from './foo'"
expect(getTransformResult(example1)?.code).toBe('import { foo } from "./foo.mjs";')
const example2 = "import { foo as bar } from './foo'"
expect(getTransformResult(example2)?.code).toBe(
'import { foo as bar } from "./foo.mjs";'
)
})
test('default import', () => {
const example1 = "import defaultFoo from './foo'"
expect(getTransformResult(example1)?.code).toBe('import defaultFoo from "./foo.mjs";')
const example2 = "import defaultFoo, { foo } from './foo'"
expect(getTransformResult(example2)?.code).toBe(
'import defaultFoo, { foo } from "./foo.mjs";'
)
})
test('namespace import', () => {
const example = "import * as fooModule from './foo'"
expect(getTransformResult(example)?.code).toBe(
'import * as fooModule from "./foo.mjs";'
)
})
test('side effects only import', () => {
const example = "import './foo'"
expect(getTransformResult(example)?.code).toBe('import "./foo.mjs";')
})
test('dynamic import()', () => {
const example = "const foo = await import('./foo')"
expect(getTransformResult(example)?.code).toBe(
'const foo = await import("./foo.mjs");'
)
})
})
describe('local re-exports', () => {
test('named', () => {
const example1 = "export { foo } from './foo'"
expect(getTransformResult(example1)?.code).toBe('export { foo } from "./foo.mjs";')
const example2 = "export { foo as bar } from './foo'"
expect(getTransformResult(example2)?.code).toBe(
'export { foo as bar } from "./foo.mjs";'
)
})
test('default', () => {
const example1 = "export { default as fooDefault } from './foo'"
expect(getTransformResult(example1)?.code).toBe(
'export { default as fooDefault } from "./foo.mjs";'
)
})
test('namespace', () => {
const example1 = "export * as fooModule from './foo'"
expect(getTransformResult(example1)?.code).toBe(
'export * as fooModule from "./foo.mjs";'
)
const example2 = "export * from './foo'"
expect(getTransformResult(example2)?.code).toBe('export * from "./foo.mjs";')
})
})
describe('transforming actual files', () => {
test('multiple extensions exists', () => {
const { code } =
transformFileSync(
path.join(__dirname, 'fixtures', 'multiple-extensions-exists', 'test.mjs'),
getTransformOptions({
pluginOptions: { ensureFileExists: true },
})
) || {}
expect(code).toMatchSnapshot()
})
test('dotted basename gets the output extension appended', () => {
const { code } =
transformFileSync(
path.join(__dirname, 'fixtures', 'dotted-basename', 'test.mjs'),
getTransformOptions({
pluginOptions: { ensureFileExists: true },
})
) || {}
expect(code).toBe('export * from "./modules/hanzogui.dev.config.mjs";')
})
test('native output extension resolves native sibling files', () => {
const { code } =
transformFileSync(
path.join(__dirname, 'fixtures', 'native-extension', 'index.native.js'),
getTransformOptions({
pluginOptions: {
ensureFileExists: true,
esExtensionDefault: '.native.js',
esExtensions: ['.js'],
},
})
) || {}
expect(code).toBe(
[
'export * from "./createComponent.native.js";',
'export * from "./hooks/index.native.js";',
].join('\n')
)
})
})
@@ -1 +0,0 @@
Object.assign(module.exports, require('./permanent/cjs/commonjs.js'))
@@ -1,45 +0,0 @@
{
"name": "@hanzogui/babel-plugin-fully-specified",
"version": "8.3.1",
"gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
"license": "MIT",
"source": "src/index.ts",
"files": [
"src",
"types",
"permanent",
"commonjs.cjs"
],
"main": "permanent/cjs/index.js",
"module": "permanent/esm/index.mjs",
"exports": {
".": {
"types": "./types/index.d.ts",
"browser": "./permanent/esm/index.mjs",
"module": "./permanent/esm/index.mjs",
"import": "./permanent/esm/index.mjs",
"require": "./permanent/cjs/index.js",
"default": "./permanent/cjs/index.js"
},
"./commonjs": {
"types": "./types/commonjs.d.ts",
"browser": "./permanent/esm/commonjs.mjs",
"module": "./permanent/esm/commonjs.mjs",
"import": "./permanent/esm/commonjs.mjs",
"require": "./permanent/cjs/commonjs.js"
}
},
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "vitest --run"
},
"dependencies": {
"@babel/core": "^8.0.1"
},
"devDependencies": {
"@babel/types": "^8.0.4",
"vitest": "^4.1.11"
}
}
@@ -1,88 +0,0 @@
var __defProp = Object.defineProperty
var __getOwnPropDesc = Object.getOwnPropertyDescriptor
var __getOwnPropNames = Object.getOwnPropertyNames
var __hasOwnProp = Object.prototype.hasOwnProperty
var __export = (target, all) => {
for (var name in all) __defProp(target, name, { get: all[name], enumerable: !0 })
},
__copyProps = (to, from, except, desc) => {
if ((from && typeof from == 'object') || typeof from == 'function')
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) &&
key !== except &&
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
})
return to
}
var __toCommonJS = (mod) => __copyProps(__defProp({}, '__esModule', { value: !0 }), mod)
var commonjs_exports = {}
__export(commonjs_exports, {
default: () => fullySpecifyCommonJS,
})
module.exports = __toCommonJS(commonjs_exports)
var import_node_fs = require('node:fs'),
import_node_path = require('node:path')
function fullySpecifyCommonJS(api, options) {
return (
api.assertVersion(7),
{
name: 'babel-plugin-fully-specified-cjs',
visitor: {
CallExpression(path, state) {
if (
path.get('callee').isIdentifier({ name: 'require' }) &&
path.node.arguments.length === 1
) {
const arg = path.node.arguments[0]
if (arg.type === 'StringLiteral') {
let moduleSpecifier = arg.value
if (moduleSpecifier.startsWith('.') || moduleSpecifier.startsWith('/')) {
const filePath = state.file.opts.filename
if (!filePath) return
const fileDir = (0, import_node_path.dirname)(filePath),
cjsExtension = options.esExtensionDefault || '.cjs',
jsExtension = '.js'
if (!(0, import_node_path.extname)(moduleSpecifier)) {
const resolvedPath = (0, import_node_path.resolve)(
fileDir,
moduleSpecifier
)
let newModuleSpecifier = moduleSpecifier
if (isLocalDirectory(resolvedPath)) {
const indexPath = (0, import_node_path.resolve)(
resolvedPath,
'index' + jsExtension
)
if ((0, import_node_fs.existsSync)(indexPath)) {
;(newModuleSpecifier.endsWith('/') || (newModuleSpecifier += '/'),
(newModuleSpecifier += 'index' + cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
if (
(0, import_node_fs.existsSync)(resolvedPath + jsExtension) ||
(0, import_node_fs.existsSync)(resolvedPath + cjsExtension)
) {
;((newModuleSpecifier += cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
}
}
}
},
},
}
)
}
function isLocalDirectory(absolutePath) {
return (
(0, import_node_fs.existsSync)(absolutePath) &&
(0, import_node_fs.lstatSync)(absolutePath).isDirectory()
)
}
//# sourceMappingURL=commonjs.js.map
@@ -1,6 +0,0 @@
{
"version": 3,
"sources": ["../../src/commonjs.ts"],
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAsC,oBACtC,mBAA0C;AAE3B,SAAR,qBACL,KACA,SAGiB;AACjB,aAAI,cAAc,CAAC,GAEZ;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,MACP,eAAe,MAAM,OAAO;AAG1B,YAFe,KAAK,IAAI,QAAQ,EAGvB,aAAa,EAAE,MAAM,UAAU,CAAC,KACvC,KAAK,KAAK,UAAU,WAAW,GAC/B;AACA,gBAAM,MAAM,KAAK,KAAK,UAAU,CAAC;AACjC,cAAI,IAAI,SAAS,iBAAiB;AAChC,gBAAI,kBAAkB,IAAI;AAG1B,gBAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,WAAW,GAAG,GAAG;AACtE,oBAAM,WAAW,MAAM,KAAK,KAAK;AACjC,kBAAI,CAAC,SAAU;AAEf,oBAAM,cAAU,0BAAQ,QAAQ,GAC1B,eAAe,QAAQ,sBAAsB,QAC7C,cAAc;AAGpB,kBAAI,KAAC,0BAAQ,eAAe,GAAG;AAC7B,sBAAM,mBAAe,0BAAQ,SAAS,eAAe;AACrD,oBAAI,qBAAqB;AAGzB,oBAAI,iBAAiB,YAAY,GAAG;AAClC,wBAAM,gBAAY,0BAAQ,cAAc,UAAU,WAAW;AAC7D,0BAAI,2BAAW,SAAS,GAAG;AAEzB,oBAAK,mBAAmB,SAAS,GAAG,MAClC,sBAAsB,MAExB,sBAAsB,UAAU,cAChC,IAAI,QAAQ;AACZ;AAAA,kBACF;AAAA,gBACF;AAGA,sBAAM,iBAAiB,eAAe;AACtC,wBAAI,2BAAW,cAAc,GAAG;AAC9B,wCAAsB,cACtB,IAAI,QAAQ;AACZ;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,cAA+B;AACvD,aAAO,2BAAW,YAAY,SAAK,0BAAU,YAAY,EAAE,YAAY;AACzE;",
"names": []
}
@@ -1,98 +0,0 @@
var __defProp = Object.defineProperty
var __getOwnPropDesc = Object.getOwnPropertyDescriptor
var __getOwnPropNames = Object.getOwnPropertyNames
var __hasOwnProp = Object.prototype.hasOwnProperty
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, {
get: all[name],
enumerable: !0,
})
},
__copyProps = (to, from, except, desc) => {
if ((from && typeof from == 'object') || typeof from == 'function')
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) &&
key !== except &&
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
})
return to
}
var __toCommonJS = (mod) =>
__copyProps(
__defProp({}, '__esModule', {
value: !0,
}),
mod
)
var commonjs_exports = {}
__export(commonjs_exports, {
default: () => fullySpecifyCommonJS,
})
module.exports = __toCommonJS(commonjs_exports)
var import_node_fs = require('node:fs'),
import_node_path = require('node:path')
function fullySpecifyCommonJS(api, options) {
return (
api.assertVersion(7),
{
name: 'babel-plugin-fully-specified-cjs',
visitor: {
CallExpression(path, state) {
if (
path.get('callee').isIdentifier({
name: 'require',
}) &&
path.node.arguments.length === 1
) {
const arg = path.node.arguments[0]
if (arg.type === 'StringLiteral') {
let moduleSpecifier = arg.value
if (moduleSpecifier.startsWith('.') || moduleSpecifier.startsWith('/')) {
const filePath = state.file.opts.filename
if (!filePath) return
const fileDir = (0, import_node_path.dirname)(filePath),
cjsExtension = options.esExtensionDefault || '.cjs',
jsExtension = '.js'
if (!(0, import_node_path.extname)(moduleSpecifier)) {
const resolvedPath = (0, import_node_path.resolve)(
fileDir,
moduleSpecifier
)
let newModuleSpecifier = moduleSpecifier
if (isLocalDirectory(resolvedPath)) {
const indexPath = (0, import_node_path.resolve)(
resolvedPath,
'index' + jsExtension
)
if ((0, import_node_fs.existsSync)(indexPath)) {
;(newModuleSpecifier.endsWith('/') || (newModuleSpecifier += '/'),
(newModuleSpecifier += 'index' + cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
const filePathWithJs = resolvedPath + jsExtension
if ((0, import_node_fs.existsSync)(filePathWithJs)) {
;((newModuleSpecifier += cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
}
}
}
},
},
}
)
}
function isLocalDirectory(absolutePath) {
return (
(0, import_node_fs.existsSync)(absolutePath) &&
(0, import_node_fs.lstatSync)(absolutePath).isDirectory()
)
}
//# sourceMappingURL=commonjs.mjs.map
@@ -1 +0,0 @@
{"version":3,"names":["commonjs_exports","__export","default","fullySpecifyCommonJS","module","exports","__toCommonJS","import_node_fs","require","import_node_path","api","options","assertVersion","name","visitor","CallExpression","path","state","get","isIdentifier","node","arguments","length","arg","type","moduleSpecifier","value","startsWith","filePath","file","opts","filename","fileDir","dirname","cjsExtension","esExtensionDefault","jsExtension","extname","resolvedPath","resolve","newModuleSpecifier","isLocalDirectory","indexPath","existsSync","endsWith","filePathWithJs","absolutePath","lstatSync","isDirectory"],"sources":["../../src/commonjs.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,gBAAA;AAAAC,QAAA,CAAAD,gBAAA;EAAAE,OAAA,EAAAA,CAAA,KAAAC;AAAA;AAAAC,MAAA,CAAAC,OAAA,GAAAC,YAAA,CAAAN,gBAAA;AAAA,IAAAO,cAAA,GAAsCC,OAAA;EACtCC,gBAAA,GAA0CD,OAAA;AAE3B,SAARL,qBACLO,GAAA,EACAC,OAAA,EAGiB;EACjB,OAAAD,GAAA,CAAIE,aAAA,CAAc,CAAC,GAEZ;IACLC,IAAA,EAAM;IACNC,OAAA,EAAS;MACPC,eAAeC,IAAA,EAAMC,KAAA,EAAO;QAG1B,IAFeD,IAAA,CAAKE,GAAA,CAAI,QAAQ,EAGvBC,YAAA,CAAa;UAAEN,IAAA,EAAM;QAAU,CAAC,KACvCG,IAAA,CAAKI,IAAA,CAAKC,SAAA,CAAUC,MAAA,KAAW,GAC/B;UACA,MAAMC,GAAA,GAAMP,IAAA,CAAKI,IAAA,CAAKC,SAAA,CAAU,CAAC;UACjC,IAAIE,GAAA,CAAIC,IAAA,KAAS,iBAAiB;YAChC,IAAIC,eAAA,GAAkBF,GAAA,CAAIG,KAAA;YAG1B,IAAID,eAAA,CAAgBE,UAAA,CAAW,GAAG,KAAKF,eAAA,CAAgBE,UAAA,CAAW,GAAG,GAAG;cACtE,MAAMC,QAAA,GAAWX,KAAA,CAAMY,IAAA,CAAKC,IAAA,CAAKC,QAAA;cACjC,IAAI,CAACH,QAAA,EAAU;cAEf,MAAMI,OAAA,OAAUvB,gBAAA,CAAAwB,OAAA,EAAQL,QAAQ;gBAC1BM,YAAA,GAAevB,OAAA,CAAQwB,kBAAA,IAAsB;gBAC7CC,WAAA,GAAc;cAGpB,IAAI,KAAC3B,gBAAA,CAAA4B,OAAA,EAAQZ,eAAe,GAAG;gBAC7B,MAAMa,YAAA,OAAe7B,gBAAA,CAAA8B,OAAA,EAAQP,OAAA,EAASP,eAAe;gBACrD,IAAIe,kBAAA,GAAqBf,eAAA;gBAGzB,IAAIgB,gBAAA,CAAiBH,YAAY,GAAG;kBAClC,MAAMI,SAAA,OAAYjC,gBAAA,CAAA8B,OAAA,EAAQD,YAAA,EAAc,UAAUF,WAAW;kBAC7D,QAAI7B,cAAA,CAAAoC,UAAA,EAAWD,SAAS,GAAG;oBAEpBF,kBAAA,CAAmBI,QAAA,CAAS,GAAG,MAClCJ,kBAAA,IAAsB,MAExBA,kBAAA,IAAsB,UAAUN,YAAA,EAChCX,GAAA,CAAIG,KAAA,GAAQc,kBAAA;oBACZ;kBACF;gBACF;gBAGA,MAAMK,cAAA,GAAiBP,YAAA,GAAeF,WAAA;gBACtC,QAAI7B,cAAA,CAAAoC,UAAA,EAAWE,cAAc,GAAG;kBAC9BL,kBAAA,IAAsBN,YAAA,EACtBX,GAAA,CAAIG,KAAA,GAAQc,kBAAA;kBACZ;gBACF;cACF;YACF;UACF;QACF;MACF;IACF;EACF;AACF;AAEA,SAASC,iBAAiBK,YAAA,EAA+B;EACvD,WAAOvC,cAAA,CAAAoC,UAAA,EAAWG,YAAY,SAAKvC,cAAA,CAAAwC,SAAA,EAAUD,YAAY,EAAEE,WAAA,CAAY;AACzE","ignoreList":[]}
@@ -1,209 +0,0 @@
var __create = Object.create
var __defProp = Object.defineProperty
var __getOwnPropDesc = Object.getOwnPropertyDescriptor
var __getOwnPropNames = Object.getOwnPropertyNames
var __getProtoOf = Object.getPrototypeOf,
__hasOwnProp = Object.prototype.hasOwnProperty
var __export = (target, all) => {
for (var name in all) __defProp(target, name, { get: all[name], enumerable: !0 })
},
__copyProps = (to, from, except, desc) => {
if ((from && typeof from == 'object') || typeof from == 'function')
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) &&
key !== except &&
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
})
return to
}
var __toESM = (mod, isNodeMode, target) => (
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
__copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule
? __defProp(target, 'default', { value: mod, enumerable: !0 })
: target,
mod
)
),
__toCommonJS = (mod) => __copyProps(__defProp({}, '__esModule', { value: !0 }), mod)
var index_exports = {}
__export(index_exports, {
default: () => FullySpecified,
})
module.exports = __toCommonJS(index_exports)
var import_node_fs = require('node:fs'),
import_node_path = require('node:path'),
t = __toESM(require('@babel/types'))
const DEFAULT_OPTIONS = {
ensureFileExists: !0,
esExtensionDefault: '.mjs',
tryExtensions: ['.js'],
esExtensions: ['.mjs'],
convertProcessEnvToImportMetaEnv: !1,
}
function FullySpecified(api, rawOptions = {}) {
api.assertVersion(7)
const options = normalizeOptions(rawOptions),
importDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.importKind === 'type') return
const originalModuleSpecifier = node.source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier)
},
exportDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.exportKind === 'type') return
const source = node.source
if (!source) return
const originalModuleSpecifier = source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier)
}
return {
name: 'babel-plugin-fully-specified',
visitor: {
ImportDeclaration: importDeclarationVisitor,
ExportNamedDeclaration: exportDeclarationVisitor,
ExportAllDeclaration: exportDeclarationVisitor,
Import: (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const parent = path.parent
if (parent.type !== 'CallExpression') return
const firstArgOfImportCall = parent.arguments[0]
if (firstArgOfImportCall.type !== 'StringLiteral') return
const originalModuleSpecifier = firstArgOfImportCall.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier &&
(firstArgOfImportCall.value = fullySpecifiedModuleSpecifier)
},
MemberExpression: (path) => {
if (!options.convertProcessEnvToImportMetaEnv) return
const { node } = path
if (
node.object.type === 'MemberExpression' &&
node.object.object.type === 'Identifier' &&
node.object.object.name === 'process' &&
node.object.property.type === 'Identifier' &&
node.object.property.name === 'env'
) {
if (node.property.type === 'Identifier' && node.property.name === 'NODE_ENV')
return
node.object = t.memberExpression(
t.metaProperty(t.identifier('import'), t.identifier('meta')),
t.identifier('env')
)
}
},
},
}
}
function normalizeOptions(rawOptions) {
const options = { ...DEFAULT_OPTIONS, ...rawOptions }
return (
rawOptions.esExtensionDefault &&
!rawOptions.tryExtensions &&
rawOptions.esExtensionDefault !== DEFAULT_OPTIONS.esExtensionDefault &&
(options.tryExtensions = [
rawOptions.esExtensionDefault,
...DEFAULT_OPTIONS.tryExtensions.filter(
(extension) => extension !== rawOptions.esExtensionDefault
),
]),
options
)
}
function getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{ filePath, options }
) {
const fileExt = (0, import_node_path.extname)(filePath),
fileDir = (0, import_node_path.dirname)(filePath),
isDirectory = isLocalDirectory(
(0, import_node_path.resolve)(fileDir, originalModuleSpecifier)
),
currentModuleExtension = (0, import_node_path.extname)(originalModuleSpecifier),
{ tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options,
targetModule = evaluateTargetModule({
moduleSpecifier: originalModuleSpecifier,
filenameDirectory: fileDir,
filenameExtension: fileExt,
currentModuleExtension,
isDirectory,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
})
return targetModule === !1 ? null : targetModule
}
function isLocalDirectory(absoluteDirectory) {
return (
(0, import_node_fs.existsSync)(absoluteDirectory) &&
(0, import_node_fs.lstatSync)(absoluteDirectory).isDirectory()
)
}
function evaluateTargetModule({
moduleSpecifier,
currentModuleExtension,
isDirectory,
filenameDirectory,
filenameExtension,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
}) {
const targetFile = (0, import_node_path.resolve)(filenameDirectory, moduleSpecifier)
if (ensureFileExists) {
for (const extension of tryExtensions)
if ((0, import_node_fs.existsSync)(targetFile + extension))
return moduleSpecifier + esExtensionDefault
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension))
return !1
if (isDirectory) {
const indexModuleSpecifier = `${moduleSpecifier.replace(/\/$/, '')}/index`,
indexTargetFile = (0, import_node_path.resolve)(
filenameDirectory,
indexModuleSpecifier
)
for (const extension of tryExtensions)
if ((0, import_node_fs.existsSync)(indexTargetFile + extension))
return indexModuleSpecifier + esExtensionDefault
}
} else
return (
esExtensions.includes(filenameExtension), moduleSpecifier + esExtensionDefault
)
return !1
}
//# sourceMappingURL=index.js.map
@@ -1,6 +0,0 @@
{
"version": 3,
"sources": ["../../src/index.ts"],
"mappings": "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",
"names": []
}
@@ -1,220 +0,0 @@
var __create = Object.create
var __defProp = Object.defineProperty
var __getOwnPropDesc = Object.getOwnPropertyDescriptor
var __getOwnPropNames = Object.getOwnPropertyNames
var __getProtoOf = Object.getPrototypeOf,
__hasOwnProp = Object.prototype.hasOwnProperty
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, {
get: all[name],
enumerable: !0,
})
},
__copyProps = (to, from, except, desc) => {
if ((from && typeof from == 'object') || typeof from == 'function')
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) &&
key !== except &&
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
})
return to
}
var __toESM = (mod, isNodeMode, target) => (
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
__copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule
? __defProp(target, 'default', {
value: mod,
enumerable: !0,
})
: target,
mod
)
),
__toCommonJS = (mod) =>
__copyProps(
__defProp({}, '__esModule', {
value: !0,
}),
mod
)
var index_exports = {}
__export(index_exports, {
default: () => FullySpecified,
})
module.exports = __toCommonJS(index_exports)
var import_node_fs = require('node:fs'),
import_node_path = require('node:path'),
t = __toESM(require('@babel/types'))
const DEFAULT_OPTIONS = {
ensureFileExists: !0,
esExtensionDefault: '.mjs',
tryExtensions: ['.js'],
esExtensions: ['.mjs'],
convertProcessEnvToImportMetaEnv: !1,
}
function FullySpecified(api, rawOptions = {}) {
api.assertVersion(7)
const options = normalizeOptions(rawOptions),
importDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.importKind === 'type') return
const originalModuleSpecifier = node.source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier)
},
exportDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.exportKind === 'type') return
const source = node.source
if (!source) return
const originalModuleSpecifier = source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier)
}
return {
name: 'babel-plugin-fully-specified',
visitor: {
ImportDeclaration: importDeclarationVisitor,
ExportNamedDeclaration: exportDeclarationVisitor,
ExportAllDeclaration: exportDeclarationVisitor,
Import: (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const parent = path.parent
if (parent.type !== 'CallExpression') return
const firstArgOfImportCall = parent.arguments[0]
if (firstArgOfImportCall.type !== 'StringLiteral') return
const originalModuleSpecifier = firstArgOfImportCall.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier &&
(firstArgOfImportCall.value = fullySpecifiedModuleSpecifier)
},
MemberExpression: (path) => {
if (!options.convertProcessEnvToImportMetaEnv) return
const { node } = path
if (
node.object.type === 'MemberExpression' &&
node.object.object.type === 'Identifier' &&
node.object.object.name === 'process' &&
node.object.property.type === 'Identifier' &&
node.object.property.name === 'env'
) {
if (node.property.type === 'Identifier' && node.property.name === 'NODE_ENV')
return
node.object = t.memberExpression(
t.metaProperty(t.identifier('import'), t.identifier('meta')),
t.identifier('env')
)
}
},
},
}
}
function normalizeOptions(rawOptions) {
const options = { ...DEFAULT_OPTIONS, ...rawOptions }
return (
rawOptions.esExtensionDefault &&
!rawOptions.tryExtensions &&
rawOptions.esExtensionDefault !== DEFAULT_OPTIONS.esExtensionDefault &&
(options.tryExtensions = [
rawOptions.esExtensionDefault,
...DEFAULT_OPTIONS.tryExtensions.filter(
(extension) => extension !== rawOptions.esExtensionDefault
),
]),
options
)
}
function getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{ filePath, options }
) {
const fileExt = (0, import_node_path.extname)(filePath),
fileDir = (0, import_node_path.dirname)(filePath),
isDirectory = isLocalDirectory(
(0, import_node_path.resolve)(fileDir, originalModuleSpecifier)
),
currentModuleExtension = (0, import_node_path.extname)(originalModuleSpecifier),
{ tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options,
targetModule = evaluateTargetModule({
moduleSpecifier: originalModuleSpecifier,
filenameDirectory: fileDir,
filenameExtension: fileExt,
currentModuleExtension,
isDirectory,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
})
return targetModule === !1 ? null : targetModule
}
function isLocalDirectory(absoluteDirectory) {
return (
(0, import_node_fs.existsSync)(absoluteDirectory) &&
(0, import_node_fs.lstatSync)(absoluteDirectory).isDirectory()
)
}
function evaluateTargetModule({
moduleSpecifier,
currentModuleExtension,
isDirectory,
filenameDirectory,
filenameExtension,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
}) {
const targetFile = (0, import_node_path.resolve)(filenameDirectory, moduleSpecifier)
if (ensureFileExists) {
for (const extension of tryExtensions)
if ((0, import_node_fs.existsSync)(targetFile + extension))
return moduleSpecifier + esExtensionDefault
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension))
return !1
isDirectory &&
!(0, import_node_fs.existsSync)(
(0, import_node_path.resolve)(
filenameDirectory,
currentModuleExtension ? moduleSpecifier : moduleSpecifier + esExtensionDefault
)
) &&
(moduleSpecifier = `${moduleSpecifier}/index`)
} else
return (
esExtensions.includes(filenameExtension), moduleSpecifier + esExtensionDefault
)
return !1
}
//# sourceMappingURL=index.mjs.map
File diff suppressed because one or more lines are too long
@@ -1,54 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
function fullySpecifyCommonJS(api, options) {
return (
api.assertVersion(7),
{
name: 'babel-plugin-fully-specified-cjs',
visitor: {
CallExpression(path, state) {
if (
path.get('callee').isIdentifier({ name: 'require' }) &&
path.node.arguments.length === 1
) {
const arg = path.node.arguments[0]
if (arg.type === 'StringLiteral') {
let moduleSpecifier = arg.value
if (moduleSpecifier.startsWith('.') || moduleSpecifier.startsWith('/')) {
const filePath = state.file.opts.filename
if (!filePath) return
const fileDir = dirname(filePath),
cjsExtension = options.esExtensionDefault || '.cjs',
jsExtension = '.js'
if (!extname(moduleSpecifier)) {
const resolvedPath = resolve(fileDir, moduleSpecifier)
let newModuleSpecifier = moduleSpecifier
if (isLocalDirectory(resolvedPath)) {
const indexPath = resolve(resolvedPath, 'index' + jsExtension)
if (existsSync(indexPath)) {
;(newModuleSpecifier.endsWith('/') || (newModuleSpecifier += '/'),
(newModuleSpecifier += 'index' + cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
const filePathWithJs = resolvedPath + jsExtension
if (existsSync(filePathWithJs)) {
;((newModuleSpecifier += cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
}
}
}
},
},
}
)
}
function isLocalDirectory(absolutePath) {
return existsSync(absolutePath) && lstatSync(absolutePath).isDirectory()
}
export { fullySpecifyCommonJS as default }
//# sourceMappingURL=commonjs.js.map
@@ -1,6 +0,0 @@
{
"version": 3,
"sources": ["../../src/commonjs.ts"],
"mappings": "AAAA,SAAS,YAAY,iBAAiB;AACtC,SAAS,SAAS,SAAS,eAAe;AAE3B,SAAR,qBACL,KACA,SAGiB;AACjB,aAAI,cAAc,CAAC,GAEZ;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,MACP,eAAe,MAAM,OAAO;AAG1B,YAFe,KAAK,IAAI,QAAQ,EAGvB,aAAa,EAAE,MAAM,UAAU,CAAC,KACvC,KAAK,KAAK,UAAU,WAAW,GAC/B;AACA,gBAAM,MAAM,KAAK,KAAK,UAAU,CAAC;AACjC,cAAI,IAAI,SAAS,iBAAiB;AAChC,gBAAI,kBAAkB,IAAI;AAG1B,gBAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,WAAW,GAAG,GAAG;AACtE,oBAAM,WAAW,MAAM,KAAK,KAAK;AACjC,kBAAI,CAAC,SAAU;AAEf,oBAAM,UAAU,QAAQ,QAAQ,GAC1B,eAAe,QAAQ,sBAAsB,QAC7C,cAAc;AAGpB,kBAAI,CAAC,QAAQ,eAAe,GAAG;AAC7B,sBAAM,eAAe,QAAQ,SAAS,eAAe;AACrD,oBAAI,qBAAqB;AAGzB,oBAAI,iBAAiB,YAAY,GAAG;AAClC,wBAAM,YAAY,QAAQ,cAAc,UAAU,WAAW;AAC7D,sBAAI,WAAW,SAAS,GAAG;AAEzB,oBAAK,mBAAmB,SAAS,GAAG,MAClC,sBAAsB,MAExB,sBAAsB,UAAU,cAChC,IAAI,QAAQ;AACZ;AAAA,kBACF;AAAA,gBACF;AAGA,sBAAM,iBAAiB,eAAe;AACtC,oBAAI,WAAW,cAAc,GAAG;AAC9B,wCAAsB,cACtB,IAAI,QAAQ;AACZ;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,cAA+B;AACvD,SAAO,WAAW,YAAY,KAAK,UAAU,YAAY,EAAE,YAAY;AACzE;",
"names": []
}
@@ -1,58 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
function fullySpecifyCommonJS(api, options) {
return (
api.assertVersion(7),
{
name: 'babel-plugin-fully-specified-cjs',
visitor: {
CallExpression(path, state) {
if (
path.get('callee').isIdentifier({
name: 'require',
}) &&
path.node.arguments.length === 1
) {
const arg = path.node.arguments[0]
if (arg.type === 'StringLiteral') {
let moduleSpecifier = arg.value
if (moduleSpecifier.startsWith('.') || moduleSpecifier.startsWith('/')) {
const filePath = state.file.opts.filename
if (!filePath) return
const fileDir = dirname(filePath),
cjsExtension = options.esExtensionDefault || '.cjs',
jsExtension = '.js'
if (!extname(moduleSpecifier)) {
const resolvedPath = resolve(fileDir, moduleSpecifier)
let newModuleSpecifier = moduleSpecifier
if (isLocalDirectory(resolvedPath)) {
const indexPath = resolve(resolvedPath, 'index' + jsExtension)
if (existsSync(indexPath)) {
;(newModuleSpecifier.endsWith('/') || (newModuleSpecifier += '/'),
(newModuleSpecifier += 'index' + cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
if (
existsSync(resolvedPath + jsExtension) ||
existsSync(resolvedPath + cjsExtension)
) {
;((newModuleSpecifier += cjsExtension),
(arg.value = newModuleSpecifier))
return
}
}
}
}
}
},
},
}
)
}
function isLocalDirectory(absolutePath) {
return existsSync(absolutePath) && lstatSync(absolutePath).isDirectory()
}
export { fullySpecifyCommonJS as default }
//# sourceMappingURL=commonjs.mjs.map
@@ -1 +0,0 @@
{"version":3,"names":["existsSync","lstatSync","dirname","extname","resolve","fullySpecifyCommonJS","api","options","assertVersion","name","visitor","CallExpression","path","state","get","isIdentifier","node","arguments","length","arg","type","moduleSpecifier","value","startsWith","filePath","file","opts","filename","fileDir","cjsExtension","esExtensionDefault","jsExtension","resolvedPath","newModuleSpecifier","isLocalDirectory","indexPath","endsWith","filePathWithJs","absolutePath","isDirectory"],"sources":["../../src/commonjs.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,UAAA,EAAYC,SAAA,QAAiB;AACtC,SAASC,OAAA,EAASC,OAAA,EAASC,OAAA,QAAe;AAE3B,SAARC,qBACLC,GAAA,EACAC,OAAA,EAGiB;EACjB,OAAAD,GAAA,CAAIE,aAAA,CAAc,CAAC,GAEZ;IACLC,IAAA,EAAM;IACNC,OAAA,EAAS;MACPC,eAAeC,IAAA,EAAMC,KAAA,EAAO;QAG1B,IAFeD,IAAA,CAAKE,GAAA,CAAI,QAAQ,EAGvBC,YAAA,CAAa;UAAEN,IAAA,EAAM;QAAU,CAAC,KACvCG,IAAA,CAAKI,IAAA,CAAKC,SAAA,CAAUC,MAAA,KAAW,GAC/B;UACA,MAAMC,GAAA,GAAMP,IAAA,CAAKI,IAAA,CAAKC,SAAA,CAAU,CAAC;UACjC,IAAIE,GAAA,CAAIC,IAAA,KAAS,iBAAiB;YAChC,IAAIC,eAAA,GAAkBF,GAAA,CAAIG,KAAA;YAG1B,IAAID,eAAA,CAAgBE,UAAA,CAAW,GAAG,KAAKF,eAAA,CAAgBE,UAAA,CAAW,GAAG,GAAG;cACtE,MAAMC,QAAA,GAAWX,KAAA,CAAMY,IAAA,CAAKC,IAAA,CAAKC,QAAA;cACjC,IAAI,CAACH,QAAA,EAAU;cAEf,MAAMI,OAAA,GAAU1B,OAAA,CAAQsB,QAAQ;gBAC1BK,YAAA,GAAetB,OAAA,CAAQuB,kBAAA,IAAsB;gBAC7CC,WAAA,GAAc;cAGpB,IAAI,CAAC5B,OAAA,CAAQkB,eAAe,GAAG;gBAC7B,MAAMW,YAAA,GAAe5B,OAAA,CAAQwB,OAAA,EAASP,eAAe;gBACrD,IAAIY,kBAAA,GAAqBZ,eAAA;gBAGzB,IAAIa,gBAAA,CAAiBF,YAAY,GAAG;kBAClC,MAAMG,SAAA,GAAY/B,OAAA,CAAQ4B,YAAA,EAAc,UAAUD,WAAW;kBAC7D,IAAI/B,UAAA,CAAWmC,SAAS,GAAG;oBAEpBF,kBAAA,CAAmBG,QAAA,CAAS,GAAG,MAClCH,kBAAA,IAAsB,MAExBA,kBAAA,IAAsB,UAAUJ,YAAA,EAChCV,GAAA,CAAIG,KAAA,GAAQW,kBAAA;oBACZ;kBACF;gBACF;gBAGA,MAAMI,cAAA,GAAiBL,YAAA,GAAeD,WAAA;gBACtC,IAAI/B,UAAA,CAAWqC,cAAc,GAAG;kBAC9BJ,kBAAA,IAAsBJ,YAAA,EACtBV,GAAA,CAAIG,KAAA,GAAQW,kBAAA;kBACZ;gBACF;cACF;YACF;UACF;QACF;MACF;IACF;EACF;AACF;AAEA,SAASC,iBAAiBI,YAAA,EAA+B;EACvD,OAAOtC,UAAA,CAAWsC,YAAY,KAAKrC,SAAA,CAAUqC,YAAY,EAAEC,WAAA,CAAY;AACzE","ignoreList":[]}
@@ -1,163 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
import * as t from '@babel/types'
const DEFAULT_OPTIONS = {
ensureFileExists: !0,
esExtensionDefault: '.mjs',
tryExtensions: ['.js'],
esExtensions: ['.mjs'],
convertProcessEnvToImportMetaEnv: !1,
}
function FullySpecified(api, rawOptions = {}) {
api.assertVersion(7)
const options = normalizeOptions(rawOptions),
importDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.importKind === 'type') return
const originalModuleSpecifier = node.source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier)
},
exportDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.exportKind === 'type') return
const source = node.source
if (!source) return
const originalModuleSpecifier = source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier)
}
return {
name: 'babel-plugin-fully-specified',
visitor: {
ImportDeclaration: importDeclarationVisitor,
ExportNamedDeclaration: exportDeclarationVisitor,
ExportAllDeclaration: exportDeclarationVisitor,
Import: (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const parent = path.parent
if (parent.type !== 'CallExpression') return
const firstArgOfImportCall = parent.arguments[0]
if (firstArgOfImportCall.type !== 'StringLiteral') return
const originalModuleSpecifier = firstArgOfImportCall.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier &&
(firstArgOfImportCall.value = fullySpecifiedModuleSpecifier)
},
MemberExpression: (path) => {
if (!options.convertProcessEnvToImportMetaEnv) return
const { node } = path
if (
node.object.type === 'MemberExpression' &&
node.object.object.type === 'Identifier' &&
node.object.object.name === 'process' &&
node.object.property.type === 'Identifier' &&
node.object.property.name === 'env'
) {
if (node.property.type === 'Identifier' && node.property.name === 'NODE_ENV')
return
node.object = t.memberExpression(
t.metaProperty(t.identifier('import'), t.identifier('meta')),
t.identifier('env')
)
}
},
},
}
}
function normalizeOptions(rawOptions) {
const options = { ...DEFAULT_OPTIONS, ...rawOptions }
return (
rawOptions.esExtensionDefault &&
!rawOptions.tryExtensions &&
rawOptions.esExtensionDefault !== DEFAULT_OPTIONS.esExtensionDefault &&
(options.tryExtensions = [
rawOptions.esExtensionDefault,
...DEFAULT_OPTIONS.tryExtensions.filter(
(extension) => extension !== rawOptions.esExtensionDefault
),
]),
options
)
}
function getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{ filePath, options }
) {
const fileExt = extname(filePath),
fileDir = dirname(filePath),
isDirectory = isLocalDirectory(resolve(fileDir, originalModuleSpecifier)),
currentModuleExtension = extname(originalModuleSpecifier),
{ tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options,
targetModule = evaluateTargetModule({
moduleSpecifier: originalModuleSpecifier,
filenameDirectory: fileDir,
filenameExtension: fileExt,
currentModuleExtension,
isDirectory,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
})
return targetModule === !1 ? null : targetModule
}
function isLocalDirectory(absoluteDirectory) {
return existsSync(absoluteDirectory) && lstatSync(absoluteDirectory).isDirectory()
}
function evaluateTargetModule({
moduleSpecifier,
currentModuleExtension,
isDirectory,
filenameDirectory,
filenameExtension,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
}) {
const targetFile = resolve(filenameDirectory, moduleSpecifier)
if (ensureFileExists) {
for (const extension of tryExtensions)
if (existsSync(targetFile + extension)) return moduleSpecifier + esExtensionDefault
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension))
return !1
isDirectory &&
!existsSync(
resolve(
filenameDirectory,
currentModuleExtension ? moduleSpecifier : moduleSpecifier + esExtensionDefault
)
) &&
(moduleSpecifier = `${moduleSpecifier}/index`)
} else
return (
esExtensions.includes(filenameExtension), moduleSpecifier + esExtensionDefault
)
return !1
}
export { FullySpecified as default }
//# sourceMappingURL=index.js.map
@@ -1,6 +0,0 @@
{
"version": 3,
"sources": ["../../src/index.ts"],
"mappings": "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",
"names": []
}
@@ -1,162 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
import * as t from '@babel/types'
const DEFAULT_OPTIONS = {
ensureFileExists: !0,
esExtensionDefault: '.mjs',
tryExtensions: ['.js'],
esExtensions: ['.mjs'],
convertProcessEnvToImportMetaEnv: !1,
}
function FullySpecified(api, rawOptions = {}) {
api.assertVersion(7)
const options = normalizeOptions(rawOptions),
importDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.importKind === 'type') return
const originalModuleSpecifier = node.source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier)
},
exportDeclarationVisitor = (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const { node } = path
if (node.exportKind === 'type') return
const source = node.source
if (!source) return
const originalModuleSpecifier = source.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier)
}
return {
name: 'babel-plugin-fully-specified',
visitor: {
ImportDeclaration: importDeclarationVisitor,
ExportNamedDeclaration: exportDeclarationVisitor,
ExportAllDeclaration: exportDeclarationVisitor,
Import: (path, state) => {
const filePath = state.file.opts.filename
if (!filePath) return
const parent = path.parent
if (parent.type !== 'CallExpression') return
const firstArgOfImportCall = parent.arguments[0]
if (firstArgOfImportCall.type !== 'StringLiteral') return
const originalModuleSpecifier = firstArgOfImportCall.value,
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
fullySpecifiedModuleSpecifier &&
(firstArgOfImportCall.value = fullySpecifiedModuleSpecifier)
},
MemberExpression: (path) => {
if (!options.convertProcessEnvToImportMetaEnv) return
const { node } = path
if (
node.object.type === 'MemberExpression' &&
node.object.object.type === 'Identifier' &&
node.object.object.name === 'process' &&
node.object.property.type === 'Identifier' &&
node.object.property.name === 'env'
) {
if (node.property.type === 'Identifier' && node.property.name === 'NODE_ENV')
return
node.object = t.memberExpression(
t.metaProperty(t.identifier('import'), t.identifier('meta')),
t.identifier('env')
)
}
},
},
}
}
function normalizeOptions(rawOptions) {
const options = { ...DEFAULT_OPTIONS, ...rawOptions }
return (
rawOptions.esExtensionDefault &&
!rawOptions.tryExtensions &&
rawOptions.esExtensionDefault !== DEFAULT_OPTIONS.esExtensionDefault &&
(options.tryExtensions = [
rawOptions.esExtensionDefault,
...DEFAULT_OPTIONS.tryExtensions.filter(
(extension) => extension !== rawOptions.esExtensionDefault
),
]),
options
)
}
function getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{ filePath, options }
) {
const fileExt = extname(filePath),
fileDir = dirname(filePath),
isDirectory = isLocalDirectory(resolve(fileDir, originalModuleSpecifier)),
currentModuleExtension = extname(originalModuleSpecifier),
{ tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options,
targetModule = evaluateTargetModule({
moduleSpecifier: originalModuleSpecifier,
filenameDirectory: fileDir,
filenameExtension: fileExt,
currentModuleExtension,
isDirectory,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
})
return targetModule === !1 ? null : targetModule
}
function isLocalDirectory(absoluteDirectory) {
return existsSync(absoluteDirectory) && lstatSync(absoluteDirectory).isDirectory()
}
function evaluateTargetModule({
moduleSpecifier,
currentModuleExtension,
isDirectory,
filenameDirectory,
filenameExtension,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
}) {
const targetFile = resolve(filenameDirectory, moduleSpecifier)
if (ensureFileExists) {
for (const extension of tryExtensions)
if (existsSync(targetFile + extension)) return moduleSpecifier + esExtensionDefault
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension))
return !1
if (isDirectory) {
const indexModuleSpecifier = `${moduleSpecifier.replace(/\/$/, '')}/index`,
indexTargetFile = resolve(filenameDirectory, indexModuleSpecifier)
for (const extension of tryExtensions)
if (existsSync(indexTargetFile + extension))
return indexModuleSpecifier + esExtensionDefault
}
} else
return (
esExtensions.includes(filenameExtension), moduleSpecifier + esExtensionDefault
)
return !1
}
export { FullySpecified as default }
//# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
{"version":3,"names":["existsSync","lstatSync","dirname","extname","resolve","t","DEFAULT_OPTIONS","ensureFileExists","esExtensionDefault","tryExtensions","esExtensions","convertProcessEnvToImportMetaEnv","FullySpecified","api","rawOptions","assertVersion","options","importDeclarationVisitor","path","state","filePath","file","opts","filename","node","importKind","originalModuleSpecifier","source","value","fullySpecifiedModuleSpecifier","getFullySpecifiedModuleSpecifier","exportDeclarationVisitor","exportKind","name","visitor","ImportDeclaration","ExportNamedDeclaration","ExportAllDeclaration","Import","parent","type","firstArgOfImportCall","arguments","MemberExpression","object","property","memberExpression","metaProperty","identifier","fileExt","fileDir","isDirectory","isLocalDirectory","currentModuleExtension","targetModule","evaluateTargetModule","moduleSpecifier","filenameDirectory","filenameExtension","absoluteDirectory","includes","targetFile","extension"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -1 +0,0 @@
not doing dist here for now since it is used by hanzogui-build itself
@@ -1,74 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
export default function fullySpecifyCommonJS(
api: any,
options: {
esExtensionDefault: string
}
): babel.PluginObj {
api.assertVersion(7)
return {
name: 'babel-plugin-fully-specified-cjs',
visitor: {
CallExpression(path, state) {
const callee = path.get('callee')
if (
callee.isIdentifier({ name: 'require' }) &&
path.node.arguments.length === 1
) {
const arg = path.node.arguments[0]
if (arg.type === 'StringLiteral') {
let moduleSpecifier = arg.value
// Skip built-in modules and node_modules
if (moduleSpecifier.startsWith('.') || moduleSpecifier.startsWith('/')) {
const filePath = state.file.opts.filename
if (!filePath) return // Cannot determine file path
const fileDir = dirname(filePath)
const cjsExtension = options.esExtensionDefault || '.cjs'
const jsExtension = '.js'
// Check if moduleSpecifier already has an extension
if (!extname(moduleSpecifier)) {
const resolvedPath = resolve(fileDir, moduleSpecifier)
let newModuleSpecifier = moduleSpecifier
// Check if the moduleSpecifier is a directory with an index.cjs file
if (isLocalDirectory(resolvedPath)) {
const indexPath = resolve(resolvedPath, 'index' + jsExtension)
if (existsSync(indexPath)) {
// Append '/' if not present
if (!newModuleSpecifier.endsWith('/')) {
newModuleSpecifier += '/'
}
newModuleSpecifier += 'index' + cjsExtension
arg.value = newModuleSpecifier
return
}
}
// Check if source file exists (try .js first, then target extension)
if (
existsSync(resolvedPath + jsExtension) ||
existsSync(resolvedPath + cjsExtension)
) {
newModuleSpecifier += cjsExtension
arg.value = newModuleSpecifier
return
}
}
}
}
}
},
},
} satisfies babel.PluginObj
}
function isLocalDirectory(absolutePath: string): boolean {
return existsSync(absolutePath) && lstatSync(absolutePath).isDirectory()
}
@@ -1,280 +0,0 @@
import { existsSync, lstatSync } from 'node:fs'
import { dirname, extname, resolve } from 'node:path'
import type { ConfigAPI, NodePath, PluginObj, PluginPass } from '@babel/core'
import * as t from '@babel/types'
import type {
ExportAllDeclaration,
ExportNamedDeclaration,
Import,
ImportDeclaration,
MemberExpression,
} from '@babel/types'
export interface FullySpecifiedOptions {
ensureFileExists: boolean
esExtensionDefault: string
/** List of all extensions which we try to find. */
tryExtensions: Array<string>
/** List of extensions that can run in Node.js or in the Browser. */
esExtensions: Array<string>
/** Convert process.env.XYZ to import.meta.env.XYZ */
convertProcessEnvToImportMetaEnv?: boolean
}
const DEFAULT_OPTIONS = {
ensureFileExists: true,
esExtensionDefault: '.mjs',
tryExtensions: ['.js'],
esExtensions: ['.mjs'],
convertProcessEnvToImportMetaEnv: false,
} satisfies FullySpecifiedOptions
export default function FullySpecified(
api: ConfigAPI,
rawOptions: Partial<FullySpecifiedOptions> = {}
): PluginObj {
api.assertVersion(7)
const options = normalizeOptions(rawOptions)
/** For `import ... from '...'`. */
const importDeclarationVisitor = (
path: NodePath<ImportDeclaration>,
state: PluginPass
) => {
const filePath = state.file.opts.filename
if (!filePath) return // cannot determine file path therefore cannot proceed
const { node } = path
if (node.importKind === 'type') return // is a type-only import, skip
const originalModuleSpecifier = node.source.value
const fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
if (fullySpecifiedModuleSpecifier) {
node.source.value = fullySpecifiedModuleSpecifier
}
}
/** For `export ... from '...'`. */
const exportDeclarationVisitor = (
path: NodePath<ExportNamedDeclaration> | NodePath<ExportAllDeclaration>,
state: PluginPass
) => {
const filePath = state.file.opts.filename
if (!filePath) return // cannot determine file path therefore cannot proceed
const { node } = path
if (node.exportKind === 'type') return // is a type-only export, skip
const source = node.source
if (!source) return // is not a re-export, skip
const originalModuleSpecifier = source.value
const fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
if (fullySpecifiedModuleSpecifier) {
source.value = fullySpecifiedModuleSpecifier
}
}
/** For dynamic `import()`s. */
const importVisitor = (path: NodePath<Import>, state) => {
const filePath = state.file.opts.filename
if (!filePath) return // cannot determine file path therefore cannot proceed
const parent = path.parent
if (parent.type !== 'CallExpression') {
return // we expect the usage of `import` is a call to it, e.g.: `import('...')`, other usages are not supported
}
const firstArgOfImportCall = parent.arguments[0]
if (firstArgOfImportCall.type !== 'StringLiteral') {
return // we expect the first argument of `import` to be a string, e.g.: `import('./myModule')`, other types are not supported
}
const originalModuleSpecifier = firstArgOfImportCall.value
const fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
originalModuleSpecifier,
{
filePath,
options,
}
)
if (fullySpecifiedModuleSpecifier) {
firstArgOfImportCall.value = fullySpecifiedModuleSpecifier
}
}
/** For converting process.env to import.meta.env */
const memberExpressionVisitor = (path: NodePath<MemberExpression>) => {
if (!options.convertProcessEnvToImportMetaEnv) return
const { node } = path
// Check if this is process.env.SOMETHING
if (
node.object.type === 'MemberExpression' &&
node.object.object.type === 'Identifier' &&
node.object.object.name === 'process' &&
node.object.property.type === 'Identifier' &&
node.object.property.name === 'env'
) {
// Skip process.env.NODE_ENV - leave it as is
if (node.property.type === 'Identifier' && node.property.name === 'NODE_ENV') {
return
}
// Replace process.env with import.meta.env
node.object = t.memberExpression(
t.metaProperty(t.identifier('import'), t.identifier('meta')),
t.identifier('env')
)
}
}
return {
name: 'babel-plugin-fully-specified',
visitor: {
ImportDeclaration: importDeclarationVisitor,
ExportNamedDeclaration: exportDeclarationVisitor,
ExportAllDeclaration: exportDeclarationVisitor,
Import: importVisitor,
MemberExpression: memberExpressionVisitor,
},
}
}
function normalizeOptions(
rawOptions: Partial<FullySpecifiedOptions>
): FullySpecifiedOptions {
const options = { ...DEFAULT_OPTIONS, ...rawOptions }
if (
rawOptions.esExtensionDefault &&
!rawOptions.tryExtensions &&
rawOptions.esExtensionDefault !== DEFAULT_OPTIONS.esExtensionDefault
) {
options.tryExtensions = [
rawOptions.esExtensionDefault,
...DEFAULT_OPTIONS.tryExtensions.filter(
(extension) => extension !== rawOptions.esExtensionDefault
),
]
}
return options
}
/**
* Returns a fully specified [module specifier](https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#prod-ModuleSpecifier) (or `null` if it can't be determined or shouldn't be transformed).
*/
function getFullySpecifiedModuleSpecifier(
/**
* The original module specifier in the code.
*
* For example, `'./foo'` for `import { foo } from './foo'`.
*/
originalModuleSpecifier: string,
{
filePath,
options,
}: {
/**
* The absolute file path of the file being transformed.
*
* Normally this can be obtained from the 2nd parameter in a visitor function (often named as `state`): `state.file.opts.filename`.
*/
filePath: string
/** Options that users pass to babel-plugin-fully-specified. */
options: FullySpecifiedOptions
}
): string | null {
const fileExt = extname(filePath)
const fileDir = dirname(filePath)
const isDirectory = isLocalDirectory(resolve(fileDir, originalModuleSpecifier))
const currentModuleExtension = extname(originalModuleSpecifier)
const { tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options
const targetModule = evaluateTargetModule({
moduleSpecifier: originalModuleSpecifier,
filenameDirectory: fileDir,
filenameExtension: fileExt,
currentModuleExtension,
isDirectory,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
})
if (targetModule === false) {
return null
}
return targetModule
}
function isLocalDirectory(absoluteDirectory: string) {
return existsSync(absoluteDirectory) && lstatSync(absoluteDirectory).isDirectory()
}
function evaluateTargetModule({
moduleSpecifier,
currentModuleExtension,
isDirectory,
filenameDirectory,
filenameExtension,
tryExtensions,
esExtensions,
esExtensionDefault,
ensureFileExists,
}: any): string | false {
const targetFile = resolve(filenameDirectory, moduleSpecifier)
if (ensureFileExists) {
for (const extension of tryExtensions) {
if (existsSync(targetFile + extension)) {
return moduleSpecifier + esExtensionDefault
}
}
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension)) {
return false
}
if (isDirectory) {
const indexModuleSpecifier = `${moduleSpecifier.replace(/\/$/, '')}/index`
const indexTargetFile = resolve(filenameDirectory, indexModuleSpecifier)
for (const extension of tryExtensions) {
if (existsSync(indexTargetFile + extension)) {
return indexModuleSpecifier + esExtensionDefault
}
}
}
} else if (esExtensions.includes(filenameExtension)) {
return moduleSpecifier + esExtensionDefault
} else {
return moduleSpecifier + esExtensionDefault
}
return false
}
@@ -1,13 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"isolatedDeclarations": true
},
"references": [],
"exclude": [
"types",
"permanent",
"__tests__"
]
}
+6 -7
View File
@@ -20,19 +20,18 @@
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"react-native": "./dist/esm/index.native.js",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/esm/index.mjs"
"react-native": "./dist/esm/index.js",
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js",
"default": "./dist/esm/index.js"
}
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "hanzogui-build --skip-types",
"build": "hanzogui-build --skip-native",
"watch": "bun run build --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build",
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+22 -74
View File
@@ -1,83 +1,31 @@
## @hanzogui/build
A small, opinionated build script for libraries that target both React Native and React web.
Path-specific extensions are the only way to support both ESM and CJS properly in modern Node and across all bundlers. Some bundlers used to be flexible and configure this for you, but we found this was the only way to achieve "no config" packages that target native and web. This is even more true as React Native is now supporting package.json exports with an experimental flag.
We wanted to build packages so we didn't have to deal with all this fuss. `@hanzogui/build` will build every input file out to both `.native` and `.web` output files to make this work. It then adds path-specific imports to the files that are reachable via package.json exports, but leaves plain `.js` files for older bundlers that don't support it (Metro without the experimental exports flag). It also does a few small re-writes to ensure everyting works without needing bundler configuration. This means it supports basically every possible setup - Metro in either mode, Vite, and older and newer Node versions.
Some details on how it works:
- uses tsc to output declaration files to `./types`
- esbuild to output `dist/esm` and `dist/cjs` for ESModules and CommonJS
- outputs `.js` and `.mjs` files in `dist/esm`
- in `.mjs`, adds path-specific imports to non-specific imports
- outputs both `.js` and `.cjs` files in `dist/cjs`:
- in `.cjs`, adds path-specific imports to non-specific imports
- strips bare imports that esbuild leaves behind, respecting the `sideEffects` field in package.json
- outputs `.native.js` and regular `.js` files for all output files, so React Native always loads separate files from web. In the `native` specific files,
- swc is sued to transform to es5
- `process.env.GUI_TARGET` is defined `native` (otherwise `web`)
- on non-native files:
- on web, imports of `react-native` are transformed to `react-native-web`
It assumes your package.json looks something like this:
One package, built by the TypeScript compiler alone.
```
{
"source": "src/index.tsx",
"types": "./types/index.d.ts",
"main": "dist/cjs",
"module": "dist/esm",
"type": "module",
"scripts": {
"build": "hanzogui-build",
"watch": "hanzogui-build --watch",
"clean": "hanzogui-build clean"
},
"exports": {
"./package.json": "./package.json",
".": {
"react-native": {
"import": "./dist/esm/index.native.js",
"require": "./dist/cjs/index.native.js"
},
"types": "./types/index.d.ts",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/cjs/index.native.js"
}
},
"devDependencies": {
"@hanzogui/build": "latest"
},
"hanzogui": {
"build": {
"skipEnvToMeta": true,
"bundle.native": "./src/index.ts",
"bundle.native.test": "./src/index.ts"
}
},
}
hanzogui-build # ESM + declarations, CommonJS, native
hanzogui-build --skip-native # a package with nothing platform-specific
hanzogui-build --watch # the ESM emit, continuously
```
### Install
Three project files in the package describe the three emits, and the compiler
reads exactly one answer per target:
`npx @hanzogui/build` or install and use the CLI:
| project | writes |
| ---------------------- | --------------------------------------------- |
| `tsconfig.esm.json` | `dist/esm/*.js` and `types/*.d.ts` |
| `tsconfig.cjs.json` | `dist/cjs/*.js`, marked commonjs by its own `package.json` |
| `tsconfig.native.json` | `dist/native/*.js`, where a `.native` file takes its sibling's name |
### Use
Source names every relative import with its extension and the compiler rewrites
it on emit, so what lands in `dist` is loadable by Node as written. Nothing else
runs over the code.
- `hanzogui-build` - builds `src` folder to `dist` and `types` folders
- normal builds clear `dist` and `types` first, so stale transformed files don't hang around
- intermediary `.js` files are removed after `.mjs` / `.cjs` postprocessing, so published output stays lean
- `hanzogui build .` second argument sets baseUrl to tsc
- `--bundle-modules` - inline node_modules
- `--declaration-root` - sets tsc flag `--declarationDir ./`
- `--skip-mjs` - don't output mjs files
- `--skip-native` - don't output native files
- `--skip-sourcemaps` - don't output js or declaration sourcemaps
- `--swap-exports` - swaps `exports.types` from `./src/*.ts` to `./types/*.d.ts` for publishing. if a command is given after `--`, runs it then swaps back. exit code is preserved.
- `hanzogui-build --swap-exports` - build and swap, stays swapped (for manual publish)
- `hanzogui-build --swap-exports -- npm publish` - build, swap, publish, swap back
- `hanzogui-build --watch` - watches for changes and does the above
- `hanzogui-build clean` - cleans dist, types, node_modules folders
A package is CommonJS only where its manifest states a `require` entry; one that
uses `import.meta` or a top-level `await` has no CommonJS form and states none.
The native pass runs only where a `tsconfig.native.json` exists, which is where
`.native.*` sources exist; on that platform the sibling's callers resolve to the
native file through the same relative import.
The `exports` map points at what the emits produce: `dist/esm/x.js`,
`dist/cjs/x.js`, `dist/native/x.js`, `types/x.d.ts`.
File diff suppressed because it is too large Load Diff
+1 -21
View File
@@ -3,8 +3,7 @@
"version": "8.3.1",
"gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
"bin": {
"hanzogui-build": "hanzogui-build.js",
"teesx": "teesx.sh"
"hanzogui-build": "tsgo-build.mjs"
},
"publishConfig": {
"access": "public"
@@ -14,22 +13,6 @@
"test:web": "bun run test"
},
"dependencies": {
"@babel/core": "^8.0.1",
"@babel/preset-typescript": "^8.0.1",
"@swc/core": "^1.16.1",
"@hanzogui/babel-plugin-fully-specified": "workspace:*",
"@types/fs-extra": "^11.0.4",
"baseline-browser-mapping": "^2.11.20",
"chokidar": "^5.0.0",
"esbuild": "^0.28.2",
"esbuild-register": "^3.6.0",
"execa": "^10.0.1",
"fast-glob": "^3.3.3",
"fs-extra": "^11.4.0",
"lodash.debounce": "^4.0.8",
"oxc-transform": "^0.147.0",
"picomatch": "^4.0.7",
"rolldown": "^1.2.6",
"typescript": "7.0.2"
},
"peerDependencies": {
@@ -39,8 +22,5 @@
"babel-plugin-react-compiler": {
"optional": true
}
},
"devDependencies": {
"vitest": "^4.1.11"
}
}
-3
View File
@@ -1,3 +0,0 @@
#!/usr/bin/env bash
node --loader esbuild-register/loader -r esbuild-register "$@"
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env node
/**
* hanzogui-build — one package, built by the TypeScript compiler alone.
*
* Three emits from one source tree, each its own project file so the compiler
* reads exactly one answer per target:
*
* tsconfig.esm.json dist/esm/*.js + types/*.d.ts
* tsconfig.cjs.json dist/cjs/*.js (marked commonjs by its own package.json)
* tsconfig.native.json dist/native/*.js, where a `.native` sibling replaces its
* web file, so the same relative import reaches the
* native implementation without a bundler choosing.
*
* Source names its imports with their extension and the compiler rewrites them
* on emit, so the output is loadable by Node as written. Nothing else runs over
* the code: no Babel, no esbuild, no plugin.
*
* --skip-native packages with nothing platform-specific
* --skip-types packages whose declarations are hand-written or unneeded
* --watch the ESM emit, continuously
*/
import { spawnSync } from 'node:child_process'
import { createRequire } from 'node:module'
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
const need = createRequire(import.meta.url)
const tsc = need(join(dirname(need.resolve('typescript/package.json')), 'lib/getExePath.js')).default()
const args = new Set(process.argv.slice(2))
const cwd = process.cwd()
const manifest = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'))
const emit = (project, extra = []) => {
const run = spawnSync(tsc, ['-p', project, ...extra], { cwd, stdio: 'inherit' })
if (run.status !== 0) process.exit(run.status ?? 1)
}
if (args.has('--watch')) {
emit('tsconfig.esm.json', ['--watch'])
} else {
for (const dir of ['dist', 'types']) rmSync(join(cwd, dir), { recursive: true, force: true })
emit('tsconfig.esm.json')
// A package is CommonJS only where its manifest says a `require` reaches it.
// One that uses import.meta or a top-level await is ESM by nature and states
// no such entry, so there is nothing to emit for CommonJS.
//
// A package that asks for isolatedDeclarations cannot emit without
// declarations, so the CJS and native passes write theirs beside their
// output and those are dropped: the ESM pass already published the one copy.
if (/"require"|dist\/cjs/.test(JSON.stringify(manifest.exports ?? {}) + (manifest.main ?? ''))) {
emit('tsconfig.cjs.json')
rmSync(join(cwd, 'dist/cjs/.types'), { recursive: true, force: true })
mkdirSync(join(cwd, 'dist/cjs'), { recursive: true })
writeFileSync(join(cwd, 'dist/cjs/package.json'), '{ "type": "commonjs" }\n')
}
if (!args.has('--skip-native') && existsSync(join(cwd, 'tsconfig.native.json'))) {
emit('tsconfig.native.json')
rmSync(join(cwd, 'dist/native/.types'), { recursive: true, force: true })
// A `.native` file was written to answer for its sibling on that platform;
// here it takes the sibling's name, so the import the sibling's callers
// already make resolves to it.
const walk = (dir) => {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const p = join(dir, entry.name)
if (entry.isDirectory()) walk(p)
else if (/\.native\.js(\.map)?$/.test(entry.name)) renameSync(p, p.replace('.native.js', '.js'))
}
}
walk(join(cwd, 'dist/native'))
}
}
+9 -9
View File
@@ -12,19 +12,19 @@
"source": "src/index.ts",
"type": "module",
"sideEffects": false,
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"react-native": "./dist/esm/index.native.js",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/esm/index.mjs"
"react-native": "./dist/esm/index.js",
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/esm/index.js"
}
},
"files": [
@@ -34,7 +34,7 @@
"README.md"
],
"scripts": {
"build": "hanzogui-build",
"build": "hanzogui-build --skip-native",
"watch": "hanzogui-build --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build"
+7 -7
View File
@@ -1,12 +1,12 @@
import type { ReactNode } from 'react'
import { SizableText, Spinner, XStack, YStack } from '@hanzo/gui'
import type { Booking } from './client'
import { BookingForm } from './BookingForm'
import { Confirmation } from './Confirmation'
import { EventHeader } from './EventHeader'
import { MonthCalendar } from './MonthCalendar'
import { TimeSlots } from './TimeSlots'
import { useBooker } from './useBooker'
import type { Booking } from './client.ts'
import { BookingForm } from './BookingForm.tsx'
import { Confirmation } from './Confirmation.tsx'
import { EventHeader } from './EventHeader.tsx'
import { MonthCalendar } from './MonthCalendar.tsx'
import { TimeSlots } from './TimeSlots.tsx'
import { useBooker } from './useBooker.ts'
export interface BookerProps {
/** Host username (the calendar owner), e.g. "hanzo". */
+2 -2
View File
@@ -1,7 +1,7 @@
import { useState, type ReactNode } from 'react'
import { Button, Input, SizableText, TextArea, XStack, YStack } from '@hanzo/gui'
import type { BookingResponses } from './client'
import { formatBookingWhen } from './time'
import type { BookingResponses } from './client.ts'
import { formatBookingWhen } from './time.ts'
export interface BookingFormProps {
slotIso: string
+7 -7
View File
@@ -1,11 +1,11 @@
import { SizableText, Spinner, XStack, YStack } from '@hanzo/gui'
import type { Booking } from './client'
import { BookingForm } from './BookingForm'
import { Confirmation } from './Confirmation'
import { EventHeader } from './EventHeader'
import { TimeSlots } from './TimeSlots'
import { formatMonthLabel } from './time'
import { useBooker } from './useBooker'
import type { Booking } from './client.ts'
import { BookingForm } from './BookingForm.tsx'
import { Confirmation } from './Confirmation.tsx'
import { EventHeader } from './EventHeader.tsx'
import { TimeSlots } from './TimeSlots.tsx'
import { formatMonthLabel } from './time.ts'
import { useBooker } from './useBooker.ts'
export interface CalendarEmbedProps {
host: string
+4 -4
View File
@@ -7,10 +7,10 @@ import {
XStack,
YStack,
} from '@hanzo/gui'
import { DEFAULT_API_URL, type Booking } from './client'
import { useBooking } from './hooks'
import { visitorTimeZone } from './time'
import { formatBookingWhen } from './time'
import { DEFAULT_API_URL, type Booking } from './client.ts'
import { useBooking } from './hooks.ts'
import { visitorTimeZone } from './time.ts'
import { formatBookingWhen } from './time.ts'
export interface ConfirmationProps {
/** Provide a booking directly, or a uid to fetch one. */
+1 -1
View File
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react'
import { Paragraph, SizableText, XStack, YStack } from '@hanzo/gui'
import type { EventType } from './client'
import type { EventType } from './client.ts'
export interface EventHeaderProps {
event: EventType
+1 -1
View File
@@ -5,7 +5,7 @@ import {
monthMatrix,
weekdayLabels,
type MonthCell,
} from './time'
} from './time.ts'
export interface MonthCalendarProps {
viewDate: Date
+2 -2
View File
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react'
import { Button, ScrollView, SizableText, XStack, YStack } from '@hanzo/gui'
import type { Slot } from './client'
import { dateFromKey, formatDayLong, formatSlotTime } from './time'
import type { Slot } from './client.ts'
import { dateFromKey, formatDayLong, formatSlotTime } from './time.ts'
export interface TimeSlotsProps {
dayKey: string | null
+1 -1
View File
@@ -11,7 +11,7 @@ import {
type BookingResponses,
type EventType,
type SlotsByDay,
} from './client'
} from './client.ts'
export interface AsyncState<T> {
data: T | null
+11 -11
View File
@@ -1,15 +1,15 @@
// @hanzo/calendar — universal (web + native) booking UI on the Hanzo Calendar
// backend, built with hanzogui primitives.
export { Booker, type BookerProps } from './Booker'
export { CalendarEmbed, type CalendarEmbedProps } from './CalendarEmbed'
export { Confirmation, type ConfirmationProps } from './Confirmation'
export { Booker, type BookerProps } from './Booker.tsx'
export { CalendarEmbed, type CalendarEmbedProps } from './CalendarEmbed.tsx'
export { Confirmation, type ConfirmationProps } from './Confirmation.tsx'
// Composable sub-views (use these to build a custom flow).
export { EventHeader, type EventHeaderProps } from './EventHeader'
export { MonthCalendar, type MonthCalendarProps } from './MonthCalendar'
export { TimeSlots, type TimeSlotsProps } from './TimeSlots'
export { BookingForm, type BookingFormProps } from './BookingForm'
export { EventHeader, type EventHeaderProps } from './EventHeader.tsx'
export { MonthCalendar, type MonthCalendarProps } from './MonthCalendar.tsx'
export { TimeSlots, type TimeSlotsProps } from './TimeSlots.tsx'
export { BookingForm, type BookingFormProps } from './BookingForm.tsx'
// Orchestration hook + data hooks.
export {
@@ -17,7 +17,7 @@ export {
type UseBookerOptions,
type BookerModel,
type BookerPhase,
} from './useBooker'
} from './useBooker.ts'
export {
useEventType,
useAvailableSlots,
@@ -28,7 +28,7 @@ export {
type SlotsState,
type CreateBookingState,
type SubmitResult,
} from './hooks'
} from './hooks.ts'
// Data plane.
export {
@@ -50,7 +50,7 @@ export {
type BookingResponses,
type CreateBookingInput,
type SlotsInput,
} from './client'
} from './client.ts'
// Time plane (Intl/Date helpers).
export {
@@ -69,4 +69,4 @@ export {
sameMonth,
isBeforeToday,
type MonthCell,
} from './time'
} from './time.ts'
+4 -4
View File
@@ -1,16 +1,16 @@
// Orchestration hook — the one booking state machine both shells consume.
import { useEffect, useMemo, useState } from 'react'
import { DEFAULT_API_URL, type Booking, type BookingResponses, type Slot } from './client'
import { DEFAULT_API_URL, type Booking, type BookingResponses, type Slot } from './client.ts'
import {
useAvailableSlots,
useCreateBooking,
useEventType,
type AsyncState,
type SlotsState,
} from './hooks'
import type { EventType } from './client'
import { addMonths, monthRange, startOfMonth, visitorTimeZone } from './time'
} from './hooks.ts'
import type { EventType } from './client.ts'
import { addMonths, monthRange, startOfMonth, visitorTimeZone } from './time.ts'
export type BookerPhase = 'pick' | 'form' | 'done'
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+9 -9
View File
@@ -7,26 +7,26 @@
"types"
],
"type": "module",
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"react-native": "./dist/esm/index.native.js",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/esm/index.mjs"
"react-native": "./dist/esm/index.js",
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/esm/index.js"
}
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "hanzogui-build",
"build": "hanzogui-build --skip-native",
"watch": "hanzogui-build --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build"
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+3 -3
View File
@@ -7,14 +7,14 @@
"types",
"dist"
],
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "hanzogui-build",
"build": "hanzogui-build --skip-native",
"watch": "hanzogui-build --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build"
+4 -4
View File
@@ -1,11 +1,11 @@
import { toHtml } from 'hast-util-to-html'
import rangeParser from 'parse-numeric-range'
import { refractor } from 'refractor'
import css from 'refractor/lang/css'
import tsx from 'refractor/lang/tsx'
import css from 'refractor/css'
import tsx from 'refractor/tsx'
import { highlightLine } from './highlightLine'
import { highlightWord } from './highlightWord'
import { highlightLine } from './highlightLine.ts'
import { highlightWord } from './highlightWord.ts'
refractor.register(tsx)
refractor.register(css)
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+1 -1
View File
@@ -10,7 +10,7 @@
"dist"
],
"main": "dist/cjs/index.js",
"module": "dist/esm",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"publishConfig": {
"access": "public"
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+6 -7
View File
@@ -8,18 +8,17 @@
"dist"
],
"type": "module",
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/cjs/index.cjs"
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js",
"default": "./dist/cjs/index.js"
}
},
"publishConfig": {
+1 -1
View File
@@ -4,7 +4,7 @@ import { existsSync } from 'node:fs'
import { dirname, join } from 'node:path'
import type { Compiler, RuleSetRule } from 'webpack'
import webpack from 'webpack'
import { requireResolve } from './requireResolve'
import { requireResolve } from './requireResolve.ts'
export type PluginOptions = GuiOptions & {
isServer?: boolean
+4 -4
View File
@@ -1,7 +1,7 @@
import './polyfills'
import './polyfills.ts'
import { loader } from './loader'
import { loader } from './loader.ts'
export default loader
export * from './GuiPlugin'
export * from './shouldExclude'
export * from './GuiPlugin.ts'
export * from './shouldExclude.ts'
+1 -1
View File
@@ -1,7 +1,7 @@
import * as StaticWorker from '@hanzogui/static-worker'
import type { GuiOptions } from '@hanzogui/types'
import type { LoaderContext } from 'webpack'
import { requireResolve } from './requireResolve'
import { requireResolve } from './requireResolve.ts'
const { getPragmaOptions, isExtractable } = StaticWorker
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+26
View File
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+1 -1
View File
@@ -9,7 +9,7 @@
"dist"
],
"main": "dist/cjs/index.js",
"module": "dist/esm",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"publishConfig": {
"access": "public"
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+7 -7
View File
@@ -10,19 +10,19 @@
"dist"
],
"type": "module",
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"exports": {
"./package.json": "./package.json",
"./reset.css": "./reset.css",
".": {
"types": "./types/index.d.ts",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs",
"default": "./dist/cjs/index.cjs"
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/cjs/index.js"
}
},
"publishConfig": {
+1 -1
View File
@@ -1 +1 @@
export * from './withGui'
export * from './withGui.ts'
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+1 -1
View File
@@ -25,7 +25,7 @@
"access": "public"
},
"scripts": {
"build": "hanzogui-build --skip-native --bundle",
"build": "bun build src/index.ts --outfile dist/index.cjs --format cjs --target node --packages external",
"watch": "bun run build --watch",
"clean": "hanzogui-build clean",
"clean:build": "hanzogui-build clean:build"
+5 -6
View File
@@ -9,17 +9,16 @@
"dist"
],
"type": "module",
"main": "dist/cjs",
"module": "dist/esm",
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
"types": "./types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"browser": "./dist/esm/index.mjs",
"module": "./dist/esm/index.mjs",
"import": "./dist/esm/index.mjs",
"require": "./dist/cjs/index.cjs"
"browser": "./dist/esm/index.js",
"module": "./dist/esm/index.js",
"import": "./dist/esm/index.js"
}
},
"publishConfig": {
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "dist/cjs",
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/cjs/.types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": false,
"incremental": false,
"rootDir": "src",
"rewriteRelativeImportExtensions": true,
"sourceMap": true,
"inlineSourceMap": false,
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "dist/esm",
"declaration": true,
"declarationMap": true,
"declarationDir": "types"
},
"include": [
"src"
],
"exclude": [
"src/**/*.test.*",
"src/**/__tests__/**",
"src/**/*.stories.*"
]
}
+3 -3
View File
@@ -16,11 +16,11 @@
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"default": "./dist/index.cjs"
"default": "./dist/cjs/index.js"
},
"./worker": {
"types": "./types/worker.d.ts",
"default": "./dist/worker.cjs"
"default": "./dist/cjs/worker.js"
},
"./extractablePath": {
"types": "./types/extractor/extractablePath.d.ts",
@@ -28,7 +28,7 @@
},
"./checkDeps": {
"types": "./types/checkDeps.d.ts",
"default": "./dist/checkDeps.cjs"
"default": "./dist/cjs/checkDeps.js"
},
"./loadGui": {
"types": "./types/extractor/loadGui.d.ts",
+1 -1
View File
@@ -1,6 +1,6 @@
import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs'
import { join, relative } from 'node:path'
import { CDVC } from './check-dep-versions'
import { CDVC } from './check-dep-versions.ts'
export enum DEPENDENCY_TYPE {
dependencies = 'dependencies',
+17 -17
View File
@@ -1,17 +1,17 @@
export * from './checkDeps'
export * from './types'
export { createExtractor } from './extractor/createExtractor'
export { literalToAst } from './extractor/literalToAst'
export * from './constants'
export * from './extractor/extractablePath'
export * from './extractor/extractToClassNames'
export * from './extractor/concatClassName'
export * from './extractor/extractToNative'
export * from './extractor/extractHelpers'
export * from './extractor/loadGui'
export * from './extractor/watchGuiConfig'
export * from './extractor/createLogger'
export * from './registerRequire'
export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat'
export { esbundleGuiConfig } from './extractor/bundle'
export * from './getPragmaOptions'
export * from './checkDeps.ts'
export * from './types.ts'
export { createExtractor } from './extractor/createExtractor.ts'
export { literalToAst } from './extractor/literalToAst.ts'
export * from './constants.ts'
export * from './extractor/extractablePath.ts'
export * from './extractor/extractToClassNames.ts'
export * from './extractor/concatClassName.ts'
export * from './extractor/extractToNative.ts'
export * from './extractor/extractHelpers.ts'
export * from './extractor/loadGui.ts'
export * from './extractor/watchGuiConfig.ts'
export * from './extractor/createLogger.ts'
export * from './registerRequire.ts'
export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat.ts'
export { esbundleGuiConfig } from './extractor/bundle.ts'
export * from './getPragmaOptions.ts'
@@ -1,6 +1,6 @@
import * as t from '@babel/types'
import type { ClassNameObject } from '../types'
import type { ClassNameObject } from '../types.ts'
type Builder = (
objects: ClassNameObject[],
+6 -6
View File
@@ -1,12 +1,12 @@
import { readFileSync } from 'node:fs'
import esbuild from 'esbuild'
import * as FS from 'fs-extra'
import type { GuiPlatform } from '../types'
import { detectModuleFormat } from './detectModuleFormat'
import { esbuildAliasPlugin } from './esbuildAliasPlugin'
import { hasTopLevelAwait } from './hasTopLevelAwait'
import { resolveWebOrNativeSpecificEntry } from './loadGui'
import { TsconfigPathsPlugin } from './esbuildTsconfigPaths'
import type { GuiPlatform } from '../types.ts'
import { detectModuleFormat } from './detectModuleFormat.ts'
import { esbuildAliasPlugin } from './esbuildAliasPlugin.ts'
import { hasTopLevelAwait } from './hasTopLevelAwait.ts'
import { resolveWebOrNativeSpecificEntry } from './loadGui.ts'
import { TsconfigPathsPlugin } from './esbuildTsconfigPaths.ts'
export const esbuildLoaderConfig = {
'.js': 'jsx',
@@ -11,14 +11,14 @@ import { type StaticConfig, type GuiInternalConfig } from '@hanzogui/web'
import esbuild from 'esbuild'
import * as FS from 'fs-extra'
import { readFile } from 'node:fs/promises'
import { registerRequire, setRequireResult } from '../registerRequire'
import type { GuiOptions } from '../types'
import { babelParse } from './babelParse'
import { esbuildLoaderConfig, esbundleGuiConfig } from './bundle'
import { getGuiConfigPathFromOptionsConfig } from './getGuiConfigPathFromOptionsConfig'
import { hasTopLevelAwait } from './hasTopLevelAwait'
import { requireGuiCore } from '../helpers/requireGuiCore'
import { detectModuleFormat } from './detectModuleFormat'
import { registerRequire, setRequireResult } from '../registerRequire.ts'
import type { GuiOptions } from '../types.ts'
import { babelParse } from './babelParse.ts'
import { esbuildLoaderConfig, esbundleGuiConfig } from './bundle.ts'
import { getGuiConfigPathFromOptionsConfig } from './getGuiConfigPathFromOptionsConfig.ts'
import { hasTopLevelAwait } from './hasTopLevelAwait.ts'
import { requireGuiCore } from '../helpers/requireGuiCore.ts'
import { detectModuleFormat } from './detectModuleFormat.ts'
// track temp files for cleanup on exit
const activeTempFiles = new Set<string>()
@@ -5,9 +5,9 @@ import type { NodePath } from '@babel/traverse'
import * as t from '@babel/types'
import esbuild from 'esbuild'
import { FAILED_EVAL } from '../constants'
import type { GuiOptionsWithFileInfo } from '../types'
import { evaluateAstNode } from './evaluateAstNode'
import { FAILED_EVAL } from '../constants.ts'
import type { GuiOptionsWithFileInfo } from '../types.ts'
import { evaluateAstNode } from './evaluateAstNode.ts'
export function createEvaluator({
props,
@@ -16,8 +16,8 @@ import { readFileSync } from 'node:fs'
import { basename, dirname, resolve, relative } from 'node:path'
import type { ViewStyle } from 'react-native'
import { FAILED_EVAL } from '../constants'
import { requireGuiCore } from '../helpers/requireGuiCore'
import { FAILED_EVAL } from '../constants.ts'
import { requireGuiCore } from '../helpers/requireGuiCore.ts'
import type {
ExtractedAttr,
ExtractedAttrStyle,
@@ -26,11 +26,11 @@ import type {
GuiOptions,
GuiOptionsWithFileInfo,
Ternary,
} from '../types'
import type { LoadedComponents, GuiProjectInfo } from './bundleConfig'
import { createEvaluator, createSafeEvaluator } from './createEvaluator'
import { installedPackageOf } from './extractablePath'
import { evaluateAstNode } from './evaluateAstNode'
} from '../types.ts'
import type { LoadedComponents, GuiProjectInfo } from './bundleConfig.ts'
import { createEvaluator, createSafeEvaluator } from './createEvaluator.ts'
import { installedPackageOf } from './extractablePath.ts'
import { evaluateAstNode } from './evaluateAstNode.ts'
import {
attrStr,
findComponentName,
@@ -40,18 +40,18 @@ import {
isPresent,
isValidImport,
objToStr,
} from './extractHelpers'
import { findTopmostFunction } from './findTopmostFunction'
import { cleanupBeforeExit, getStaticBindingsForScope } from './getStaticBindingsForScope'
import { literalToAst } from './literalToAst'
import { loadGui, loadGuiSync } from './loadGui'
import { logLines } from './logLines'
import { normalizeTernaries } from './normalizeTernaries'
import { setPropsToFontFamily } from './propsToFontFamilyCache'
import { timer } from './timer'
import { validHTMLAttributes } from './validHTMLAttributes'
import { BailOptimizationError } from './errors'
import { probe, resolveAlias } from './esbuildTsconfigPaths'
} from './extractHelpers.ts'
import { findTopmostFunction } from './findTopmostFunction.ts'
import { cleanupBeforeExit, getStaticBindingsForScope } from './getStaticBindingsForScope.ts'
import { literalToAst } from './literalToAst.ts'
import { loadGui, loadGuiSync } from './loadGui.ts'
import { logLines } from './logLines.ts'
import { normalizeTernaries } from './normalizeTernaries.ts'
import { setPropsToFontFamily } from './propsToFontFamilyCache.ts'
import { timer } from './timer.ts'
import { validHTMLAttributes } from './validHTMLAttributes.ts'
import { BailOptimizationError } from './errors.ts'
import { probe, resolveAlias } from './esbuildTsconfigPaths.ts'
const UNTOUCHED_PROPS = {
key: true,

Some files were not shown because too many files have changed in this diff Show More