/** * Build-entry preparation for `tekir build`. * * `tekir build` parses the user entry with `oxc-parser`, locates the * top-level `await tekir({...})` call, and emits a temporary source * that contains only: * * 1. Every bare `import 'X'` (no specifiers) — kept conservatively * because side-effect-only imports register polyfills, type * augmentation, etc., that the `tekir()` argument may rely on. * 2. The transitive closure of imports + top-level declarations * (`const`, `let`, `function`, `class`) reachable from the * `tekir()` call's argument expression. * 3. The `tekir()` call itself, verbatim. * * Everything else — `app.router.registerDir(...)`, `app.start(...)`, * `app.onShutdown(...)` callbacks, custom services with eager init, * scheduler ticks, fs watchers — is dropped. Inside `tekir()`, the * build dispatch fires the `onBuild` hooks, runs `Bun.build` for the * backend bundle, and exits; the temporary file is never re-evaluated * at runtime — the original entry is what gets bundled and shipped. * * Returning `null` is the safe-fallback signal: any AST shape we do * not recognise (no `tekir()` call, dynamic argument, multiple calls, * parse error) keeps the cli on a full-entry import so user code that * doesn't fit this shape still builds. */ interface BuildEntryResult { /** Generated source ready to write to a temp file and import. */ source: string; /** Names of top-level statements that were dropped, for diagnostics. */ dropped: string[]; /** Names of imports that were dropped, for diagnostics. */ droppedImports: string[]; } /** * Walk an AST node recursively and collect every `Identifier` it * references that is not an own binding of a sub-scope. We intentionally * stay coarse here: the goal is "names that resolve to module scope", * and over-approximation (keeping a binding we don't actually need) is * fine — under-approximation (dropping a needed binding) breaks * builds. A few cases are excluded to keep the result useful: * * - Property keys on member access (`a.b` → `b` is not a free var). * - Object literal property keys (`{ foo: bar }` → `foo` is not). * - The bound name of a `function` or arrow parameter, which is * scoped to the function body and shadows module bindings. * - The bound name in a `VariableDeclarator`'s left-hand-side * (`const x = y` → `y` is free, `x` is the binding). */ declare function collectFreeIdentifiers(node: any, out: Set): void; /** Pull every binding name introduced by a top-level statement. */ declare function bindingNamesOf(stmt: any): string[]; /** * Spot the top-level `await tekir({...})` call. Accepts both shapes that * appear in real entries: * * const app = await tekir({...}) * await tekir({...}) // value discarded * export const app = await tekir({...}) * * Returns the wrapping top-level statement node (so the build-entry emitter * can keep it verbatim) plus the call expression for argument analysis. */ declare function findTekirCallStatement(body: any[]): { stmt: any; call: any; } | null; /** * Build the build-entry source. Returns `null` when the entry shape is not * supported (no top-level `await tekir()`, multiple calls, parse error, * etc.) — callers fall back to the historical full-entry execution. */ export declare function generateBuildEntry(entryPath: string): Promise; /** * Resolve `entry` against `cwd` for callers that pass relative paths * (the cli's user-facing flow). Centralised so cli and other * consumers share the same resolution logic. */ export declare function resolveEntryPath(entry: string, cwd: string): string; export declare const __internal: { findTekirCallStatement: typeof findTekirCallStatement; collectFreeIdentifiers: typeof collectFreeIdentifiers; bindingNamesOf: typeof bindingNamesOf; }; export {};