streetui 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +1 -1
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/{compile-CJJQYi71.d.cts → compile-DqsMQVJk.d.cts} +120 -4
- package/dist/{compile-CJJQYi71.d.ts → compile-DqsMQVJk.d.ts} +120 -4
- package/dist/create-bin.cjs +1 -1
- package/dist/create-bin.cjs.map +1 -1
- package/dist/create-bin.js +1 -1
- package/dist/create-bin.js.map +1 -1
- package/dist/{hydration-diagnostics-BQeehq3i.d.cts → hydration-diagnostics-4pwt6v7b.d.cts} +1 -1
- package/dist/{hydration-diagnostics-DNAJumYF.d.ts → hydration-diagnostics-B2FmY05M.d.ts} +1 -1
- package/dist/index.cjs +537 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +261 -18
- package/dist/index.d.ts +261 -18
- package/dist/index.js +529 -40
- package/dist/index.js.map +1 -1
- package/dist/{server-DNlg7ou2.d.ts → server-BYnmb_hR.d.ts} +1 -1
- package/dist/{server-CnLEnlYU.d.cts → server-DnwqBTfE.d.cts} +1 -1
- package/dist/server.cjs +266 -30
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +266 -30
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +387 -36
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +42 -4
- package/dist/testing.d.ts +42 -4
- package/dist/testing.js +379 -35
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../cli/src/args.ts","../../cli/src/logger.ts","../../cli/src/diagnostics.ts","../../cli/src/project.ts","../../cli/src/config.ts","../../cli/src/build.ts","../../cli/src/env.ts","../../cli/src/dev.ts","../../cli/src/serve.ts","../../cli/src/start.ts","../../cli/src/create.ts","../../cli/src/templates.ts","../../cli/src/index.ts","../src/bin.ts"],"sourcesContent":["/**\n * A tiny, dependency-free argument parser tailored to the StreetUI CLI.\n *\n * It intentionally supports only what the CLI actually uses — a leading command\n * word, positional arguments, boolean flags, and a handful of value options\n * (`--port`, `--host`, `--template`, `--dir`). Unknown flags are collected so a\n * command can reject them with a useful message rather than silently ignoring\n * them (Phase 14: no options that are ignored).\n */\n\nexport interface ParsedArgs {\n /** The command word, e.g. `create` / `dev` / `build` / `start`. */\n readonly command: string | undefined;\n /** Positional arguments after the command (e.g. the project name). */\n readonly positionals: readonly string[];\n /** `--help` / `-h` anywhere. */\n readonly help: boolean;\n /** `--version` / `-v` anywhere. */\n readonly version: boolean;\n /** `--port <n>` (validated as an integer, else `undefined`). */\n readonly port: number | undefined;\n /** `--host <h>`. */\n readonly host: string | undefined;\n /** `--template <name>` (project template for `create`). */\n readonly template: string | undefined;\n /** `--dir <path>` project directory override. */\n readonly dir: string | undefined;\n /** Any flags we do not recognise, reported verbatim (without leading `--`). */\n readonly unknown: readonly string[];\n}\n\nconst VALUE_FLAGS = new Set(['port', 'host', 'template', 'dir']);\nconst BOOLEAN_FLAGS = new Set(['help', 'version']);\nconst SHORT: Record<string, string> = { h: 'help', v: 'version', p: 'port' };\n\n/** Parse `process.argv.slice(2)`-style tokens into a `ParsedArgs`. */\nexport function parseArgs(argv: readonly string[]): ParsedArgs {\n let command: string | undefined;\n const positionals: string[] = [];\n const unknown: string[] = [];\n let help = false;\n let version = false;\n let port: number | undefined;\n let host: string | undefined;\n let template: string | undefined;\n let dir: string | undefined;\n\n for (let i = 0; i < argv.length; i++) {\n const token = argv[i];\n if (token === undefined) continue;\n\n if (token.startsWith('--') || (token.startsWith('-') && token.length > 1 && !/^-\\d/.test(token))) {\n // Normalise `--name=value` and short flags to a long flag name + value.\n const isLong = token.startsWith('--');\n const raw = isLong ? token.slice(2) : token.slice(1);\n const eq = raw.indexOf('=');\n let name = eq >= 0 ? raw.slice(0, eq) : raw;\n let inlineValue: string | undefined = eq >= 0 ? raw.slice(eq + 1) : undefined;\n if (!isLong) name = SHORT[name] ?? name;\n\n if (BOOLEAN_FLAGS.has(name)) {\n if (name === 'help') help = true;\n else if (name === 'version') version = true;\n continue;\n }\n\n if (VALUE_FLAGS.has(name)) {\n const value = inlineValue ?? argv[++i];\n if (value === undefined) {\n unknown.push(`${name} (missing value)`);\n continue;\n }\n if (name === 'port') {\n const n = Number.parseInt(value, 10);\n port = Number.isFinite(n) && n > 0 ? n : undefined;\n if (port === undefined) unknown.push(`port (invalid: ${value})`);\n } else if (name === 'host') host = value;\n else if (name === 'template') template = value;\n else if (name === 'dir') dir = value;\n continue;\n }\n\n unknown.push(name);\n // A stray `--flag value` shouldn't swallow the value as a positional\n // silently; but we also don't know it takes a value, so leave `value`.\n inlineValue = undefined;\n continue;\n }\n\n if (command === undefined) command = token;\n else positionals.push(token);\n }\n\n return { command, positionals, help, version, port, host, template, dir, unknown };\n}\n","/**\n * Minimal ANSI logger — no third-party colour dependency. Colours are disabled\n * automatically when output is not a TTY or when `NO_COLOR` is set, so piped and\n * CI output stays clean.\n */\n\n/* eslint-disable no-console */\n\nconst useColor =\n process.env['NO_COLOR'] === undefined &&\n process.env['FORCE_COLOR'] !== '0' &&\n (process.stdout.isTTY === true || process.env['FORCE_COLOR'] !== undefined);\n\nfunction paint(code: number, text: string): string {\n return useColor ? `\u001b[${code}m${text}\u001b[0m` : text;\n}\n\nexport const style = {\n bold: (t: string): string => paint(1, t),\n dim: (t: string): string => paint(2, t),\n red: (t: string): string => paint(31, t),\n green: (t: string): string => paint(32, t),\n yellow: (t: string): string => paint(33, t),\n blue: (t: string): string => paint(34, t),\n cyan: (t: string): string => paint(36, t),\n};\n\nconst BRAND = style.bold(style.cyan('streetui'));\n\nexport interface Logger {\n info(message: string): void;\n success(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n plain(message: string): void;\n}\n\n/** The default logger writes to stdout/stderr with a `streetui` prefix. */\nexport function createLogger(prefix = BRAND): Logger {\n return {\n info: (m) => console.log(`${prefix} ${m}`),\n success: (m) => console.log(`${prefix} ${style.green(m)}`),\n warn: (m) => console.warn(`${prefix} ${style.yellow(m)}`),\n error: (m) => console.error(`${prefix} ${style.red(m)}`),\n plain: (m) => console.log(m),\n };\n}\n","/**\n * Developer-facing diagnostics. Two rules govern everything here (Phase 6, 19,\n * 22): be USEFUL and be TRUTHFUL. We only print a source position when the\n * underlying tool (esbuild / Node) actually gives us one, and we never dress up\n * a failure as anything other than what it is.\n */\n\nimport { style } from './logger.js';\n\n/**\n * A CLI-level error carrying a human-readable explanation and, optionally, a\n * concrete suggestion. Throwing this (instead of a bare `Error`) lets the top\n * level render a clean message rather than a raw stack trace for expected\n * user mistakes (Phase 17).\n */\nexport class CliError extends Error {\n readonly suggestion: string | undefined;\n /** Process exit code to use when this error reaches the top level. */\n readonly exitCode: number;\n\n constructor(message: string, options?: { suggestion?: string; exitCode?: number }) {\n super(message);\n this.name = 'CliError';\n this.suggestion = options?.suggestion;\n this.exitCode = options?.exitCode ?? 1;\n }\n}\n\n/** A single build problem with an optional, real source location. */\nexport interface BuildProblem {\n readonly message: string;\n /** File path, when the tool reported one. */\n readonly file?: string;\n /** 1-based line, when known. */\n readonly line?: number;\n /** 1-based column, when known. */\n readonly column?: number;\n /** The offending source line, when the tool provided it. */\n readonly lineText?: string;\n /** A concrete suggestion, when we can infer one honestly. */\n readonly suggestion?: string;\n}\n\n/** Known StreetUI API names, used only to suggest fixes for obvious typos. */\nconst KNOWN_DSL_METHODS = [\n 'app', 'page', 'section', 'container', 'heading', 'text', 'button', 'link',\n 'input', 'form', 'list', 'listOf', 'when', 'errorBoundary',\n];\n\n/**\n * Turn an esbuild message into a `BuildProblem`, preserving the real location\n * esbuild computed. If esbuild could not determine a location, none is invented.\n */\nexport function fromEsbuildMessage(msg: {\n text: string;\n location: { file: string; line: number; column: number; lineText: string } | null;\n}): BuildProblem {\n const problem: BuildProblem = { message: msg.text };\n const loc = msg.location;\n if (loc === null) return withSuggestion(problem);\n return withSuggestion({\n message: msg.text,\n file: loc.file,\n line: loc.line,\n column: loc.column + 1, // esbuild columns are 0-based; humans count from 1.\n lineText: loc.lineText,\n });\n}\n\nfunction withSuggestion(problem: BuildProblem): BuildProblem {\n // Only attach a suggestion when we can make a truthful, specific one.\n const unknownApi = /Property '(\\w+)' does not exist|'(\\w+)' is not a function/.exec(problem.message);\n const missingModule = /Could not resolve [\"']([^\"']+)[\"']/.exec(problem.message);\n\n if (missingModule) {\n const spec = missingModule[1] ?? '';\n if (spec.startsWith('@streetui/')) {\n return {\n ...problem,\n suggestion: `Install the StreetUI packages (run \"npm install\") — \"${spec}\" is not resolvable yet.`,\n };\n }\n return { ...problem, suggestion: `Check the import path \"${spec}\" — the file or package could not be found.` };\n }\n\n if (unknownApi) {\n const name = unknownApi[1] ?? unknownApi[2] ?? '';\n const near = KNOWN_DSL_METHODS.find((m) => m.toLowerCase() === name.toLowerCase() && m !== name)\n ?? KNOWN_DSL_METHODS.find((m) => m.startsWith(name.slice(0, 3)));\n if (near !== undefined && name.length > 0) {\n return { ...problem, suggestion: `Did you mean \"${near}\"? Check the StreetUI DSL API.` };\n }\n }\n\n return problem;\n}\n\n/** Render one build problem as a readable multi-line block (Phase 6 shape). */\nexport function formatProblem(problem: BuildProblem): string {\n const lines: string[] = [];\n if (problem.file !== undefined) {\n const pos =\n problem.line !== undefined\n ? `:${problem.line}${problem.column !== undefined ? `:${problem.column}` : ''}`\n : '';\n lines.push(style.cyan(`${problem.file}${pos}`));\n }\n lines.push(problem.message);\n if (problem.lineText !== undefined && problem.lineText.trim().length > 0) {\n lines.push(style.dim(` | ${problem.lineText.trim()}`));\n }\n if (problem.suggestion !== undefined) {\n lines.push('');\n lines.push(`${style.yellow('Suggestion:')} ${problem.suggestion}`);\n }\n return lines.join('\\n');\n}\n\n/** Render a full build failure with a StreetUI header and every problem. */\nexport function formatBuildFailure(problems: readonly BuildProblem[]): string {\n const header = style.red(style.bold('StreetUI build error'));\n const count = problems.length === 1 ? '1 error' : `${problems.length} errors`;\n const blocks = problems.map((p) => formatProblem(p)).join('\\n\\n');\n return `${header} (${count})\\n\\n${blocks}`;\n}\n","/**\n * Project resolution and validation (Phase 17). Before `dev`, `build`, or\n * `start` do any real work, we confirm the working directory actually looks\n * like a StreetUI project and fail with a clear, actionable message otherwise —\n * never a cryptic stack trace.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { resolve, join } from 'node:path';\nimport { CliError } from './diagnostics.js';\nimport { loadConfig, type ResolvedConfig } from './config.js';\n\n/** A validated StreetUI project ready for a command to act on. */\nexport interface ResolvedProject {\n /** Absolute project root. */\n readonly root: string;\n /** Parsed package.json. */\n readonly packageJson: PackageJson;\n /** Fully-resolved configuration (defaults applied). */\n readonly config: ResolvedConfig;\n}\n\ninterface PackageJson {\n readonly name?: string;\n readonly version?: string;\n readonly type?: string;\n readonly dependencies?: Record<string, string>;\n readonly devDependencies?: Record<string, string>;\n readonly scripts?: Record<string, string>;\n readonly [key: string]: unknown;\n}\n\nfunction readPackageJson(root: string): PackageJson {\n const pkgPath = join(root, 'package.json');\n if (!existsSync(pkgPath)) {\n throw new CliError(`No package.json found in ${root}.`, {\n suggestion: 'Run this command from the root of a StreetUI project, or create one with \"npm create streetui@latest\".',\n });\n }\n let raw: string;\n try {\n raw = readFileSync(pkgPath, 'utf8');\n } catch (err) {\n throw new CliError(`Could not read ${pkgPath}: ${(err as Error).message}`);\n }\n try {\n return JSON.parse(raw) as PackageJson;\n } catch (err) {\n throw new CliError(`package.json is not valid JSON: ${(err as Error).message}`, {\n suggestion: 'Fix the syntax error in package.json and try again.',\n });\n }\n}\n\n/** True when the package depends on any `@streetui/*` package. */\nfunction dependsOnStreetUI(pkg: PackageJson): boolean {\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n return Object.keys(deps).some((name) => name === 'streetui' || name.startsWith('@streetui/'));\n}\n\n/**\n * Resolve + validate the project rooted at `cwd` (or `--dir`). Throws a\n * `CliError` with a helpful suggestion for every failure mode Phase 17 lists:\n * missing package.json, not a StreetUI project, invalid config, missing entry.\n */\nexport async function resolveProject(cwd: string, options?: { requireEntry?: boolean }): Promise<ResolvedProject> {\n const root = resolve(cwd);\n const packageJson = readPackageJson(root);\n\n if (!dependsOnStreetUI(packageJson)) {\n throw new CliError(`${root} does not look like a StreetUI project.`, {\n suggestion: 'Its package.json declares no \"@streetui/*\" dependency. Create a project with \"npm create streetui@latest\".',\n });\n }\n\n let config: ResolvedConfig;\n try {\n config = await loadConfig(root);\n } catch (err) {\n if (err instanceof CliError) throw err;\n throw new CliError(`Failed to load streetui.config: ${(err as Error).message}`, {\n suggestion: 'Check streetui.config.ts for syntax or import errors.',\n });\n }\n\n if (options?.requireEntry === true && !existsSync(config.clientEntry)) {\n throw new CliError(`Client entry not found: ${config.clientEntry}`, {\n suggestion: 'Create the entry file, or set \"clientEntry\" in streetui.config.ts to point at your app entry.',\n });\n }\n\n return { root, packageJson, config };\n}\n","/**\n * StreetUI project configuration (Phase 9). The config is intentionally tiny:\n * every field has a sensible default so `streetui.config.ts` is optional. A\n * project with no config file still builds and runs.\n *\n * The file is authored as TypeScript (`streetui.config.ts`) and compiled with\n * esbuild to a temporary ESM module before import, so we never depend on the\n * host having a TS loader registered.\n */\n\nimport { build as esbuildBuild } from 'esbuild';\nimport { rm, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve, isAbsolute } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\n/** User-facing configuration shape (all fields optional). */\nexport interface StreetUIConfig {\n /** Dev server / preview port. Default 3000. */\n readonly port?: number;\n /** Host to bind. Default 'localhost'. */\n readonly host?: string;\n /** Client/browser entry, relative to project root. Default 'src/main.ts'. */\n readonly clientEntry?: string;\n /** Server entry used for SSR, relative to project root. Default 'src/server.ts'. */\n readonly serverEntry?: string;\n /** Output directory for `build`. Default 'dist'. */\n readonly outDir?: string;\n /** Static assets directory copied verbatim. Default 'public'. */\n readonly publicDir?: string;\n}\n\n/** Fully-resolved config: every field present, all paths absolute. */\nexport interface ResolvedConfig {\n readonly root: string;\n readonly port: number;\n readonly host: string;\n readonly clientEntry: string;\n readonly serverEntry: string;\n readonly outDir: string;\n readonly publicDir: string;\n}\n\n/**\n * Identity helper that gives config authors type-checking and autocomplete.\n * It returns its argument unchanged — the value matters, not the call.\n */\nexport function defineConfig(config: StreetUIConfig): StreetUIConfig {\n return config;\n}\n\nconst DEFAULTS = {\n port: 3000,\n host: 'localhost',\n clientEntry: 'src/main.ts',\n serverEntry: 'src/server.ts',\n outDir: 'dist',\n publicDir: 'public',\n} as const;\n\n/** Config file names we look for, in priority order. */\nconst CONFIG_FILENAMES = ['streetui.config.ts', 'streetui.config.mjs', 'streetui.config.js'];\n\n/** Absolute path of the first config file present in `root`, or undefined. */\nexport function findConfigFile(root: string): string | undefined {\n for (const name of CONFIG_FILENAMES) {\n const candidate = join(root, name);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n\n/** Compile + import a `streetui.config.*` file and return its default export. */\nasync function importConfigFile(file: string): Promise<StreetUIConfig> {\n // `.js`/`.mjs` can be imported directly; `.ts` is compiled first.\n if (!file.endsWith('.ts')) {\n const mod = (await import(pathToFileURL(file).href)) as { default?: StreetUIConfig };\n return mod.default ?? {};\n }\n\n const result = await esbuildBuild({\n entryPoints: [file],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n // Keep node builtins and any deps external — we only want the config value.\n packages: 'external',\n logLevel: 'silent',\n });\n const code = result.outputFiles[0]?.text ?? '';\n\n // Write the compiled module *next to the config file* (not the OS temp dir)\n // so that any bare imports it kept external — e.g. `@streetui/cli` for\n // `defineConfig` — resolve against the project's own `node_modules`. A temp\n // file in the system temp directory would have no node_modules to walk up to.\n const outFile = join(dirname(file), `.streetui.config.${Date.now()}.mjs`);\n try {\n await writeFile(outFile, code, 'utf8');\n const mod = (await import(pathToFileURL(outFile).href)) as {\n default?: StreetUIConfig;\n };\n return mod.default ?? {};\n } finally {\n await rm(outFile, { force: true });\n }\n}\n\nfunction toAbsolute(root: string, p: string): string {\n return isAbsolute(p) ? p : resolve(root, p);\n}\n\n/**\n * Load and fully resolve configuration for the project rooted at `root`.\n * Missing config file → all defaults. Every returned path is absolute.\n */\nexport async function loadConfig(root: string): Promise<ResolvedConfig> {\n const absRoot = resolve(root);\n const file = findConfigFile(absRoot);\n const user = file ? await importConfigFile(file) : {};\n\n return {\n root: absRoot,\n port: user.port ?? DEFAULTS.port,\n host: user.host ?? DEFAULTS.host,\n clientEntry: toAbsolute(absRoot, user.clientEntry ?? DEFAULTS.clientEntry),\n serverEntry: toAbsolute(absRoot, user.serverEntry ?? DEFAULTS.serverEntry),\n outDir: toAbsolute(absRoot, user.outDir ?? DEFAULTS.outDir),\n publicDir: toAbsolute(absRoot, user.publicDir ?? DEFAULTS.publicDir),\n };\n}\n","/**\n * Production build (Phase 7). Two esbuild passes over the project's real\n * entries — a browser bundle for hydration and a Node bundle for SSR — plus a\n * copy of the public directory. No separate production rendering system: the\n * same DSL → compile → renderer pipeline the app already uses is bundled as-is.\n */\n\nimport { build as esbuildBuild, type BuildOptions, type Message } from 'esbuild';\nimport { cp, mkdir, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedProject } from './project.js';\nimport { fromEsbuildMessage, formatBuildFailure, CliError, type BuildProblem } from './diagnostics.js';\nimport { clientEnvDefine } from './env.js';\n\n/** Where each artifact lands under the configured `outDir`. */\nexport interface BuildOutput {\n readonly clientDir: string;\n readonly serverDir: string;\n readonly clientBundle: string;\n readonly serverBundle: string;\n}\n\n/** Convert esbuild's error array into our problem shape, preserving locations. */\nfunction toProblems(messages: readonly Message[]): BuildProblem[] {\n return messages.map((m) => fromEsbuildMessage({ text: m.text, location: m.location }));\n}\n\n/** Shared esbuild options for both passes. */\nfunction baseOptions(mode: 'development' | 'production'): BuildOptions {\n return {\n bundle: true,\n format: 'esm',\n sourcemap: true,\n logLevel: 'silent',\n define: {\n // Public build-time constants. Server secrets are never injected here.\n 'process.env.NODE_ENV': JSON.stringify(mode),\n },\n minify: mode === 'production',\n };\n}\n\n/**\n * Run the production build for `project`. Returns the output layout on success;\n * throws a `CliError` carrying formatted diagnostics on failure. When\n * `serverEntry` is absent the server pass is skipped (client-only project).\n */\nexport async function buildProject(\n project: ResolvedProject,\n mode: 'development' | 'production' = 'production',\n): Promise<BuildOutput> {\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverDir = join(config.outDir, 'server');\n\n await rm(config.outDir, { recursive: true, force: true });\n await mkdir(clientDir, { recursive: true });\n\n // Only errors are fatal. esbuild throws (rejects) when a pass has errors, so\n // the catch branch is the sole source of build-breaking problems. Warnings —\n // including exports-ordering notes emitted for third-party dependency\n // package.json files — must never fail a production build.\n const errors: BuildProblem[] = [];\n\n // Client (browser) pass — always required.\n await esbuildBuild({\n ...baseOptions(mode),\n entryPoints: [config.clientEntry],\n outfile: join(clientDir, 'main.js'),\n platform: 'browser',\n target: ['es2022'],\n // Only STREETUI_PUBLIC_* env vars reach the browser (plus NODE_ENV).\n define: clientEnvDefine(mode),\n }).catch((err: { errors?: Message[] }) => {\n errors.push(...toProblems(err.errors ?? []));\n return undefined;\n });\n\n // Server (node) pass — only when a server entry exists.\n const hasServerEntry = existsSync(config.serverEntry);\n if (hasServerEntry) {\n await mkdir(serverDir, { recursive: true });\n await esbuildBuild({\n ...baseOptions(mode),\n entryPoints: [config.serverEntry],\n outfile: join(serverDir, 'server.js'),\n platform: 'node',\n target: ['node18'],\n packages: 'external',\n }).catch((err: { errors?: Message[] }) => {\n errors.push(...toProblems(err.errors ?? []));\n return undefined;\n });\n }\n\n if (errors.length > 0) {\n throw new CliError(formatBuildFailure(errors), { exitCode: 1 });\n }\n\n // Copy static assets into the client output so they ship together.\n if (existsSync(config.publicDir)) {\n await cp(config.publicDir, clientDir, { recursive: true });\n }\n\n return {\n clientDir,\n serverDir,\n clientBundle: join(clientDir, 'main.js'),\n serverBundle: join(serverDir, 'server.js'),\n };\n}\n","/**\n * Environment variables (Phase 10). The rule is simple and safe by default:\n * only variables whose names begin with `STREETUI_PUBLIC_` are exposed to the\n * browser bundle. Everything else stays on the server, so secrets in the\n * process environment cannot leak into client-side JavaScript.\n *\n * `NODE_ENV` is always defined (as the build mode) so app code can branch on\n * development vs production.\n */\n\n/** Prefix that marks an env var as safe to ship to the browser. */\nexport const PUBLIC_ENV_PREFIX = 'STREETUI_PUBLIC_';\n\n/**\n * Build the esbuild `define` map for the CLIENT bundle: `NODE_ENV` plus every\n * `STREETUI_PUBLIC_*` variable, each stringified as a compile-time constant.\n * Server-only variables are deliberately excluded.\n */\nexport function clientEnvDefine(\n mode: 'development' | 'production',\n env: NodeJS.ProcessEnv = process.env,\n): Record<string, string> {\n const define: Record<string, string> = {\n 'process.env.NODE_ENV': JSON.stringify(mode),\n };\n for (const [key, value] of Object.entries(env)) {\n if (key.startsWith(PUBLIC_ENV_PREFIX) && value !== undefined) {\n define[`process.env.${key}`] = JSON.stringify(value);\n }\n }\n return define;\n}\n\n/** Names of the public variables currently visible (for logging/diagnostics). */\nexport function publicEnvNames(env: NodeJS.ProcessEnv = process.env): string[] {\n return Object.keys(env).filter((k) => k.startsWith(PUBLIC_ENV_PREFIX));\n}\n","/**\n * `streetui dev` (Phase 5). Builds the project once, then watches for changes\n * with esbuild's incremental context API and rebuilds only what changed —\n * avoiding a full cold build per keystroke (Phase 27). On each successful\n * rebuild connected browsers are told to reload; build errors are printed with\n * real source positions and never crash the server.\n */\n\nimport { context, type BuildContext, type BuildOptions, type Message } from 'esbuild';\nimport { cp, mkdir, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Logger } from './logger.js';\nimport type { ResolvedProject } from './project.js';\nimport { startServer, ReloadHub, type RunningServer } from './serve.js';\nimport { fromEsbuildMessage, formatBuildFailure } from './diagnostics.js';\nimport { clientEnvDefine } from './env.js';\n\nexport interface DevOptions {\n readonly project: ResolvedProject;\n readonly logger: Logger;\n readonly host?: string;\n readonly port?: number;\n}\n\n/** Handle returned so callers (and tests) can shut the dev server down. */\nexport interface DevServer {\n readonly url: string;\n stop(): Promise<void>;\n}\n\n/** Report esbuild results to the logger and reload browsers when clean. */\nfunction reportResult(\n label: string,\n errors: readonly Message[],\n logger: Logger,\n reload: ReloadHub,\n): void {\n if (errors.length > 0) {\n const problems = errors.map((m) => fromEsbuildMessage({ text: m.text, location: m.location }));\n logger.error(`${label} rebuild failed:`);\n logger.plain(formatBuildFailure(problems));\n return;\n }\n reload.triggerReload();\n}\n\n/** Start the dev server. Resolves once it is listening; keep the handle to stop. */\nexport async function runDev(options: DevOptions): Promise<DevServer> {\n const { project, logger } = options;\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverDir = join(config.outDir, 'server');\n const serverBundle = join(serverDir, 'server.js');\n const reload = new ReloadHub();\n\n await rm(config.outDir, { recursive: true, force: true });\n await mkdir(clientDir, { recursive: true });\n await mkdir(serverDir, { recursive: true });\n\n const shared: BuildOptions = {\n bundle: true,\n format: 'esm',\n sourcemap: true,\n logLevel: 'silent',\n define: { 'process.env.NODE_ENV': JSON.stringify('development') },\n };\n\n const contexts: BuildContext[] = [];\n\n const clientCtx = await context({\n ...shared,\n entryPoints: [config.clientEntry],\n outfile: join(clientDir, 'main.js'),\n platform: 'browser',\n target: ['es2022'],\n define: clientEnvDefine('development'),\n plugins: [\n {\n name: 'streetui-client-reload',\n setup(builder) {\n builder.onEnd((result) => reportResult('Client', result.errors, logger, reload));\n },\n },\n ],\n });\n contexts.push(clientCtx);\n\n const hasServerEntry = existsSync(config.serverEntry);\n if (hasServerEntry) {\n const serverCtx = await context({\n ...shared,\n entryPoints: [config.serverEntry],\n outfile: serverBundle,\n platform: 'node',\n target: ['node18'],\n packages: 'external',\n plugins: [\n {\n name: 'streetui-server-reload',\n setup(builder) {\n builder.onEnd((result) => {\n if (result.errors.length > 0) {\n reportResult('Server', result.errors, logger, reload);\n }\n });\n },\n },\n ],\n });\n contexts.push(serverCtx);\n }\n\n // Initial build for every context, then enable watch mode.\n await Promise.all(contexts.map((c) => c.rebuild().catch(() => undefined)));\n await Promise.all(contexts.map((c) => c.watch()));\n\n if (existsSync(config.publicDir)) {\n await cp(config.publicDir, clientDir, { recursive: true });\n }\n\n const host = options.host ?? config.host;\n const port = options.port ?? config.port;\n\n let running: RunningServer | undefined;\n if (hasServerEntry) {\n running = await startServer({ clientDir, serverBundle, host, port, reload, devMode: true });\n logger.success(`Dev server running at ${running.url}`);\n logger.info('Watching for changes… (press Ctrl+C to stop)');\n } else {\n logger.warn('No server entry found — client bundle is being watched, but no dev server was started.');\n }\n\n const url = running?.url ?? `http://${host}:${port}`;\n return {\n url,\n stop: async () => {\n await Promise.all(contexts.map((c) => c.dispose()));\n await running?.close();\n },\n };\n}\n","/**\n * The StreetUI HTTP server (Phases 5 & 8). Built on Node's standard `node:http`\n * — no Express, no third-party server. It serves the built client assets as\n * static files and delegates every other request to the project's server\n * bundle, which exports a `render(request)` function producing full HTML.\n *\n * The same server backs both `dev` (with live-reload injection) and `start`\n * (production). Dev-only behaviour is gated behind the `reload` option.\n */\n\nimport { createServer as createHttpServer, type IncomingMessage, type ServerResponse, type Server } from 'node:http';\nimport { readFile, stat } from 'node:fs/promises';\nimport { join, normalize, extname, relative, isAbsolute } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\n/** The contract a project's server entry must satisfy. */\nexport interface RenderRequest {\n readonly url: string;\n readonly method: string;\n readonly headers: Record<string, string | string[] | undefined>;\n}\nexport interface RenderResult {\n readonly html: string;\n readonly status?: number;\n readonly headers?: Record<string, string>;\n}\nexport type RenderFn = (request: RenderRequest) => RenderResult | Promise<RenderResult>;\n\nexport interface ServeOptions {\n readonly clientDir: string;\n readonly serverBundle: string;\n readonly host: string;\n readonly port: number;\n /** When set, HTML responses get a live-reload snippet + an SSE endpoint. */\n readonly reload?: ReloadHub;\n /**\n * Dev mode: re-import the server bundle on every request so edits are picked\n * up without restarting. In production the bundle is loaded once.\n */\n readonly devMode?: boolean;\n}\n\n/** A running server plus the resolved address and a stop handle. */\nexport interface RunningServer {\n readonly server: Server;\n readonly url: string;\n close(): Promise<void>;\n}\n\nconst MIME: Record<string, string> = {\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.html': 'text/html; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\n/** Live-reload coordination for dev: tracks SSE clients and pushes events. */\nexport class ReloadHub {\n private readonly clients = new Set<ServerResponse>();\n static readonly PATH = '/__streetui_reload';\n\n /** The snippet injected before `</body>` so the page listens for reloads. */\n static readonly snippet =\n `<script>(function(){try{new EventSource(\"${ReloadHub.PATH}\").onmessage=function(e){if(e.data===\"reload\")location.reload()}}catch(_){}})();</script>`;\n\n handle(_req: IncomingMessage, res: ServerResponse): void {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n res.write(': connected\\n\\n');\n this.clients.add(res);\n res.on('close', () => this.clients.delete(res));\n }\n\n /** Tell every connected browser to reload. */\n triggerReload(): void {\n for (const res of this.clients) res.write('data: reload\\n\\n');\n }\n\n closeAll(): void {\n for (const res of this.clients) res.end();\n this.clients.clear();\n }\n}\n\n/**\n * Resolve a URL path to a file inside `clientDir`, guarding against escapes.\n *\n * Security notes (production hardening, v0.8):\n * - Malformed percent-encoding (`decodeURIComponent` throwing) is rejected\n * rather than allowed to bubble up as a 500.\n * - Null-byte injection (`\\0`) is rejected — it can truncate paths in some\n * syscalls.\n * - Containment is verified with `path.relative`, NOT a raw `startsWith`\n * prefix check: a prefix check treats a sibling dir like `<clientDir>-x` as\n * \"inside\" and is a real traversal hole. `relative` yields a `..`-leading or\n * absolute path exactly when the target escapes the root.\n */\nfunction resolveStatic(clientDir: string, urlPath: string): string | undefined {\n let decoded: string;\n try {\n decoded = decodeURIComponent(urlPath.split('?')[0] ?? '');\n } catch {\n return undefined; // malformed percent-encoding\n }\n if (decoded.includes('\\0')) return undefined; // null-byte injection\n const clean = normalize(decoded).replace(/^(\\.\\.[/\\\\])+/, '');\n const full = join(clientDir, clean);\n const rel = relative(clientDir, full);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) return full;\n return undefined; // escaped the client root\n}\n\nasync function tryServeStatic(\n clientDir: string,\n urlPath: string,\n res: ServerResponse,\n devMode: boolean,\n): Promise<boolean> {\n const full = resolveStatic(clientDir, urlPath);\n if (full === undefined) return false;\n try {\n const info = await stat(full);\n if (!info.isFile()) return false;\n const body = await readFile(full);\n res.writeHead(200, {\n 'Content-Type': MIME[extname(full)] ?? 'application/octet-stream',\n // Never let a browser MIME-sniff a served asset into something executable.\n 'X-Content-Type-Options': 'nosniff',\n // Dev must always re-fetch; production may cache immutable build output.\n 'Cache-Control': devMode ? 'no-cache' : 'public, max-age=3600',\n });\n res.end(body);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Import the built server bundle and return its `render` export. */\nasync function loadRender(serverBundle: string): Promise<RenderFn> {\n const mod = (await import(`${pathToFileURL(serverBundle).href}?t=${Date.now()}`)) as {\n render?: RenderFn;\n default?: RenderFn | { render?: RenderFn };\n };\n const candidate =\n mod.render ??\n (typeof mod.default === 'function' ? mod.default : mod.default?.render);\n if (typeof candidate !== 'function') {\n throw new Error(`Server entry ${serverBundle} must export a \"render(request)\" function.`);\n }\n return candidate;\n}\n\nfunction injectReload(html: string): string {\n if (html.includes('</body>')) return html.replace('</body>', `${ReloadHub.snippet}</body>`);\n return html + ReloadHub.snippet;\n}\n\n/** Start the HTTP server and resolve once it is actually listening. */\nexport async function startServer(options: ServeOptions): Promise<RunningServer> {\n // In production, load the render function once. In dev, load per request so\n // rebuilt bundles are picked up (loadRender cache-busts the import URL).\n let cachedRender: RenderFn | undefined;\n const getRender = async (): Promise<RenderFn> => {\n if (options.devMode === true) return loadRender(options.serverBundle);\n if (cachedRender === undefined) cachedRender = await loadRender(options.serverBundle);\n return cachedRender;\n };\n // Fail fast on a broken bundle before we start listening.\n await getRender();\n\n const server = createHttpServer((req, res) => {\n void handleRequest(req, res, getRender, options);\n });\n\n await new Promise<void>((resolvePromise, reject) => {\n server.once('error', reject);\n server.listen(options.port, options.host, () => {\n server.off('error', reject);\n resolvePromise();\n });\n });\n\n const url = `http://${options.host}:${options.port}`;\n return {\n server,\n url,\n close: () =>\n new Promise<void>((resolveClose) => {\n options.reload?.closeAll();\n server.close(() => resolveClose());\n }),\n };\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n getRender: () => Promise<RenderFn>,\n options: ServeOptions,\n): Promise<void> {\n const url = req.url ?? '/';\n\n // Dev live-reload channel.\n if (options.reload && url === ReloadHub.PATH) {\n options.reload.handle(req, res);\n return;\n }\n\n // Static assets first (only paths with an extension, so routes fall through).\n if (extname(url.split('?')[0] ?? '') !== '') {\n const served = await tryServeStatic(options.clientDir, url, res, options.devMode === true);\n if (served) return;\n }\n\n // Otherwise, server-render the requested route.\n try {\n const render = await getRender();\n const result = await render({\n url,\n method: req.method ?? 'GET',\n headers: req.headers,\n });\n const status = result.status ?? 200;\n const html = options.reload ? injectReload(result.html) : result.html;\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8', ...result.headers });\n res.end(html);\n } catch (err) {\n // Always surface the failure server-side for operators.\n // eslint-disable-next-line no-console\n console.error(`[StreetUI] render error for ${url}:`, err);\n // But only leak stack traces / internal detail in dev. A production server\n // must not disclose stacks, file paths or env-derived strings to clients\n // (information-disclosure hardening, v0.8 §18/§19).\n res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });\n if (options.devMode === true) {\n const message = err instanceof Error ? err.stack ?? err.message : String(err);\n res.end(`StreetUI server error while rendering ${url}:\\n\\n${message}`);\n } else {\n res.end('Internal Server Error');\n }\n }\n}\n","/**\n * `streetui start` (Phase 8). Serves an existing production build. If the build\n * output is missing we build it first, so `start` on a fresh checkout still\n * works. Uses the standard Node HTTP server from `serve.ts`.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Logger } from './logger.js';\nimport type { ResolvedProject } from './project.js';\nimport { buildProject } from './build.js';\nimport { startServer, type RunningServer } from './serve.js';\nimport { CliError } from './diagnostics.js';\n\nexport interface StartOptions {\n readonly project: ResolvedProject;\n readonly logger: Logger;\n /** Overrides for the configured host/port (from --host/--port). */\n readonly host?: string;\n readonly port?: number;\n}\n\n/** Build (if needed) and serve the production output. Resolves once listening. */\nexport async function runStart(options: StartOptions): Promise<RunningServer> {\n const { project, logger } = options;\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverBundle = join(config.outDir, 'server', 'server.js');\n\n if (!existsSync(serverBundle)) {\n logger.info('No production build found — building first…');\n await buildProject(project, 'production');\n }\n if (!existsSync(serverBundle)) {\n throw new CliError('Production build did not produce a server bundle.', {\n suggestion: 'Ensure your project has a server entry (default src/server.ts) that exports render().',\n });\n }\n\n const host = options.host ?? config.host;\n const port = options.port ?? config.port;\n const running = await startServer({ clientDir, serverBundle, host, port });\n logger.success(`Production server running at ${running.url}`);\n return running;\n}\n","/**\n * `streetui create` / `npm create streetui` (Phase 3). Scaffolds a real,\n * working StreetUI project from a shipped template. No network access, no\n * post-install magic — just a recursive copy with placeholder substitution.\n */\n\nimport { mkdir, readdir, readFile, writeFile, stat } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join, resolve, basename } from 'node:path';\nimport type { Logger } from './logger.js';\nimport { CliError } from './diagnostics.js';\nimport {\n templateDir,\n resolveTemplateName,\n materialisedName,\n applyTokens,\n isTextFile,\n type TemplateName,\n type TemplateTokens,\n} from './templates.js';\n\nexport interface CreateOptions {\n /** Target directory (relative or absolute). */\n readonly targetDir: string;\n /** Template to use; defaults to the SSR starter. */\n readonly template?: string;\n /** StreetUI package version the generated project should depend on. */\n readonly frameworkVersion: string;\n readonly logger: Logger;\n}\n\nexport interface CreateResult {\n readonly root: string;\n readonly template: TemplateName;\n readonly files: readonly string[];\n}\n\n/** True when a directory is absent or empty (safe to scaffold into). */\nasync function isEmptyDir(dir: string): Promise<boolean> {\n if (!existsSync(dir)) return true;\n const entries = await readdir(dir);\n return entries.filter((e) => e !== '.git').length === 0;\n}\n\n/** Recursively copy a template directory, transforming names and tokens. */\nasync function copyTree(\n srcDir: string,\n destDir: string,\n tokens: TemplateTokens,\n written: string[],\n): Promise<void> {\n await mkdir(destDir, { recursive: true });\n const entries = await readdir(srcDir);\n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const info = await stat(srcPath);\n const destName = materialisedName(entry);\n const destPath = join(destDir, destName);\n if (info.isDirectory()) {\n await copyTree(srcPath, destPath, tokens, written);\n } else if (isTextFile(entry)) {\n const raw = await readFile(srcPath, 'utf8');\n await writeFile(destPath, applyTokens(raw, tokens), 'utf8');\n written.push(destPath);\n } else {\n const raw = await readFile(srcPath);\n await writeFile(destPath, raw);\n written.push(destPath);\n }\n }\n}\n\n/**\n * Scaffold a new project. Validates the template and the (empty) target, copies\n * the tree, and returns the created root + file list. Throws `CliError` on any\n * user-facing problem.\n */\nexport async function createProject(options: CreateOptions): Promise<CreateResult> {\n const { logger } = options;\n\n let template: TemplateName;\n try {\n template = resolveTemplateName(options.template);\n } catch (err) {\n throw new CliError((err as Error).message, { suggestion: 'Pass a valid --template value.' });\n }\n\n const root = resolve(options.targetDir);\n const projectName = basename(root);\n\n if (!(await isEmptyDir(root))) {\n throw new CliError(`Target directory ${root} already exists and is not empty.`, {\n suggestion: 'Choose a new directory name or empty the existing one.',\n });\n }\n\n const src = templateDir(template);\n if (!existsSync(src)) {\n throw new CliError(`Template \"${template}\" is missing from the CLI installation (${src}).`, {\n suggestion: 'Reinstall @streetui/cli — the shipped templates appear to be absent.',\n });\n }\n\n const tokens: TemplateTokens = { projectName, frameworkVersion: options.frameworkVersion };\n const files: string[] = [];\n await copyTree(src, root, tokens, files);\n\n logger.success(`Created ${projectName} (${template} template) with ${files.length} files.`);\n logger.plain('');\n logger.info('Next steps:');\n logger.plain(` cd ${options.targetDir}`);\n logger.plain(' npm install');\n logger.plain(' npm run dev');\n\n return { root, template, files };\n}\n","/**\n * Template registry (Phases 3, 11, 12). Templates are real files shipped inside\n * the CLI package under `templates/<name>/`. They are copied verbatim at\n * scaffold time, with two transforms: a small set of placeholder tokens are\n * substituted, and files prefixed `_` are un-prefixed (so `_gitignore` becomes\n * `.gitignore` and `_package.json` becomes `package.json` — npm would otherwise\n * mangle those names on publish).\n */\n\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Available starter templates. */\nexport type TemplateName = 'basic' | 'ssr';\n\nexport const TEMPLATES: readonly TemplateName[] = ['basic', 'ssr'];\nexport const DEFAULT_TEMPLATE: TemplateName = 'ssr';\n\n/** Tokens replaced in every text file of a template. */\nexport interface TemplateTokens {\n readonly projectName: string;\n readonly frameworkVersion: string;\n}\n\n/**\n * Files stored under a transformed name because npm would otherwise mangle them\n * on publish (it renames `.gitignore` and drops/collides on `package.json`). The\n * key is the shipped name; the value is what it becomes in the scaffolded app.\n */\nconst NAME_MAP: Record<string, string> = {\n '_gitignore': '.gitignore',\n '_npmrc': '.npmrc',\n '_package.json': 'package.json',\n};\n\n/** Absolute path to the shipped `templates/` directory. */\nexport function templatesRoot(): string {\n // dist/index.js (or the test-time src) lives one level below the package\n // root; templates/ sits beside dist/. Resolve relative to this module.\n const here = dirname(fileURLToPath(import.meta.url));\n // From dist/ or src/, go up to the package root, then into templates/.\n const candidates = [resolve(here, '..', 'templates'), resolve(here, '..', '..', 'templates')];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n // Fall back to the first candidate; callers surface a clear error if missing.\n return candidates[0] ?? resolve(here, '..', 'templates');\n}\n\n/** Absolute path to a specific template's source directory. */\nexport function templateDir(name: TemplateName): string {\n return join(templatesRoot(), name);\n}\n\n/** Validate a user-supplied template name, returning it typed or throwing. */\nexport function resolveTemplateName(name: string | undefined): TemplateName {\n if (name === undefined) return DEFAULT_TEMPLATE;\n if ((TEMPLATES as readonly string[]).includes(name)) return name as TemplateName;\n throw new Error(`Unknown template \"${name}\". Available: ${TEMPLATES.join(', ')}.`);\n}\n\n/** Map a template file name to its materialised name (see `NAME_MAP`). */\nexport function materialisedName(fileName: string): string {\n return NAME_MAP[fileName] ?? fileName;\n}\n\n/** Replace template tokens in a text file's contents. */\nexport function applyTokens(contents: string, tokens: TemplateTokens): string {\n return contents\n .replaceAll('__PROJECT_NAME__', tokens.projectName)\n .replaceAll('__FRAMEWORK_VERSION__', tokens.frameworkVersion);\n}\n\n/** File extensions treated as text (token substitution applies). */\nconst TEXT_EXTENSIONS = new Set([\n '.ts', '.tsx', '.js', '.mjs', '.cjs', '.json', '.css', '.html', '.md', '.txt', '.npmrc', '',\n]);\n\n/** Whether a file should be read as text for token substitution. */\nexport function isTextFile(fileName: string): boolean {\n const dot = fileName.lastIndexOf('.');\n const ext = dot >= 0 ? fileName.slice(dot) : '';\n // `_gitignore` / `_npmrc` have no dotted extension → treat as text.\n return TEXT_EXTENSIONS.has(ext);\n}\n","/**\n * `@streetui/cli` public entry. Exposes the programmatic API used by the\n * executables and the tests, and implements `runCli` — the command dispatcher\n * that turns argv into one of `create` / `dev` / `build` / `start` (plus\n * `--help` / `--version`). The CLI only orchestrates the existing StreetUI\n * pipeline; it is not a framework layer of its own.\n */\n\nimport { parseArgs, type ParsedArgs } from './args.js';\nimport { createLogger, type Logger } from './logger.js';\nimport { CliError } from './diagnostics.js';\nimport { resolveProject } from './project.js';\nimport { buildProject } from './build.js';\nimport { runDev } from './dev.js';\nimport { runStart } from './start.js';\nimport { createProject } from './create.js';\n\nexport { parseArgs } from './args.js';\nexport { defineConfig, loadConfig, findConfigFile } from './config.js';\nexport type { StreetUIConfig, ResolvedConfig } from './config.js';\nexport { clientEnvDefine, publicEnvNames, PUBLIC_ENV_PREFIX } from './env.js';\nexport { resolveProject } from './project.js';\nexport type { ResolvedProject } from './project.js';\nexport { buildProject } from './build.js';\nexport type { BuildOutput } from './build.js';\nexport { runDev } from './dev.js';\nexport type { DevServer } from './dev.js';\nexport { runStart } from './start.js';\nexport { createProject } from './create.js';\nexport type { CreateResult } from './create.js';\nexport { startServer, ReloadHub } from './serve.js';\nexport type { RenderRequest, RenderResult, RenderFn } from './serve.js';\nexport { CliError } from './diagnostics.js';\nexport { createLogger } from './logger.js';\nexport type { Logger } from './logger.js';\n\n/** The CLI version, read from the compiled package. Kept in one place. */\nexport const CLI_VERSION = '1.8.0';\n\n/** Options for `runCli`, all injectable so tests can drive it in-process. */\nexport interface RunCliOptions {\n /** Working directory the command acts on. Defaults to `process.cwd()`. */\n readonly cwd?: string;\n /** Logger sink. Defaults to the branded stdout logger. */\n readonly logger?: Logger;\n /**\n * When true, `dev` and `start` return their running handle instead of\n * blocking forever. Tests set this; the real binary leaves it false.\n */\n readonly returnServer?: boolean;\n}\n\n/** Result of a command: an exit code plus any long-lived handle for tests. */\nexport interface RunCliResult {\n readonly exitCode: number;\n readonly server?: { url: string; stop: () => Promise<void> };\n}\n\nconst HELP = `streetui — the StreetUI application CLI\n\nUsage:\n streetui <command> [options]\n\nCommands:\n create <dir> Scaffold a new StreetUI project\n dev Start the development server with live reload\n build Produce a production build (dist/client, dist/server)\n start Serve the production build\n\nOptions:\n -h, --help Show this help\n -v, --version Show the CLI version\n -p, --port <n> Port for dev/start (default 3000)\n --host <host> Host for dev/start (default localhost)\n --template <t> Template for create (basic | ssr)\n --dir <path> Project directory (default current directory)\n\nExamples:\n npm create streetui@latest my-app\n streetui dev --port 4000\n streetui build\n streetui start`;\n\n/** Dispatch a parsed command line. Never throws for expected errors — it maps\n * `CliError` to an exit code and a logged message instead. */\nexport async function runCli(argv: readonly string[], options: RunCliOptions = {}): Promise<RunCliResult> {\n const logger = options.logger ?? createLogger();\n const cwd = options.cwd ?? process.cwd();\n const args = parseArgs(argv);\n\n // Reject unknown flags before doing anything (Phase 14: no ignored options).\n if (args.unknown.length > 0) {\n logger.error(`Unknown or invalid option(s): ${args.unknown.join(', ')}`);\n logger.plain(HELP);\n return { exitCode: 1 };\n }\n\n if (args.version && args.command === undefined) {\n logger.plain(CLI_VERSION);\n return { exitCode: 0 };\n }\n if (args.help || args.command === undefined) {\n logger.plain(HELP);\n return { exitCode: args.command === undefined && !args.help ? 1 : 0 };\n }\n\n try {\n return await dispatch(args, cwd, logger, options.returnServer === true);\n } catch (err) {\n if (err instanceof CliError) {\n logger.error(err.message);\n if (err.suggestion !== undefined) logger.plain(err.suggestion);\n return { exitCode: err.exitCode };\n }\n logger.error(`Unexpected error: ${(err as Error).message}`);\n return { exitCode: 1 };\n }\n}\n\nasync function dispatch(\n args: ParsedArgs,\n cwd: string,\n logger: Logger,\n returnServer: boolean,\n): Promise<RunCliResult> {\n const projectCwd = args.dir ?? cwd;\n\n switch (args.command) {\n case 'create': {\n const targetDir = args.positionals[0] ?? args.dir;\n if (targetDir === undefined) {\n throw new CliError('create requires a target directory.', {\n suggestion: 'Usage: streetui create <dir> [--template basic|ssr]',\n });\n }\n await createProject({\n targetDir,\n ...(args.template !== undefined ? { template: args.template } : {}),\n frameworkVersion: CLI_VERSION,\n logger,\n });\n return { exitCode: 0 };\n }\n\n case 'build': {\n const project = await resolveProject(projectCwd, { requireEntry: true });\n const out = await buildProject(project, 'production');\n logger.success(`Build complete → ${out.clientDir}`);\n return { exitCode: 0 };\n }\n\n case 'dev': {\n const project = await resolveProject(projectCwd, { requireEntry: true });\n const server = await runDev({\n project,\n logger,\n ...(args.host !== undefined ? { host: args.host } : {}),\n ...(args.port !== undefined ? { port: args.port } : {}),\n });\n if (returnServer) return { exitCode: 0, server };\n await blockForever();\n return { exitCode: 0 };\n }\n\n case 'start': {\n const project = await resolveProject(projectCwd);\n const running = await runStart({\n project,\n logger,\n ...(args.host !== undefined ? { host: args.host } : {}),\n ...(args.port !== undefined ? { port: args.port } : {}),\n });\n if (returnServer) return { exitCode: 0, server: { url: running.url, stop: running.close } };\n await blockForever();\n return { exitCode: 0 };\n }\n\n default:\n throw new CliError(`Unknown command \"${args.command}\".`, {\n suggestion: 'Run \"streetui --help\" to see available commands.',\n });\n }\n}\n\n/** Keep the process alive for long-running commands until interrupted. */\nfunction blockForever(): Promise<never> {\n return new Promise<never>(() => {\n /* resolved only by process termination */\n });\n}\n","#!/usr/bin/env node\n/**\n * The `streetui` executable.\n *\n * StreetUI ships a single CLI as part of the one `streetui` package: `streetui\n * create | dev | build | start`, plus `--help` / `--version`. This is a thin\n * shim over the already-implemented CLI (`runCli`); all logic lives there. The\n * CLI implementation is bundled into this package, so users never install a\n * separate `@streetui/cli`.\n */\nimport { runCli } from '@streetui/cli';\n\nrunCli(process.argv.slice(2))\n .then((result) => {\n if (result.exitCode !== 0) process.exitCode = result.exitCode;\n })\n .catch((err: unknown) => {\n // Last-resort guard; runCli already handles expected errors.\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n });\n"],"mappings":"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","names":["existsSync","resolve","join","join","existsSync","resolve","esbuildBuild","rm","existsSync","join","join","rm","esbuildBuild","existsSync","cp","mkdir","rm","existsSync","join","join","isAbsolute","pathToFileURL","join","rm","mkdir","existsSync","cp","existsSync","join","join","existsSync","mkdir","readFile","writeFile","stat","existsSync","join","resolve","existsSync","dirname","join","resolve","existsSync","mkdir","join","stat","readFile","writeFile","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../../cli/src/args.ts","../../cli/src/logger.ts","../../cli/src/diagnostics.ts","../../cli/src/project.ts","../../cli/src/config.ts","../../cli/src/build.ts","../../cli/src/env.ts","../../cli/src/dev.ts","../../cli/src/serve.ts","../../cli/src/start.ts","../../cli/src/create.ts","../../cli/src/templates.ts","../../cli/src/index.ts","../src/bin.ts"],"sourcesContent":["/**\n * A tiny, dependency-free argument parser tailored to the StreetUI CLI.\n *\n * It intentionally supports only what the CLI actually uses — a leading command\n * word, positional arguments, boolean flags, and a handful of value options\n * (`--port`, `--host`, `--template`, `--dir`). Unknown flags are collected so a\n * command can reject them with a useful message rather than silently ignoring\n * them (Phase 14: no options that are ignored).\n */\n\nexport interface ParsedArgs {\n /** The command word, e.g. `create` / `dev` / `build` / `start`. */\n readonly command: string | undefined;\n /** Positional arguments after the command (e.g. the project name). */\n readonly positionals: readonly string[];\n /** `--help` / `-h` anywhere. */\n readonly help: boolean;\n /** `--version` / `-v` anywhere. */\n readonly version: boolean;\n /** `--port <n>` (validated as an integer, else `undefined`). */\n readonly port: number | undefined;\n /** `--host <h>`. */\n readonly host: string | undefined;\n /** `--template <name>` (project template for `create`). */\n readonly template: string | undefined;\n /** `--dir <path>` project directory override. */\n readonly dir: string | undefined;\n /** Any flags we do not recognise, reported verbatim (without leading `--`). */\n readonly unknown: readonly string[];\n}\n\nconst VALUE_FLAGS = new Set(['port', 'host', 'template', 'dir']);\nconst BOOLEAN_FLAGS = new Set(['help', 'version']);\nconst SHORT: Record<string, string> = { h: 'help', v: 'version', p: 'port' };\n\n/** Parse `process.argv.slice(2)`-style tokens into a `ParsedArgs`. */\nexport function parseArgs(argv: readonly string[]): ParsedArgs {\n let command: string | undefined;\n const positionals: string[] = [];\n const unknown: string[] = [];\n let help = false;\n let version = false;\n let port: number | undefined;\n let host: string | undefined;\n let template: string | undefined;\n let dir: string | undefined;\n\n for (let i = 0; i < argv.length; i++) {\n const token = argv[i];\n if (token === undefined) continue;\n\n if (token.startsWith('--') || (token.startsWith('-') && token.length > 1 && !/^-\\d/.test(token))) {\n // Normalise `--name=value` and short flags to a long flag name + value.\n const isLong = token.startsWith('--');\n const raw = isLong ? token.slice(2) : token.slice(1);\n const eq = raw.indexOf('=');\n let name = eq >= 0 ? raw.slice(0, eq) : raw;\n let inlineValue: string | undefined = eq >= 0 ? raw.slice(eq + 1) : undefined;\n if (!isLong) name = SHORT[name] ?? name;\n\n if (BOOLEAN_FLAGS.has(name)) {\n if (name === 'help') help = true;\n else if (name === 'version') version = true;\n continue;\n }\n\n if (VALUE_FLAGS.has(name)) {\n const value = inlineValue ?? argv[++i];\n if (value === undefined) {\n unknown.push(`${name} (missing value)`);\n continue;\n }\n if (name === 'port') {\n const n = Number.parseInt(value, 10);\n port = Number.isFinite(n) && n > 0 ? n : undefined;\n if (port === undefined) unknown.push(`port (invalid: ${value})`);\n } else if (name === 'host') host = value;\n else if (name === 'template') template = value;\n else if (name === 'dir') dir = value;\n continue;\n }\n\n unknown.push(name);\n // A stray `--flag value` shouldn't swallow the value as a positional\n // silently; but we also don't know it takes a value, so leave `value`.\n inlineValue = undefined;\n continue;\n }\n\n if (command === undefined) command = token;\n else positionals.push(token);\n }\n\n return { command, positionals, help, version, port, host, template, dir, unknown };\n}\n","/**\n * Minimal ANSI logger — no third-party colour dependency. Colours are disabled\n * automatically when output is not a TTY or when `NO_COLOR` is set, so piped and\n * CI output stays clean.\n */\n\n/* eslint-disable no-console */\n\nconst useColor =\n process.env['NO_COLOR'] === undefined &&\n process.env['FORCE_COLOR'] !== '0' &&\n (process.stdout.isTTY === true || process.env['FORCE_COLOR'] !== undefined);\n\nfunction paint(code: number, text: string): string {\n return useColor ? `\u001b[${code}m${text}\u001b[0m` : text;\n}\n\nexport const style = {\n bold: (t: string): string => paint(1, t),\n dim: (t: string): string => paint(2, t),\n red: (t: string): string => paint(31, t),\n green: (t: string): string => paint(32, t),\n yellow: (t: string): string => paint(33, t),\n blue: (t: string): string => paint(34, t),\n cyan: (t: string): string => paint(36, t),\n};\n\nconst BRAND = style.bold(style.cyan('streetui'));\n\nexport interface Logger {\n info(message: string): void;\n success(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n plain(message: string): void;\n}\n\n/** The default logger writes to stdout/stderr with a `streetui` prefix. */\nexport function createLogger(prefix = BRAND): Logger {\n return {\n info: (m) => console.log(`${prefix} ${m}`),\n success: (m) => console.log(`${prefix} ${style.green(m)}`),\n warn: (m) => console.warn(`${prefix} ${style.yellow(m)}`),\n error: (m) => console.error(`${prefix} ${style.red(m)}`),\n plain: (m) => console.log(m),\n };\n}\n","/**\n * Developer-facing diagnostics. Two rules govern everything here (Phase 6, 19,\n * 22): be USEFUL and be TRUTHFUL. We only print a source position when the\n * underlying tool (esbuild / Node) actually gives us one, and we never dress up\n * a failure as anything other than what it is.\n */\n\nimport { style } from './logger.js';\n\n/**\n * A CLI-level error carrying a human-readable explanation and, optionally, a\n * concrete suggestion. Throwing this (instead of a bare `Error`) lets the top\n * level render a clean message rather than a raw stack trace for expected\n * user mistakes (Phase 17).\n */\nexport class CliError extends Error {\n readonly suggestion: string | undefined;\n /** Process exit code to use when this error reaches the top level. */\n readonly exitCode: number;\n\n constructor(message: string, options?: { suggestion?: string; exitCode?: number }) {\n super(message);\n this.name = 'CliError';\n this.suggestion = options?.suggestion;\n this.exitCode = options?.exitCode ?? 1;\n }\n}\n\n/** A single build problem with an optional, real source location. */\nexport interface BuildProblem {\n readonly message: string;\n /** File path, when the tool reported one. */\n readonly file?: string;\n /** 1-based line, when known. */\n readonly line?: number;\n /** 1-based column, when known. */\n readonly column?: number;\n /** The offending source line, when the tool provided it. */\n readonly lineText?: string;\n /** A concrete suggestion, when we can infer one honestly. */\n readonly suggestion?: string;\n}\n\n/** Known StreetUI API names, used only to suggest fixes for obvious typos. */\nconst KNOWN_DSL_METHODS = [\n 'app', 'page', 'section', 'container', 'heading', 'text', 'button', 'link',\n 'input', 'form', 'list', 'listOf', 'when', 'errorBoundary',\n];\n\n/**\n * Turn an esbuild message into a `BuildProblem`, preserving the real location\n * esbuild computed. If esbuild could not determine a location, none is invented.\n */\nexport function fromEsbuildMessage(msg: {\n text: string;\n location: { file: string; line: number; column: number; lineText: string } | null;\n}): BuildProblem {\n const problem: BuildProblem = { message: msg.text };\n const loc = msg.location;\n if (loc === null) return withSuggestion(problem);\n return withSuggestion({\n message: msg.text,\n file: loc.file,\n line: loc.line,\n column: loc.column + 1, // esbuild columns are 0-based; humans count from 1.\n lineText: loc.lineText,\n });\n}\n\nfunction withSuggestion(problem: BuildProblem): BuildProblem {\n // Only attach a suggestion when we can make a truthful, specific one.\n const unknownApi = /Property '(\\w+)' does not exist|'(\\w+)' is not a function/.exec(problem.message);\n const missingModule = /Could not resolve [\"']([^\"']+)[\"']/.exec(problem.message);\n\n if (missingModule) {\n const spec = missingModule[1] ?? '';\n if (spec.startsWith('@streetui/')) {\n return {\n ...problem,\n suggestion: `Install the StreetUI packages (run \"npm install\") — \"${spec}\" is not resolvable yet.`,\n };\n }\n return { ...problem, suggestion: `Check the import path \"${spec}\" — the file or package could not be found.` };\n }\n\n if (unknownApi) {\n const name = unknownApi[1] ?? unknownApi[2] ?? '';\n const near = KNOWN_DSL_METHODS.find((m) => m.toLowerCase() === name.toLowerCase() && m !== name)\n ?? KNOWN_DSL_METHODS.find((m) => m.startsWith(name.slice(0, 3)));\n if (near !== undefined && name.length > 0) {\n return { ...problem, suggestion: `Did you mean \"${near}\"? Check the StreetUI DSL API.` };\n }\n }\n\n return problem;\n}\n\n/** Render one build problem as a readable multi-line block (Phase 6 shape). */\nexport function formatProblem(problem: BuildProblem): string {\n const lines: string[] = [];\n if (problem.file !== undefined) {\n const pos =\n problem.line !== undefined\n ? `:${problem.line}${problem.column !== undefined ? `:${problem.column}` : ''}`\n : '';\n lines.push(style.cyan(`${problem.file}${pos}`));\n }\n lines.push(problem.message);\n if (problem.lineText !== undefined && problem.lineText.trim().length > 0) {\n lines.push(style.dim(` | ${problem.lineText.trim()}`));\n }\n if (problem.suggestion !== undefined) {\n lines.push('');\n lines.push(`${style.yellow('Suggestion:')} ${problem.suggestion}`);\n }\n return lines.join('\\n');\n}\n\n/** Render a full build failure with a StreetUI header and every problem. */\nexport function formatBuildFailure(problems: readonly BuildProblem[]): string {\n const header = style.red(style.bold('StreetUI build error'));\n const count = problems.length === 1 ? '1 error' : `${problems.length} errors`;\n const blocks = problems.map((p) => formatProblem(p)).join('\\n\\n');\n return `${header} (${count})\\n\\n${blocks}`;\n}\n","/**\n * Project resolution and validation (Phase 17). Before `dev`, `build`, or\n * `start` do any real work, we confirm the working directory actually looks\n * like a StreetUI project and fail with a clear, actionable message otherwise —\n * never a cryptic stack trace.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { resolve, join } from 'node:path';\nimport { CliError } from './diagnostics.js';\nimport { loadConfig, type ResolvedConfig } from './config.js';\n\n/** A validated StreetUI project ready for a command to act on. */\nexport interface ResolvedProject {\n /** Absolute project root. */\n readonly root: string;\n /** Parsed package.json. */\n readonly packageJson: PackageJson;\n /** Fully-resolved configuration (defaults applied). */\n readonly config: ResolvedConfig;\n}\n\ninterface PackageJson {\n readonly name?: string;\n readonly version?: string;\n readonly type?: string;\n readonly dependencies?: Record<string, string>;\n readonly devDependencies?: Record<string, string>;\n readonly scripts?: Record<string, string>;\n readonly [key: string]: unknown;\n}\n\nfunction readPackageJson(root: string): PackageJson {\n const pkgPath = join(root, 'package.json');\n if (!existsSync(pkgPath)) {\n throw new CliError(`No package.json found in ${root}.`, {\n suggestion: 'Run this command from the root of a StreetUI project, or create one with \"npm create streetui@latest\".',\n });\n }\n let raw: string;\n try {\n raw = readFileSync(pkgPath, 'utf8');\n } catch (err) {\n throw new CliError(`Could not read ${pkgPath}: ${(err as Error).message}`);\n }\n try {\n return JSON.parse(raw) as PackageJson;\n } catch (err) {\n throw new CliError(`package.json is not valid JSON: ${(err as Error).message}`, {\n suggestion: 'Fix the syntax error in package.json and try again.',\n });\n }\n}\n\n/** True when the package depends on any `@streetui/*` package. */\nfunction dependsOnStreetUI(pkg: PackageJson): boolean {\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n return Object.keys(deps).some((name) => name === 'streetui' || name.startsWith('@streetui/'));\n}\n\n/**\n * Resolve + validate the project rooted at `cwd` (or `--dir`). Throws a\n * `CliError` with a helpful suggestion for every failure mode Phase 17 lists:\n * missing package.json, not a StreetUI project, invalid config, missing entry.\n */\nexport async function resolveProject(cwd: string, options?: { requireEntry?: boolean }): Promise<ResolvedProject> {\n const root = resolve(cwd);\n const packageJson = readPackageJson(root);\n\n if (!dependsOnStreetUI(packageJson)) {\n throw new CliError(`${root} does not look like a StreetUI project.`, {\n suggestion: 'Its package.json declares no \"@streetui/*\" dependency. Create a project with \"npm create streetui@latest\".',\n });\n }\n\n let config: ResolvedConfig;\n try {\n config = await loadConfig(root);\n } catch (err) {\n if (err instanceof CliError) throw err;\n throw new CliError(`Failed to load streetui.config: ${(err as Error).message}`, {\n suggestion: 'Check streetui.config.ts for syntax or import errors.',\n });\n }\n\n if (options?.requireEntry === true && !existsSync(config.clientEntry)) {\n throw new CliError(`Client entry not found: ${config.clientEntry}`, {\n suggestion: 'Create the entry file, or set \"clientEntry\" in streetui.config.ts to point at your app entry.',\n });\n }\n\n return { root, packageJson, config };\n}\n","/**\n * StreetUI project configuration (Phase 9). The config is intentionally tiny:\n * every field has a sensible default so `streetui.config.ts` is optional. A\n * project with no config file still builds and runs.\n *\n * The file is authored as TypeScript (`streetui.config.ts`) and compiled with\n * esbuild to a temporary ESM module before import, so we never depend on the\n * host having a TS loader registered.\n */\n\nimport { build as esbuildBuild } from 'esbuild';\nimport { rm, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve, isAbsolute } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\n/** User-facing configuration shape (all fields optional). */\nexport interface StreetUIConfig {\n /** Dev server / preview port. Default 3000. */\n readonly port?: number;\n /** Host to bind. Default 'localhost'. */\n readonly host?: string;\n /** Client/browser entry, relative to project root. Default 'src/main.ts'. */\n readonly clientEntry?: string;\n /** Server entry used for SSR, relative to project root. Default 'src/server.ts'. */\n readonly serverEntry?: string;\n /** Output directory for `build`. Default 'dist'. */\n readonly outDir?: string;\n /** Static assets directory copied verbatim. Default 'public'. */\n readonly publicDir?: string;\n}\n\n/** Fully-resolved config: every field present, all paths absolute. */\nexport interface ResolvedConfig {\n readonly root: string;\n readonly port: number;\n readonly host: string;\n readonly clientEntry: string;\n readonly serverEntry: string;\n readonly outDir: string;\n readonly publicDir: string;\n}\n\n/**\n * Identity helper that gives config authors type-checking and autocomplete.\n * It returns its argument unchanged — the value matters, not the call.\n */\nexport function defineConfig(config: StreetUIConfig): StreetUIConfig {\n return config;\n}\n\nconst DEFAULTS = {\n port: 3000,\n host: 'localhost',\n clientEntry: 'src/main.ts',\n serverEntry: 'src/server.ts',\n outDir: 'dist',\n publicDir: 'public',\n} as const;\n\n/** Config file names we look for, in priority order. */\nconst CONFIG_FILENAMES = ['streetui.config.ts', 'streetui.config.mjs', 'streetui.config.js'];\n\n/** Absolute path of the first config file present in `root`, or undefined. */\nexport function findConfigFile(root: string): string | undefined {\n for (const name of CONFIG_FILENAMES) {\n const candidate = join(root, name);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n\n/** Compile + import a `streetui.config.*` file and return its default export. */\nasync function importConfigFile(file: string): Promise<StreetUIConfig> {\n // `.js`/`.mjs` can be imported directly; `.ts` is compiled first.\n if (!file.endsWith('.ts')) {\n const mod = (await import(pathToFileURL(file).href)) as { default?: StreetUIConfig };\n return mod.default ?? {};\n }\n\n const result = await esbuildBuild({\n entryPoints: [file],\n bundle: true,\n write: false,\n format: 'esm',\n platform: 'node',\n // Keep node builtins and any deps external — we only want the config value.\n packages: 'external',\n logLevel: 'silent',\n });\n const code = result.outputFiles[0]?.text ?? '';\n\n // Write the compiled module *next to the config file* (not the OS temp dir)\n // so that any bare imports it kept external — e.g. `@streetui/cli` for\n // `defineConfig` — resolve against the project's own `node_modules`. A temp\n // file in the system temp directory would have no node_modules to walk up to.\n const outFile = join(dirname(file), `.streetui.config.${Date.now()}.mjs`);\n try {\n await writeFile(outFile, code, 'utf8');\n const mod = (await import(pathToFileURL(outFile).href)) as {\n default?: StreetUIConfig;\n };\n return mod.default ?? {};\n } finally {\n await rm(outFile, { force: true });\n }\n}\n\nfunction toAbsolute(root: string, p: string): string {\n return isAbsolute(p) ? p : resolve(root, p);\n}\n\n/**\n * Load and fully resolve configuration for the project rooted at `root`.\n * Missing config file → all defaults. Every returned path is absolute.\n */\nexport async function loadConfig(root: string): Promise<ResolvedConfig> {\n const absRoot = resolve(root);\n const file = findConfigFile(absRoot);\n const user = file ? await importConfigFile(file) : {};\n\n return {\n root: absRoot,\n port: user.port ?? DEFAULTS.port,\n host: user.host ?? DEFAULTS.host,\n clientEntry: toAbsolute(absRoot, user.clientEntry ?? DEFAULTS.clientEntry),\n serverEntry: toAbsolute(absRoot, user.serverEntry ?? DEFAULTS.serverEntry),\n outDir: toAbsolute(absRoot, user.outDir ?? DEFAULTS.outDir),\n publicDir: toAbsolute(absRoot, user.publicDir ?? DEFAULTS.publicDir),\n };\n}\n","/**\n * Production build (Phase 7). Two esbuild passes over the project's real\n * entries — a browser bundle for hydration and a Node bundle for SSR — plus a\n * copy of the public directory. No separate production rendering system: the\n * same DSL → compile → renderer pipeline the app already uses is bundled as-is.\n */\n\nimport { build as esbuildBuild, type BuildOptions, type Message } from 'esbuild';\nimport { cp, mkdir, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedProject } from './project.js';\nimport { fromEsbuildMessage, formatBuildFailure, CliError, type BuildProblem } from './diagnostics.js';\nimport { clientEnvDefine } from './env.js';\n\n/** Where each artifact lands under the configured `outDir`. */\nexport interface BuildOutput {\n readonly clientDir: string;\n readonly serverDir: string;\n readonly clientBundle: string;\n readonly serverBundle: string;\n}\n\n/** Convert esbuild's error array into our problem shape, preserving locations. */\nfunction toProblems(messages: readonly Message[]): BuildProblem[] {\n return messages.map((m) => fromEsbuildMessage({ text: m.text, location: m.location }));\n}\n\n/** Shared esbuild options for both passes. */\nfunction baseOptions(mode: 'development' | 'production'): BuildOptions {\n return {\n bundle: true,\n format: 'esm',\n sourcemap: true,\n logLevel: 'silent',\n define: {\n // Public build-time constants. Server secrets are never injected here.\n 'process.env.NODE_ENV': JSON.stringify(mode),\n },\n minify: mode === 'production',\n };\n}\n\n/**\n * Run the production build for `project`. Returns the output layout on success;\n * throws a `CliError` carrying formatted diagnostics on failure. When\n * `serverEntry` is absent the server pass is skipped (client-only project).\n */\nexport async function buildProject(\n project: ResolvedProject,\n mode: 'development' | 'production' = 'production',\n): Promise<BuildOutput> {\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverDir = join(config.outDir, 'server');\n\n await rm(config.outDir, { recursive: true, force: true });\n await mkdir(clientDir, { recursive: true });\n\n // Only errors are fatal. esbuild throws (rejects) when a pass has errors, so\n // the catch branch is the sole source of build-breaking problems. Warnings —\n // including exports-ordering notes emitted for third-party dependency\n // package.json files — must never fail a production build.\n const errors: BuildProblem[] = [];\n\n // Client (browser) pass — always required.\n await esbuildBuild({\n ...baseOptions(mode),\n entryPoints: [config.clientEntry],\n outfile: join(clientDir, 'main.js'),\n platform: 'browser',\n target: ['es2022'],\n // Only STREETUI_PUBLIC_* env vars reach the browser (plus NODE_ENV).\n define: clientEnvDefine(mode),\n }).catch((err: { errors?: Message[] }) => {\n errors.push(...toProblems(err.errors ?? []));\n return undefined;\n });\n\n // Server (node) pass — only when a server entry exists.\n const hasServerEntry = existsSync(config.serverEntry);\n if (hasServerEntry) {\n await mkdir(serverDir, { recursive: true });\n await esbuildBuild({\n ...baseOptions(mode),\n entryPoints: [config.serverEntry],\n outfile: join(serverDir, 'server.js'),\n platform: 'node',\n target: ['node18'],\n packages: 'external',\n }).catch((err: { errors?: Message[] }) => {\n errors.push(...toProblems(err.errors ?? []));\n return undefined;\n });\n }\n\n if (errors.length > 0) {\n throw new CliError(formatBuildFailure(errors), { exitCode: 1 });\n }\n\n // Copy static assets into the client output so they ship together.\n if (existsSync(config.publicDir)) {\n await cp(config.publicDir, clientDir, { recursive: true });\n }\n\n return {\n clientDir,\n serverDir,\n clientBundle: join(clientDir, 'main.js'),\n serverBundle: join(serverDir, 'server.js'),\n };\n}\n","/**\n * Environment variables (Phase 10). The rule is simple and safe by default:\n * only variables whose names begin with `STREETUI_PUBLIC_` are exposed to the\n * browser bundle. Everything else stays on the server, so secrets in the\n * process environment cannot leak into client-side JavaScript.\n *\n * `NODE_ENV` is always defined (as the build mode) so app code can branch on\n * development vs production.\n */\n\n/** Prefix that marks an env var as safe to ship to the browser. */\nexport const PUBLIC_ENV_PREFIX = 'STREETUI_PUBLIC_';\n\n/**\n * Build the esbuild `define` map for the CLIENT bundle: `NODE_ENV` plus every\n * `STREETUI_PUBLIC_*` variable, each stringified as a compile-time constant.\n * Server-only variables are deliberately excluded.\n */\nexport function clientEnvDefine(\n mode: 'development' | 'production',\n env: NodeJS.ProcessEnv = process.env,\n): Record<string, string> {\n const define: Record<string, string> = {\n 'process.env.NODE_ENV': JSON.stringify(mode),\n };\n for (const [key, value] of Object.entries(env)) {\n if (key.startsWith(PUBLIC_ENV_PREFIX) && value !== undefined) {\n define[`process.env.${key}`] = JSON.stringify(value);\n }\n }\n return define;\n}\n\n/** Names of the public variables currently visible (for logging/diagnostics). */\nexport function publicEnvNames(env: NodeJS.ProcessEnv = process.env): string[] {\n return Object.keys(env).filter((k) => k.startsWith(PUBLIC_ENV_PREFIX));\n}\n","/**\n * `streetui dev` (Phase 5). Builds the project once, then watches for changes\n * with esbuild's incremental context API and rebuilds only what changed —\n * avoiding a full cold build per keystroke (Phase 27). On each successful\n * rebuild connected browsers are told to reload; build errors are printed with\n * real source positions and never crash the server.\n */\n\nimport { context, type BuildContext, type BuildOptions, type Message } from 'esbuild';\nimport { cp, mkdir, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Logger } from './logger.js';\nimport type { ResolvedProject } from './project.js';\nimport { startServer, ReloadHub, type RunningServer } from './serve.js';\nimport { fromEsbuildMessage, formatBuildFailure } from './diagnostics.js';\nimport { clientEnvDefine } from './env.js';\n\nexport interface DevOptions {\n readonly project: ResolvedProject;\n readonly logger: Logger;\n readonly host?: string;\n readonly port?: number;\n}\n\n/** Handle returned so callers (and tests) can shut the dev server down. */\nexport interface DevServer {\n readonly url: string;\n stop(): Promise<void>;\n}\n\n/** Report esbuild results to the logger and reload browsers when clean. */\nfunction reportResult(\n label: string,\n errors: readonly Message[],\n logger: Logger,\n reload: ReloadHub,\n): void {\n if (errors.length > 0) {\n const problems = errors.map((m) => fromEsbuildMessage({ text: m.text, location: m.location }));\n logger.error(`${label} rebuild failed:`);\n logger.plain(formatBuildFailure(problems));\n return;\n }\n reload.triggerReload();\n}\n\n/** Start the dev server. Resolves once it is listening; keep the handle to stop. */\nexport async function runDev(options: DevOptions): Promise<DevServer> {\n const { project, logger } = options;\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverDir = join(config.outDir, 'server');\n const serverBundle = join(serverDir, 'server.js');\n const reload = new ReloadHub();\n\n await rm(config.outDir, { recursive: true, force: true });\n await mkdir(clientDir, { recursive: true });\n await mkdir(serverDir, { recursive: true });\n\n const shared: BuildOptions = {\n bundle: true,\n format: 'esm',\n sourcemap: true,\n logLevel: 'silent',\n define: { 'process.env.NODE_ENV': JSON.stringify('development') },\n };\n\n const contexts: BuildContext[] = [];\n\n const clientCtx = await context({\n ...shared,\n entryPoints: [config.clientEntry],\n outfile: join(clientDir, 'main.js'),\n platform: 'browser',\n target: ['es2022'],\n define: clientEnvDefine('development'),\n plugins: [\n {\n name: 'streetui-client-reload',\n setup(builder) {\n builder.onEnd((result) => reportResult('Client', result.errors, logger, reload));\n },\n },\n ],\n });\n contexts.push(clientCtx);\n\n const hasServerEntry = existsSync(config.serverEntry);\n if (hasServerEntry) {\n const serverCtx = await context({\n ...shared,\n entryPoints: [config.serverEntry],\n outfile: serverBundle,\n platform: 'node',\n target: ['node18'],\n packages: 'external',\n plugins: [\n {\n name: 'streetui-server-reload',\n setup(builder) {\n builder.onEnd((result) => {\n if (result.errors.length > 0) {\n reportResult('Server', result.errors, logger, reload);\n }\n });\n },\n },\n ],\n });\n contexts.push(serverCtx);\n }\n\n // Initial build for every context, then enable watch mode.\n await Promise.all(contexts.map((c) => c.rebuild().catch(() => undefined)));\n await Promise.all(contexts.map((c) => c.watch()));\n\n if (existsSync(config.publicDir)) {\n await cp(config.publicDir, clientDir, { recursive: true });\n }\n\n const host = options.host ?? config.host;\n const port = options.port ?? config.port;\n\n let running: RunningServer | undefined;\n if (hasServerEntry) {\n running = await startServer({ clientDir, serverBundle, host, port, reload, devMode: true });\n logger.success(`Dev server running at ${running.url}`);\n logger.info('Watching for changes… (press Ctrl+C to stop)');\n } else {\n logger.warn('No server entry found — client bundle is being watched, but no dev server was started.');\n }\n\n const url = running?.url ?? `http://${host}:${port}`;\n return {\n url,\n stop: async () => {\n await Promise.all(contexts.map((c) => c.dispose()));\n await running?.close();\n },\n };\n}\n","/**\n * The StreetUI HTTP server (Phases 5 & 8). Built on Node's standard `node:http`\n * — no Express, no third-party server. It serves the built client assets as\n * static files and delegates every other request to the project's server\n * bundle, which exports a `render(request)` function producing full HTML.\n *\n * The same server backs both `dev` (with live-reload injection) and `start`\n * (production). Dev-only behaviour is gated behind the `reload` option.\n */\n\nimport { createServer as createHttpServer, type IncomingMessage, type ServerResponse, type Server } from 'node:http';\nimport { readFile, stat } from 'node:fs/promises';\nimport { join, normalize, extname, relative, isAbsolute } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\n/** The contract a project's server entry must satisfy. */\nexport interface RenderRequest {\n readonly url: string;\n readonly method: string;\n readonly headers: Record<string, string | string[] | undefined>;\n}\nexport interface RenderResult {\n readonly html: string;\n readonly status?: number;\n readonly headers?: Record<string, string>;\n}\nexport type RenderFn = (request: RenderRequest) => RenderResult | Promise<RenderResult>;\n\nexport interface ServeOptions {\n readonly clientDir: string;\n readonly serverBundle: string;\n readonly host: string;\n readonly port: number;\n /** When set, HTML responses get a live-reload snippet + an SSE endpoint. */\n readonly reload?: ReloadHub;\n /**\n * Dev mode: re-import the server bundle on every request so edits are picked\n * up without restarting. In production the bundle is loaded once.\n */\n readonly devMode?: boolean;\n}\n\n/** A running server plus the resolved address and a stop handle. */\nexport interface RunningServer {\n readonly server: Server;\n readonly url: string;\n close(): Promise<void>;\n}\n\nconst MIME: Record<string, string> = {\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.html': 'text/html; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\n/** Live-reload coordination for dev: tracks SSE clients and pushes events. */\nexport class ReloadHub {\n private readonly clients = new Set<ServerResponse>();\n static readonly PATH = '/__streetui_reload';\n\n /** The snippet injected before `</body>` so the page listens for reloads. */\n static readonly snippet =\n `<script>(function(){try{new EventSource(\"${ReloadHub.PATH}\").onmessage=function(e){if(e.data===\"reload\")location.reload()}}catch(_){}})();</script>`;\n\n handle(_req: IncomingMessage, res: ServerResponse): void {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n res.write(': connected\\n\\n');\n this.clients.add(res);\n res.on('close', () => this.clients.delete(res));\n }\n\n /** Tell every connected browser to reload. */\n triggerReload(): void {\n for (const res of this.clients) res.write('data: reload\\n\\n');\n }\n\n closeAll(): void {\n for (const res of this.clients) res.end();\n this.clients.clear();\n }\n}\n\n/**\n * Resolve a URL path to a file inside `clientDir`, guarding against escapes.\n *\n * Security notes (production hardening, v0.8):\n * - Malformed percent-encoding (`decodeURIComponent` throwing) is rejected\n * rather than allowed to bubble up as a 500.\n * - Null-byte injection (`\\0`) is rejected — it can truncate paths in some\n * syscalls.\n * - Containment is verified with `path.relative`, NOT a raw `startsWith`\n * prefix check: a prefix check treats a sibling dir like `<clientDir>-x` as\n * \"inside\" and is a real traversal hole. `relative` yields a `..`-leading or\n * absolute path exactly when the target escapes the root.\n */\nfunction resolveStatic(clientDir: string, urlPath: string): string | undefined {\n let decoded: string;\n try {\n decoded = decodeURIComponent(urlPath.split('?')[0] ?? '');\n } catch {\n return undefined; // malformed percent-encoding\n }\n if (decoded.includes('\\0')) return undefined; // null-byte injection\n const clean = normalize(decoded).replace(/^(\\.\\.[/\\\\])+/, '');\n const full = join(clientDir, clean);\n const rel = relative(clientDir, full);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) return full;\n return undefined; // escaped the client root\n}\n\nasync function tryServeStatic(\n clientDir: string,\n urlPath: string,\n res: ServerResponse,\n devMode: boolean,\n): Promise<boolean> {\n const full = resolveStatic(clientDir, urlPath);\n if (full === undefined) return false;\n try {\n const info = await stat(full);\n if (!info.isFile()) return false;\n const body = await readFile(full);\n res.writeHead(200, {\n 'Content-Type': MIME[extname(full)] ?? 'application/octet-stream',\n // Never let a browser MIME-sniff a served asset into something executable.\n 'X-Content-Type-Options': 'nosniff',\n // Dev must always re-fetch; production may cache immutable build output.\n 'Cache-Control': devMode ? 'no-cache' : 'public, max-age=3600',\n });\n res.end(body);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Import the built server bundle and return its `render` export. */\nasync function loadRender(serverBundle: string): Promise<RenderFn> {\n const mod = (await import(`${pathToFileURL(serverBundle).href}?t=${Date.now()}`)) as {\n render?: RenderFn;\n default?: RenderFn | { render?: RenderFn };\n };\n const candidate =\n mod.render ??\n (typeof mod.default === 'function' ? mod.default : mod.default?.render);\n if (typeof candidate !== 'function') {\n throw new Error(`Server entry ${serverBundle} must export a \"render(request)\" function.`);\n }\n return candidate;\n}\n\nfunction injectReload(html: string): string {\n if (html.includes('</body>')) return html.replace('</body>', `${ReloadHub.snippet}</body>`);\n return html + ReloadHub.snippet;\n}\n\n/** Start the HTTP server and resolve once it is actually listening. */\nexport async function startServer(options: ServeOptions): Promise<RunningServer> {\n // In production, load the render function once. In dev, load per request so\n // rebuilt bundles are picked up (loadRender cache-busts the import URL).\n let cachedRender: RenderFn | undefined;\n const getRender = async (): Promise<RenderFn> => {\n if (options.devMode === true) return loadRender(options.serverBundle);\n if (cachedRender === undefined) cachedRender = await loadRender(options.serverBundle);\n return cachedRender;\n };\n // Fail fast on a broken bundle before we start listening.\n await getRender();\n\n const server = createHttpServer((req, res) => {\n void handleRequest(req, res, getRender, options);\n });\n\n await new Promise<void>((resolvePromise, reject) => {\n server.once('error', reject);\n server.listen(options.port, options.host, () => {\n server.off('error', reject);\n resolvePromise();\n });\n });\n\n const url = `http://${options.host}:${options.port}`;\n return {\n server,\n url,\n close: () =>\n new Promise<void>((resolveClose) => {\n options.reload?.closeAll();\n server.close(() => resolveClose());\n }),\n };\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n getRender: () => Promise<RenderFn>,\n options: ServeOptions,\n): Promise<void> {\n const url = req.url ?? '/';\n\n // Dev live-reload channel.\n if (options.reload && url === ReloadHub.PATH) {\n options.reload.handle(req, res);\n return;\n }\n\n // Static assets first (only paths with an extension, so routes fall through).\n if (extname(url.split('?')[0] ?? '') !== '') {\n const served = await tryServeStatic(options.clientDir, url, res, options.devMode === true);\n if (served) return;\n }\n\n // Otherwise, server-render the requested route.\n try {\n const render = await getRender();\n const result = await render({\n url,\n method: req.method ?? 'GET',\n headers: req.headers,\n });\n const status = result.status ?? 200;\n const html = options.reload ? injectReload(result.html) : result.html;\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8', ...result.headers });\n res.end(html);\n } catch (err) {\n // Always surface the failure server-side for operators.\n // eslint-disable-next-line no-console\n console.error(`[StreetUI] render error for ${url}:`, err);\n // But only leak stack traces / internal detail in dev. A production server\n // must not disclose stacks, file paths or env-derived strings to clients\n // (information-disclosure hardening, v0.8 §18/§19).\n res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });\n if (options.devMode === true) {\n const message = err instanceof Error ? err.stack ?? err.message : String(err);\n res.end(`StreetUI server error while rendering ${url}:\\n\\n${message}`);\n } else {\n res.end('Internal Server Error');\n }\n }\n}\n","/**\n * `streetui start` (Phase 8). Serves an existing production build. If the build\n * output is missing we build it first, so `start` on a fresh checkout still\n * works. Uses the standard Node HTTP server from `serve.ts`.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Logger } from './logger.js';\nimport type { ResolvedProject } from './project.js';\nimport { buildProject } from './build.js';\nimport { startServer, type RunningServer } from './serve.js';\nimport { CliError } from './diagnostics.js';\n\nexport interface StartOptions {\n readonly project: ResolvedProject;\n readonly logger: Logger;\n /** Overrides for the configured host/port (from --host/--port). */\n readonly host?: string;\n readonly port?: number;\n}\n\n/** Build (if needed) and serve the production output. Resolves once listening. */\nexport async function runStart(options: StartOptions): Promise<RunningServer> {\n const { project, logger } = options;\n const { config } = project;\n const clientDir = join(config.outDir, 'client');\n const serverBundle = join(config.outDir, 'server', 'server.js');\n\n if (!existsSync(serverBundle)) {\n logger.info('No production build found — building first…');\n await buildProject(project, 'production');\n }\n if (!existsSync(serverBundle)) {\n throw new CliError('Production build did not produce a server bundle.', {\n suggestion: 'Ensure your project has a server entry (default src/server.ts) that exports render().',\n });\n }\n\n const host = options.host ?? config.host;\n const port = options.port ?? config.port;\n const running = await startServer({ clientDir, serverBundle, host, port });\n logger.success(`Production server running at ${running.url}`);\n return running;\n}\n","/**\n * `streetui create` / `npm create streetui` (Phase 3). Scaffolds a real,\n * working StreetUI project from a shipped template. No network access, no\n * post-install magic — just a recursive copy with placeholder substitution.\n */\n\nimport { mkdir, readdir, readFile, writeFile, stat } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join, resolve, basename } from 'node:path';\nimport type { Logger } from './logger.js';\nimport { CliError } from './diagnostics.js';\nimport {\n templateDir,\n resolveTemplateName,\n materialisedName,\n applyTokens,\n isTextFile,\n type TemplateName,\n type TemplateTokens,\n} from './templates.js';\n\nexport interface CreateOptions {\n /** Target directory (relative or absolute). */\n readonly targetDir: string;\n /** Template to use; defaults to the SSR starter. */\n readonly template?: string;\n /** StreetUI package version the generated project should depend on. */\n readonly frameworkVersion: string;\n readonly logger: Logger;\n}\n\nexport interface CreateResult {\n readonly root: string;\n readonly template: TemplateName;\n readonly files: readonly string[];\n}\n\n/** True when a directory is absent or empty (safe to scaffold into). */\nasync function isEmptyDir(dir: string): Promise<boolean> {\n if (!existsSync(dir)) return true;\n const entries = await readdir(dir);\n return entries.filter((e) => e !== '.git').length === 0;\n}\n\n/** Recursively copy a template directory, transforming names and tokens. */\nasync function copyTree(\n srcDir: string,\n destDir: string,\n tokens: TemplateTokens,\n written: string[],\n): Promise<void> {\n await mkdir(destDir, { recursive: true });\n const entries = await readdir(srcDir);\n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const info = await stat(srcPath);\n const destName = materialisedName(entry);\n const destPath = join(destDir, destName);\n if (info.isDirectory()) {\n await copyTree(srcPath, destPath, tokens, written);\n } else if (isTextFile(entry)) {\n const raw = await readFile(srcPath, 'utf8');\n await writeFile(destPath, applyTokens(raw, tokens), 'utf8');\n written.push(destPath);\n } else {\n const raw = await readFile(srcPath);\n await writeFile(destPath, raw);\n written.push(destPath);\n }\n }\n}\n\n/**\n * Scaffold a new project. Validates the template and the (empty) target, copies\n * the tree, and returns the created root + file list. Throws `CliError` on any\n * user-facing problem.\n */\nexport async function createProject(options: CreateOptions): Promise<CreateResult> {\n const { logger } = options;\n\n let template: TemplateName;\n try {\n template = resolveTemplateName(options.template);\n } catch (err) {\n throw new CliError((err as Error).message, { suggestion: 'Pass a valid --template value.' });\n }\n\n const root = resolve(options.targetDir);\n const projectName = basename(root);\n\n if (!(await isEmptyDir(root))) {\n throw new CliError(`Target directory ${root} already exists and is not empty.`, {\n suggestion: 'Choose a new directory name or empty the existing one.',\n });\n }\n\n const src = templateDir(template);\n if (!existsSync(src)) {\n throw new CliError(`Template \"${template}\" is missing from the CLI installation (${src}).`, {\n suggestion: 'Reinstall @streetui/cli — the shipped templates appear to be absent.',\n });\n }\n\n const tokens: TemplateTokens = { projectName, frameworkVersion: options.frameworkVersion };\n const files: string[] = [];\n await copyTree(src, root, tokens, files);\n\n logger.success(`Created ${projectName} (${template} template) with ${files.length} files.`);\n logger.plain('');\n logger.info('Next steps:');\n logger.plain(` cd ${options.targetDir}`);\n logger.plain(' npm install');\n logger.plain(' npm run dev');\n\n return { root, template, files };\n}\n","/**\n * Template registry (Phases 3, 11, 12). Templates are real files shipped inside\n * the CLI package under `templates/<name>/`. They are copied verbatim at\n * scaffold time, with two transforms: a small set of placeholder tokens are\n * substituted, and files prefixed `_` are un-prefixed (so `_gitignore` becomes\n * `.gitignore` and `_package.json` becomes `package.json` — npm would otherwise\n * mangle those names on publish).\n */\n\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Available starter templates. */\nexport type TemplateName = 'basic' | 'ssr';\n\nexport const TEMPLATES: readonly TemplateName[] = ['basic', 'ssr'];\nexport const DEFAULT_TEMPLATE: TemplateName = 'ssr';\n\n/** Tokens replaced in every text file of a template. */\nexport interface TemplateTokens {\n readonly projectName: string;\n readonly frameworkVersion: string;\n}\n\n/**\n * Files stored under a transformed name because npm would otherwise mangle them\n * on publish (it renames `.gitignore` and drops/collides on `package.json`). The\n * key is the shipped name; the value is what it becomes in the scaffolded app.\n */\nconst NAME_MAP: Record<string, string> = {\n '_gitignore': '.gitignore',\n '_npmrc': '.npmrc',\n '_package.json': 'package.json',\n};\n\n/** Absolute path to the shipped `templates/` directory. */\nexport function templatesRoot(): string {\n // dist/index.js (or the test-time src) lives one level below the package\n // root; templates/ sits beside dist/. Resolve relative to this module.\n const here = dirname(fileURLToPath(import.meta.url));\n // From dist/ or src/, go up to the package root, then into templates/.\n const candidates = [resolve(here, '..', 'templates'), resolve(here, '..', '..', 'templates')];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n // Fall back to the first candidate; callers surface a clear error if missing.\n return candidates[0] ?? resolve(here, '..', 'templates');\n}\n\n/** Absolute path to a specific template's source directory. */\nexport function templateDir(name: TemplateName): string {\n return join(templatesRoot(), name);\n}\n\n/** Validate a user-supplied template name, returning it typed or throwing. */\nexport function resolveTemplateName(name: string | undefined): TemplateName {\n if (name === undefined) return DEFAULT_TEMPLATE;\n if ((TEMPLATES as readonly string[]).includes(name)) return name as TemplateName;\n throw new Error(`Unknown template \"${name}\". Available: ${TEMPLATES.join(', ')}.`);\n}\n\n/** Map a template file name to its materialised name (see `NAME_MAP`). */\nexport function materialisedName(fileName: string): string {\n return NAME_MAP[fileName] ?? fileName;\n}\n\n/** Replace template tokens in a text file's contents. */\nexport function applyTokens(contents: string, tokens: TemplateTokens): string {\n return contents\n .replaceAll('__PROJECT_NAME__', tokens.projectName)\n .replaceAll('__FRAMEWORK_VERSION__', tokens.frameworkVersion);\n}\n\n/** File extensions treated as text (token substitution applies). */\nconst TEXT_EXTENSIONS = new Set([\n '.ts', '.tsx', '.js', '.mjs', '.cjs', '.json', '.css', '.html', '.md', '.txt', '.npmrc', '',\n]);\n\n/** Whether a file should be read as text for token substitution. */\nexport function isTextFile(fileName: string): boolean {\n const dot = fileName.lastIndexOf('.');\n const ext = dot >= 0 ? fileName.slice(dot) : '';\n // `_gitignore` / `_npmrc` have no dotted extension → treat as text.\n return TEXT_EXTENSIONS.has(ext);\n}\n","/**\n * `@streetui/cli` public entry. Exposes the programmatic API used by the\n * executables and the tests, and implements `runCli` — the command dispatcher\n * that turns argv into one of `create` / `dev` / `build` / `start` (plus\n * `--help` / `--version`). The CLI only orchestrates the existing StreetUI\n * pipeline; it is not a framework layer of its own.\n */\n\nimport { parseArgs, type ParsedArgs } from './args.js';\nimport { createLogger, type Logger } from './logger.js';\nimport { CliError } from './diagnostics.js';\nimport { resolveProject } from './project.js';\nimport { buildProject } from './build.js';\nimport { runDev } from './dev.js';\nimport { runStart } from './start.js';\nimport { createProject } from './create.js';\n\nexport { parseArgs } from './args.js';\nexport { defineConfig, loadConfig, findConfigFile } from './config.js';\nexport type { StreetUIConfig, ResolvedConfig } from './config.js';\nexport { clientEnvDefine, publicEnvNames, PUBLIC_ENV_PREFIX } from './env.js';\nexport { resolveProject } from './project.js';\nexport type { ResolvedProject } from './project.js';\nexport { buildProject } from './build.js';\nexport type { BuildOutput } from './build.js';\nexport { runDev } from './dev.js';\nexport type { DevServer } from './dev.js';\nexport { runStart } from './start.js';\nexport { createProject } from './create.js';\nexport type { CreateResult } from './create.js';\nexport { startServer, ReloadHub } from './serve.js';\nexport type { RenderRequest, RenderResult, RenderFn } from './serve.js';\nexport { CliError } from './diagnostics.js';\nexport { createLogger } from './logger.js';\nexport type { Logger } from './logger.js';\n\n/** The CLI version, read from the compiled package. Kept in one place. */\nexport const CLI_VERSION = '1.9.0';\n\n/** Options for `runCli`, all injectable so tests can drive it in-process. */\nexport interface RunCliOptions {\n /** Working directory the command acts on. Defaults to `process.cwd()`. */\n readonly cwd?: string;\n /** Logger sink. Defaults to the branded stdout logger. */\n readonly logger?: Logger;\n /**\n * When true, `dev` and `start` return their running handle instead of\n * blocking forever. Tests set this; the real binary leaves it false.\n */\n readonly returnServer?: boolean;\n}\n\n/** Result of a command: an exit code plus any long-lived handle for tests. */\nexport interface RunCliResult {\n readonly exitCode: number;\n readonly server?: { url: string; stop: () => Promise<void> };\n}\n\nconst HELP = `streetui — the StreetUI application CLI\n\nUsage:\n streetui <command> [options]\n\nCommands:\n create <dir> Scaffold a new StreetUI project\n dev Start the development server with live reload\n build Produce a production build (dist/client, dist/server)\n start Serve the production build\n\nOptions:\n -h, --help Show this help\n -v, --version Show the CLI version\n -p, --port <n> Port for dev/start (default 3000)\n --host <host> Host for dev/start (default localhost)\n --template <t> Template for create (basic | ssr)\n --dir <path> Project directory (default current directory)\n\nExamples:\n npm create streetui@latest my-app\n streetui dev --port 4000\n streetui build\n streetui start`;\n\n/** Dispatch a parsed command line. Never throws for expected errors — it maps\n * `CliError` to an exit code and a logged message instead. */\nexport async function runCli(argv: readonly string[], options: RunCliOptions = {}): Promise<RunCliResult> {\n const logger = options.logger ?? createLogger();\n const cwd = options.cwd ?? process.cwd();\n const args = parseArgs(argv);\n\n // Reject unknown flags before doing anything (Phase 14: no ignored options).\n if (args.unknown.length > 0) {\n logger.error(`Unknown or invalid option(s): ${args.unknown.join(', ')}`);\n logger.plain(HELP);\n return { exitCode: 1 };\n }\n\n if (args.version && args.command === undefined) {\n logger.plain(CLI_VERSION);\n return { exitCode: 0 };\n }\n if (args.help || args.command === undefined) {\n logger.plain(HELP);\n return { exitCode: args.command === undefined && !args.help ? 1 : 0 };\n }\n\n try {\n return await dispatch(args, cwd, logger, options.returnServer === true);\n } catch (err) {\n if (err instanceof CliError) {\n logger.error(err.message);\n if (err.suggestion !== undefined) logger.plain(err.suggestion);\n return { exitCode: err.exitCode };\n }\n logger.error(`Unexpected error: ${(err as Error).message}`);\n return { exitCode: 1 };\n }\n}\n\nasync function dispatch(\n args: ParsedArgs,\n cwd: string,\n logger: Logger,\n returnServer: boolean,\n): Promise<RunCliResult> {\n const projectCwd = args.dir ?? cwd;\n\n switch (args.command) {\n case 'create': {\n const targetDir = args.positionals[0] ?? args.dir;\n if (targetDir === undefined) {\n throw new CliError('create requires a target directory.', {\n suggestion: 'Usage: streetui create <dir> [--template basic|ssr]',\n });\n }\n await createProject({\n targetDir,\n ...(args.template !== undefined ? { template: args.template } : {}),\n frameworkVersion: CLI_VERSION,\n logger,\n });\n return { exitCode: 0 };\n }\n\n case 'build': {\n const project = await resolveProject(projectCwd, { requireEntry: true });\n const out = await buildProject(project, 'production');\n logger.success(`Build complete → ${out.clientDir}`);\n return { exitCode: 0 };\n }\n\n case 'dev': {\n const project = await resolveProject(projectCwd, { requireEntry: true });\n const server = await runDev({\n project,\n logger,\n ...(args.host !== undefined ? { host: args.host } : {}),\n ...(args.port !== undefined ? { port: args.port } : {}),\n });\n if (returnServer) return { exitCode: 0, server };\n await blockForever();\n return { exitCode: 0 };\n }\n\n case 'start': {\n const project = await resolveProject(projectCwd);\n const running = await runStart({\n project,\n logger,\n ...(args.host !== undefined ? { host: args.host } : {}),\n ...(args.port !== undefined ? { port: args.port } : {}),\n });\n if (returnServer) return { exitCode: 0, server: { url: running.url, stop: running.close } };\n await blockForever();\n return { exitCode: 0 };\n }\n\n default:\n throw new CliError(`Unknown command \"${args.command}\".`, {\n suggestion: 'Run \"streetui --help\" to see available commands.',\n });\n }\n}\n\n/** Keep the process alive for long-running commands until interrupted. */\nfunction blockForever(): Promise<never> {\n return new Promise<never>(() => {\n /* resolved only by process termination */\n });\n}\n","#!/usr/bin/env node\n/**\n * The `streetui` executable.\n *\n * StreetUI ships a single CLI as part of the one `streetui` package: `streetui\n * create | dev | build | start`, plus `--help` / `--version`. This is a thin\n * shim over the already-implemented CLI (`runCli`); all logic lives there. The\n * CLI implementation is bundled into this package, so users never install a\n * separate `@streetui/cli`.\n */\nimport { runCli } from '@streetui/cli';\n\nrunCli(process.argv.slice(2))\n .then((result) => {\n if (result.exitCode !== 0) process.exitCode = result.exitCode;\n })\n .catch((err: unknown) => {\n // Last-resort guard; runCli already handles expected errors.\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n });\n"],"mappings":"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","names":["existsSync","resolve","join","join","existsSync","resolve","esbuildBuild","rm","existsSync","join","join","rm","esbuildBuild","existsSync","cp","mkdir","rm","existsSync","join","join","isAbsolute","pathToFileURL","join","rm","mkdir","existsSync","cp","existsSync","join","join","existsSync","mkdir","readFile","writeFile","stat","existsSync","join","resolve","existsSync","dirname","join","resolve","existsSync","mkdir","join","stat","readFile","writeFile","resolve"]}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (`streetui --version`) — the consolidated test-suite pins all three to the
|
|
8
8
|
* same coordinated release so they can never silently drift apart.
|
|
9
9
|
*/
|
|
10
|
-
declare const VERSION = "1.
|
|
10
|
+
declare const VERSION = "1.9.0";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* StreetUI reactive signals — framework-owned reactivity, no external libraries.
|
|
@@ -446,6 +446,90 @@ declare function component<P = Record<string, never>>(setup: ComponentSetup<P>,
|
|
|
446
446
|
/** Runtime guard: is `value` a component definition? */
|
|
447
447
|
declare function isComponentDefinition(value: unknown): value is ComponentDefinition<unknown>;
|
|
448
448
|
|
|
449
|
+
/**
|
|
450
|
+
* Transition configuration (§2, §4).
|
|
451
|
+
*
|
|
452
|
+
* A `TransitionConfig` is a pure, declarative description of a CSS class-based
|
|
453
|
+
* enter/leave transition — the engine choice for this milestone. It contains NO
|
|
454
|
+
* DOM references, NO timers and NO browser-only APIs, so it is safe to build on
|
|
455
|
+
* the server (where it is simply ignored — see the renderer's SSR guard) and to
|
|
456
|
+
* carry on a graph handler (`__transition__<nodeId>`) alongside the existing
|
|
457
|
+
* `__overlay__`/`__component__` descriptors.
|
|
458
|
+
*
|
|
459
|
+
* The class model follows the widely-understood enter/leave convention:
|
|
460
|
+
*
|
|
461
|
+
* enter: [enterActive (+ enter) whole phase] · enterFrom (start) → enterTo (end)
|
|
462
|
+
* leave: [leaveActive (+ leave) whole phase] · leaveFrom (start) → leaveTo (end)
|
|
463
|
+
*
|
|
464
|
+
* `name` is a shorthand that expands to `${name}-enter-from`,
|
|
465
|
+
* `${name}-enter-active`, `${name}-enter-to` and the leave equivalents; explicit
|
|
466
|
+
* class fields override the derived ones. Because the classes are just strings,
|
|
467
|
+
* SSR output is deterministic (no class is applied on the server at all — the
|
|
468
|
+
* controller is browser-only), satisfying §4/§21.
|
|
469
|
+
*/
|
|
470
|
+
interface TransitionConfig {
|
|
471
|
+
/** Shorthand base: expands to `${name}-enter-from`, `${name}-enter-active`, … */
|
|
472
|
+
readonly name?: string;
|
|
473
|
+
/** Class(es) present for the whole enter phase (in addition to `enterActive`). */
|
|
474
|
+
readonly enter?: string;
|
|
475
|
+
/** Class(es) applied at the start of enter, removed on the next frame. */
|
|
476
|
+
readonly enterFrom?: string;
|
|
477
|
+
/** Class(es) present for the whole enter phase (where the CSS `transition` lives). */
|
|
478
|
+
readonly enterActive?: string;
|
|
479
|
+
/** Class(es) added on the next frame, removed when enter completes. */
|
|
480
|
+
readonly enterTo?: string;
|
|
481
|
+
/** Class(es) present for the whole leave phase (in addition to `leaveActive`). */
|
|
482
|
+
readonly leave?: string;
|
|
483
|
+
/** Class(es) applied at the start of leave, removed on the next frame. */
|
|
484
|
+
readonly leaveFrom?: string;
|
|
485
|
+
/** Class(es) present for the whole leave phase (where the CSS `transition` lives). */
|
|
486
|
+
readonly leaveActive?: string;
|
|
487
|
+
/** Class(es) added on the next frame, removed when leave completes. */
|
|
488
|
+
readonly leaveTo?: string;
|
|
489
|
+
/**
|
|
490
|
+
* Also animate the very first appearance (initial mount). Hydration never
|
|
491
|
+
* animates appear (the DOM is already present and correct); this only affects
|
|
492
|
+
* fresh browser mounts. Defaults to false.
|
|
493
|
+
*/
|
|
494
|
+
readonly appear?: boolean;
|
|
495
|
+
/**
|
|
496
|
+
* Fallback completion timeout in milliseconds. A transition normally completes
|
|
497
|
+
* on the element's `transitionend`/`animationend`. This timeout is the safety
|
|
498
|
+
* net for (a) transitions that fire no such event and (b) test DOMs like
|
|
499
|
+
* happy-dom that dispatch no transition events at all — making tests
|
|
500
|
+
* deterministic without a real browser (§24). Defaults to 1000. Use a small
|
|
501
|
+
* value (or 0 → next macrotask) in tests.
|
|
502
|
+
*/
|
|
503
|
+
readonly duration?: number;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* The resolved, ready-to-apply form of a {@link TransitionConfig}: each phase's
|
|
507
|
+
* classes are pre-split into arrays so the controller applies/removes them with
|
|
508
|
+
* no per-run string parsing. Produced once by {@link resolveTransition} at wire
|
|
509
|
+
* time (browser only).
|
|
510
|
+
*/
|
|
511
|
+
interface ResolvedTransition {
|
|
512
|
+
/** enter classes present for the whole phase (base `enter` + `enterActive`). */
|
|
513
|
+
readonly enterActive: readonly string[];
|
|
514
|
+
/** enter start classes (removed next frame). */
|
|
515
|
+
readonly enterFrom: readonly string[];
|
|
516
|
+
/** enter end classes (added next frame). */
|
|
517
|
+
readonly enterTo: readonly string[];
|
|
518
|
+
readonly leaveActive: readonly string[];
|
|
519
|
+
readonly leaveFrom: readonly string[];
|
|
520
|
+
readonly leaveTo: readonly string[];
|
|
521
|
+
readonly appear: boolean;
|
|
522
|
+
readonly duration: number;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Resolve a {@link TransitionConfig} into applied class arrays. The `name`
|
|
526
|
+
* shorthand supplies defaults; any explicit field overrides the derived class
|
|
527
|
+
* for that phase-slot (still merged with `enter`/`leave` base classes).
|
|
528
|
+
*/
|
|
529
|
+
declare function resolveTransition(config: TransitionConfig): ResolvedTransition;
|
|
530
|
+
/** Runtime brand check for a transition descriptor value. */
|
|
531
|
+
declare function isTransitionConfig(value: unknown): value is TransitionConfig;
|
|
532
|
+
|
|
449
533
|
/**
|
|
450
534
|
* StreetUI DSL type system.
|
|
451
535
|
* All builder callbacks and option shapes live here.
|
|
@@ -492,6 +576,14 @@ interface A11yOptions {
|
|
|
492
576
|
readonly ariaRequired?: boolean;
|
|
493
577
|
/** aria-modal — mark a dialog as modal (content outside is inert to AT). */
|
|
494
578
|
readonly ariaModal?: boolean;
|
|
579
|
+
/** aria-owns — id(s) of elements owned by this one when the DOM can't express it. */
|
|
580
|
+
readonly ariaOwns?: string;
|
|
581
|
+
/** aria-activedescendant — id of the active option in a composite widget (menu/listbox/combobox). */
|
|
582
|
+
readonly ariaActiveDescendant?: string;
|
|
583
|
+
/** aria-haspopup — the element opens a popup ('menu' | 'listbox' | 'dialog' | 'grid' | 'tree' | true). */
|
|
584
|
+
readonly ariaHasPopup?: boolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';
|
|
585
|
+
/** aria-selected — selection state within a composite widget. */
|
|
586
|
+
readonly ariaSelected?: boolean;
|
|
495
587
|
}
|
|
496
588
|
interface TextOptions extends A11yOptions {
|
|
497
589
|
readonly class?: string;
|
|
@@ -555,6 +647,15 @@ interface ContainerOptions extends A11yOptions {
|
|
|
555
647
|
readonly class?: string;
|
|
556
648
|
readonly id?: string;
|
|
557
649
|
readonly key?: string;
|
|
650
|
+
/**
|
|
651
|
+
* Enter/leave transition for this element (§2). CSS class-based and
|
|
652
|
+
* browser-only: on the server it is ignored (deterministic SSR output). The
|
|
653
|
+
* enter animation runs when the element is added by a reactive `when`/`listOf`
|
|
654
|
+
* change (or on initial mount when `appear` is set); the leave animation runs
|
|
655
|
+
* before the element is removed and disposed — the reconciler defers teardown
|
|
656
|
+
* until the transition completes.
|
|
657
|
+
*/
|
|
658
|
+
readonly transition?: TransitionConfig;
|
|
558
659
|
}
|
|
559
660
|
interface SectionOptions extends ContainerOptions {
|
|
560
661
|
}
|
|
@@ -562,6 +663,21 @@ interface FormOptions extends ContainerOptions {
|
|
|
562
663
|
readonly onSubmit?: (e: Event) => void;
|
|
563
664
|
}
|
|
564
665
|
interface ListOptions extends ContainerOptions {
|
|
666
|
+
/**
|
|
667
|
+
* Enter/leave transition applied to each list item (§7). Preserves keyed
|
|
668
|
+
* identity: reordering reuses items (no leave/enter), append/prepend enter,
|
|
669
|
+
* remove leaves before disposal, and a removed key that reappears mid-leave is
|
|
670
|
+
* reclaimed (leave→enter). `transition` (inherited) applies to the list
|
|
671
|
+
* container itself; `itemTransition` applies to its rows.
|
|
672
|
+
*/
|
|
673
|
+
readonly itemTransition?: TransitionConfig;
|
|
674
|
+
}
|
|
675
|
+
/** Options for `when()` (§2 conditional transitions). */
|
|
676
|
+
interface WhenOptions {
|
|
677
|
+
/** Transition applied to the active branch as it mounts/unmounts. */
|
|
678
|
+
readonly transition?: TransitionConfig;
|
|
679
|
+
/** Also animate the branch present on the initial mount (appear). */
|
|
680
|
+
readonly appear?: boolean;
|
|
565
681
|
}
|
|
566
682
|
/** Options for a plain portal (mount children into `document.body`). */
|
|
567
683
|
interface PortalOptions extends ContainerOptions {
|
|
@@ -634,7 +750,7 @@ interface ContainerDSL extends ContentDSL {
|
|
|
634
750
|
* renders while the condition is false. Compiles into the same reactive
|
|
635
751
|
* reconciliation machinery as `listOf` — there is no separate render path.
|
|
636
752
|
*/
|
|
637
|
-
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder): void;
|
|
753
|
+
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder, options?: WhenOptions): void;
|
|
638
754
|
/**
|
|
639
755
|
* Render `builder`, but swap to `options.fallback` when the boundary enters an
|
|
640
756
|
* error state. A boundary enters that state when (a) any observed `source`
|
|
@@ -753,7 +869,7 @@ declare class ContainerBuilderBase extends ContentBuilderBase implements Contain
|
|
|
753
869
|
list(key: string, builder: ListBuilder, options?: ListOptions): void;
|
|
754
870
|
listOf<T>(key: string, items: Signal<T[]> | ReadonlySignal<T[]>, renderItem: (item: T, index: number, content: ContentDSL) => void, options?: ListOptions): void;
|
|
755
871
|
form(key: string, builder: FormBuilder, options?: FormOptions): void;
|
|
756
|
-
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder): void;
|
|
872
|
+
when(condition: Bindable<boolean>, builder: ContainerBuilder, elseBuilder?: ContainerBuilder, options?: WhenOptions): void;
|
|
757
873
|
errorBoundary(id: string, builder: ContainerBuilder, options: ErrorBoundaryOptions): void;
|
|
758
874
|
portal(key: string, builder: ContainerBuilder, options?: PortalOptions): void;
|
|
759
875
|
/**
|
|
@@ -880,4 +996,4 @@ declare function compile(app: StreetApp, options?: CompileOptions): CompiledAppl
|
|
|
880
996
|
*/
|
|
881
997
|
declare function compileGraph(graph: ApplicationGraph, options?: CompileOptions): CompiledApplication;
|
|
882
998
|
|
|
883
|
-
export { type
|
|
999
|
+
export { type InputOptions as $, type ApplicationId as A, BaseNode as B, type CompiledApplication as C, DiagnosticCollector as D, type Diagnostic as E, DiagnosticError as F, GraphNode as G, type DiagnosticLocation as H, type DiagnosticSeverity as I, type ErrorBoundaryOptions as J, type ErrorFallbackBuilder as K, type ErrorSource as L, type EventDescriptor as M, type FormBuilder as N, FormBuilderImpl as O, type PageDSL as P, type FormDSL as Q, type ReadonlySignal as R, StreetApp as S, type TransitionConfig as T, type Unsubscribe as U, VERSION as V, type FormOptions as W, type GraphNodeData as X, type HandlerFn as Y, type HeadingOptions as Z, type ImageOptions as _, type ComponentDefinition as a, type InputOptionsBase as a0, type LinkOptions as a1, type ListBuilder as a2, ListBuilderImpl as a3, type ListDSL as a4, type ListOptions as a5, type ListPlanEntry as a6, type NodeId as a7, type NodeMetadata as a8, type OverlayOptions as a9, formatDiagnostic as aA, generateApplicationId as aB, generateNodeId as aC, isBatching as aD, isComponentDefinition as aE, isTransitionConfig as aF, nextId as aG, nodeIdPrefix as aH, observerCount as aI, reactiveListItemKey as aJ, reactiveListItemSignature as aK, resetIdCounter as aL, resolveTransition as aM, signal as aN, signalKind as aO, streetui as aP, type PageBuilder as aa, PageBuilderImpl as ab, type PortalOptions as ac, type PropValue as ad, type Props as ae, type ReactiveConsumer as af, type ReactiveSource as ag, type ResolvedTransition as ah, type SectionBuilder as ai, SectionBuilderImpl as aj, type SectionDSL as ak, type SectionOptions as al, type SerializedGraph as am, type SerializedNode as an, type StateRef as ao, type StreetUI as ap, type TextOptions as aq, type TextValue as ar, type WhenOptions as as, batch as at, compile as au, compileGraph as av, component as aw, createNodeId as ax, derived as ay, effect as az, type ContainerBuilder as b, Signal as c, type Subscriber as d, ApplicationGraph as e, type SemanticNodeType as f, type ContainerDSL as g, type SignalKind as h, type A11yOptions as i, AppBuilder as j, type AppDSL as k, type AppOptions as l, type ApplicationGraphOptions as m, type Bindable as n, type BindableText as o, type BoundInputOptions as p, type ButtonOptions as q, type CompileOptions as r, type ComponentContext as s, type ComponentRender as t, type ComponentSetup as u, ContainerBuilderImpl as v, type ContainerOptions as w, type ContentDSL as x, type ControlledInputOptions as y, DerivedSignal as z };
|