@wolfstar/cli 2.1.0 → 2.2.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/LICENSE +201 -201
- package/README.md +304 -304
- package/dist/{_shared-B-hRZDRS.js → _shared-DJrpalNQ.js} +12 -5
- package/dist/_shared-DJrpalNQ.js.map +1 -0
- package/dist/{build-CPnSLYME.js → build-CluOR8dJ.js} +5 -5
- package/dist/build-CluOR8dJ.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{codegen-BqpLGLLs.js → codegen-D6V1i_fa.js} +4 -4
- package/dist/codegen-D6V1i_fa.js.map +1 -0
- package/dist/{commands-ExM8HILu.js → commands-BJ589_AC.js} +4 -4
- package/dist/commands-BJ589_AC.js.map +1 -0
- package/dist/{dev-4wpEQC7l.js → dev-DJJZN4NJ.js} +11 -30
- package/dist/dev-DJJZN4NJ.js.map +1 -0
- package/dist/{diagnostics-CZBVxlpj.js → diagnostics-3JRAy8Xj.js} +17 -1
- package/dist/diagnostics-3JRAy8Xj.js.map +1 -0
- package/dist/{errors-Crt4hu0b.js → errors-COFWKKKw.js} +5 -2
- package/dist/errors-COFWKKKw.js.map +1 -0
- package/dist/external-CxFKxwi3.js.map +1 -1
- package/dist/framework-auto-imports-Gu_PXSyr.js.map +1 -1
- package/dist/hooks-BfDFM38k.js +316 -0
- package/dist/hooks-BfDFM38k.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{info-CdiQajgn.js → info-C1Kx_4Og.js} +4 -4
- package/dist/info-C1Kx_4Og.js.map +1 -0
- package/dist/{locales-C7X8VNmK.js → locales-BzOLRBVg.js} +5 -5
- package/dist/locales-BzOLRBVg.js.map +1 -0
- package/dist/log-buffer-CY82aqnb.js.map +1 -1
- package/dist/{nitro-sP2F3SQu.js → nitro-yjqZBh5L.js} +2 -2
- package/dist/nitro-yjqZBh5L.js.map +1 -0
- package/dist/none-uC_wi_l4.js.map +1 -1
- package/dist/output-mode-Bp7Da8vJ.js.map +1 -1
- package/dist/plain-B6z85uQP.js.map +1 -1
- package/dist/{prepare-B4ysyG6H.js → prepare-Cb45Z4re.js} +9 -5
- package/dist/prepare-Cb45Z4re.js.map +1 -0
- package/dist/{project-MD4dIo2X.js → project-D-8VIcyF.js} +2 -2
- package/dist/project-D-8VIcyF.js.map +1 -0
- package/dist/{run-Ddwrxe1O.js → run-BiLZqib3.js} +8 -8
- package/dist/run-BiLZqib3.js.map +1 -0
- package/dist/theme-3Fc_LI-2.js.map +1 -1
- package/dist/tsc-B931Ezh7.js +3 -0
- package/dist/{tsc-DO7D_uCl.js → tsc-DEBcwIO0.js} +3 -3
- package/dist/tsc-DEBcwIO0.js.map +1 -0
- package/dist/{tsdown-CD68G8_U.js → tsdown-DrWXld54.js} +2 -2
- package/dist/tsdown-DrWXld54.js.map +1 -0
- package/dist/tui-BRddrLQP.js.map +1 -1
- package/dist/{tunnel-DT1FH6oA.js → tunnel-DHSxOZKr.js} +2 -2
- package/dist/tunnel-DHSxOZKr.js.map +1 -0
- package/dist/version-BzclCE19.js.map +1 -1
- package/dist/{vite-CLyB6wl7.js → vite-Bf7nrJx7.js} +2 -2
- package/dist/vite-Bf7nrJx7.js.map +1 -0
- package/package.json +5 -4
- package/dist/_shared-B-hRZDRS.js.map +0 -1
- package/dist/build-CPnSLYME.js.map +0 -1
- package/dist/codegen-BqpLGLLs.js.map +0 -1
- package/dist/commands-ExM8HILu.js.map +0 -1
- package/dist/dev-4wpEQC7l.js.map +0 -1
- package/dist/diagnostics-CZBVxlpj.js.map +0 -1
- package/dist/errors-Crt4hu0b.js.map +0 -1
- package/dist/hooks-H9kjLCMk.js +0 -148
- package/dist/hooks-H9kjLCMk.js.map +0 -1
- package/dist/info-CdiQajgn.js.map +0 -1
- package/dist/locales-C7X8VNmK.js.map +0 -1
- package/dist/nitro-sP2F3SQu.js.map +0 -1
- package/dist/prepare-B4ysyG6H.js.map +0 -1
- package/dist/project-MD4dIo2X.js.map +0 -1
- package/dist/run-Ddwrxe1O.js.map +0 -1
- package/dist/tsc-DO7D_uCl.js.map +0 -1
- package/dist/tsc-YnAWKn3n.js +0 -3
- package/dist/tsdown-CD68G8_U.js.map +0 -1
- package/dist/tunnel-DT1FH6oA.js.map +0 -1
- package/dist/vite-CLyB6wl7.js.map +0 -1
package/dist/dev-4wpEQC7l.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-4wpEQC7l.js","names":[],"sources":["../src/utils/env-import.ts","../src/dev/typechecker.ts","../src/dev/dev-service.ts","../src/dev/host.ts","../src/dev/log-file.ts","../src/commands/dev.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { envModuleSource } from '@wolfstar/vite-server/internal';\nimport { pathToFileURL } from 'node:url';\nimport { resolveFromProject } from './project.js';\n\n/** Build tools whose output never passes through the entry transform that registers `env`. */\nconst UNTRANSFORMED_TOOLS = new Set<string>(['none', 'tsc']);\n\n/**\n * `node` arguments that register `env` before the entry runs, for the build tools the entry transform cannot reach.\n * The preload is a `data:` URL, so `.stars/` gets no generated runtime file; a `data:` URL cannot resolve bare\n * specifiers, so `@wolfstar/env-utilities` is resolved from the project first. When it cannot be resolved nothing is\n * preloaded, and the bot's own import of it reports the missing install.\n */\nexport function envImportArgs(config: ResolvedStarsConfig): string[] {\n\tif (!config.env.enabled || !UNTRANSFORMED_TOOLS.has(config.build.tool)) return [];\n\n\tconst resolved = resolveFromProject(config.root, '@wolfstar/env-utilities');\n\tif (resolved === null) return [];\n\n\tconst source = envModuleSource(config.env.options, pathToFileURL(resolved).href);\n\treturn ['--import', `data:text/javascript,${encodeURIComponent(source)}`];\n}\n","import type { ResolvedStarsConfig, StarsTypechecker } from '@wolfstar/schema';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport type { Diagnostic } from 'nostics';\nimport { resolveTscBinary } from '../builders/tsc.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport type { LogLevel } from '../utils/log-buffer.js';\nimport { createLineSplitter } from '../utils/process-supervisor.js';\nimport { resolveBinary } from '../utils/project.js';\n\nconst WATCH_START = /Starting (incremental )?compilation/;\nconst WATCH_DONE = /Found (\\d+) errors?\\. Watching for file changes/;\nconst ONE_SHOT_DONE = /Found (\\d+) errors?/;\nconst ERROR_LINE = /error TS\\d+:/;\n\nexport type TypecheckState = 'idle' | 'checking' | 'ok' | 'failed';\n\nexport interface TypecheckerEvents {\n\tlog: [level: LogLevel, text: string];\n\tstate: [state: TypecheckState, errors: number];\n}\n\nexport interface TypecheckCommand {\n\t/** The executable, and whether it is a script `node` has to run. */\n\treadonly command: string;\n\treadonly args: readonly string[];\n\treadonly node: boolean;\n\t/** Whether the checker watches the project itself, or has to be re-run after every build. */\n\treadonly watch: boolean;\n}\n\n/**\n * Runs a type checker next to the bot and reports type errors on their own channel, without ever blocking builds or\n * restarts: `stars dev` keeps running whatever the build tool produced, the way Seedcord's `hmr.typecheck` and\n * Vite's `checker` plugin do.\n *\n * `tsc` and `golar` (which forwards to TypeScript) watch the project themselves; `tsz` has no watch mode, so\n * {@link Typechecker.check} re-runs it after every build instead.\n */\nexport class Typechecker extends EventEmitter<TypecheckerEvents> {\n\t#child: ChildProcess | null = null;\n\t#state: TypecheckState = 'idle';\n\t#errors = 0;\n\t#pending = false;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t}\n\n\tpublic get state(): TypecheckState {\n\t\treturn this.#state;\n\t}\n\n\tpublic get errors(): number {\n\t\treturn this.#errors;\n\t}\n\n\t/** Whether the checker re-runs per build instead of watching on its own. */\n\tpublic get oneShot(): boolean {\n\t\treturn this.config.dev.typecheck.enabled && !resolveTypecheckCommand(this.config).watch;\n\t}\n\n\tpublic start(): void {\n\t\tif (!this.config.dev.typecheck.enabled) return;\n\t\tthis.#run();\n\t}\n\n\t/**\n\t * Re-runs a checker that cannot watch. Called after every successful build; a run already in flight is replaced,\n\t * so a fast series of builds only leaves the last check standing.\n\t */\n\tpublic check(): void {\n\t\tif (!this.oneShot) return;\n\t\tif (this.#child) {\n\t\t\tthis.#pending = true;\n\t\t\tthis.#child.kill();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#run();\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tconst child = this.#child;\n\t\tthis.#child = null;\n\t\tthis.#pending = false;\n\t\tif (!child || child.exitCode !== null) return Promise.resolve();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once('exit', () => resolve());\n\t\t\tchild.kill();\n\t\t});\n\t}\n\n\t#run(): void {\n\t\tconst { command, args, node, watch } = resolveTypecheckCommand(this.config);\n\t\tconst child = spawn(node ? process.execPath : command, node ? [command, ...args] : [...args], {\n\t\t\tcwd: this.config.root,\n\t\t\tenv: process.env,\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\twindowsHide: true\n\t\t});\n\t\tthis.#child = child;\n\t\tthis.#setState('checking', 0);\n\n\t\tlet errors = 0;\n\t\tconst handleLine = (line: string) => {\n\t\t\tif (ERROR_LINE.test(line)) errors++;\n\t\t\tthis.#handleLine(line);\n\t\t};\n\n\t\tconst stdout = createLineSplitter(handleLine);\n\t\tconst stderr = createLineSplitter(handleLine);\n\t\tchild.stdout?.on('data', stdout.push);\n\t\tchild.stderr?.on('data', stderr.push);\n\n\t\tchild.once('exit', (code) => {\n\t\t\tstdout.flush();\n\t\t\tstderr.flush();\n\t\t\tthis.#child = null;\n\n\t\t\tif (!watch && this.#state === 'checking') {\n\t\t\t\t// A one-shot checker only reports through its exit code when it prints no summary line.\n\t\t\t\tthis.#setState(code === 0 && errors === 0 ? 'ok' : 'failed', errors);\n\t\t\t}\n\n\t\t\tif (this.#pending) {\n\t\t\t\tthis.#pending = false;\n\t\t\t\tthis.#run();\n\t\t\t}\n\t\t});\n\t\tchild.once('error', (error: NodeJS.ErrnoException) => {\n\t\t\tthis.#child = null;\n\t\t\tthis.emit('log', 'error', error.code === 'ENOENT' ? `${command} is not installed` : error.message);\n\t\t\tthis.#setState('failed', this.#errors);\n\t\t});\n\t}\n\n\t#handleLine(line: string): void {\n\t\tconst text = line.trim();\n\t\tif (text.length === 0) return;\n\n\t\tif (WATCH_START.test(text)) {\n\t\t\tthis.#setState('checking', 0);\n\t\t\treturn;\n\t\t}\n\n\t\tif (ERROR_LINE.test(text)) {\n\t\t\tthis.emit('log', 'error', text);\n\t\t\treturn;\n\t\t}\n\n\t\tconst done = WATCH_DONE.exec(text) ?? ONE_SHOT_DONE.exec(text);\n\t\tif (done) {\n\t\t\tconst errors = Number(done[1]);\n\t\t\tthis.#setState(errors === 0 ? 'ok' : 'failed', errors);\n\t\t\tthis.emit('log', errors === 0 ? 'success' : 'error', errors === 0 ? 'No type errors' : `${errors} type error${errors === 1 ? '' : 's'}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.emit('log', 'info', text);\n\t}\n\n\t#setState(state: TypecheckState, errors: number): void {\n\t\tthis.#state = state;\n\t\tthis.#errors = errors;\n\t\tthis.emit('state', state, errors);\n\t}\n}\n\n/**\n * Builds the command line of the configured type checker, resolved from the project's own `node_modules`.\n *\n * @throws {Diagnostic} when the checker is not installed in the project.\n */\nexport function resolveTypecheckCommand(config: ResolvedStarsConfig): TypecheckCommand {\n\tconst { checker, tsconfig } = config.dev.typecheck;\n\tconst project = tsconfig!;\n\n\tswitch (checker) {\n\t\tcase 'golar': {\n\t\t\t// `golar tsc` forwards everything after it to the TypeScript CLI, watch mode included.\n\t\t\tconst golar = resolveBinary(config.root, 'golar', 'golar');\n\t\t\tif (!golar) throw missing(config, 'golar', 'Install it with `pnpm add -D golar`');\n\n\t\t\treturn { command: golar, args: ['tsc', ...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\n\t\tcase 'tsz': {\n\t\t\t// `tsz` is an early, tsc-compatible checker with no watch mode; `try-tsz` is its comparison harness.\n\t\t\tconst tsz = resolveBinary(config.root, '@mohsen-azimi/tsz-dev', 'tsz');\n\t\t\tif (tsz) return { command: tsz, args: ['--noEmit', '-p', project], node: true, watch: false };\n\n\t\t\tconst tryTsz = resolveBinary(config.root, 'try-tsz', 'try-tsz');\n\t\t\tif (tryTsz) return { command: tryTsz, args: ['-p', project], node: true, watch: false };\n\n\t\t\tthrow missing(config, 'tsz', 'Install it with `pnpm add -D @mohsen-azimi/tsz-dev` (or `try-tsz`)');\n\t\t}\n\n\t\tdefault: {\n\t\t\tconst tsc = resolveTscBinary(config.root);\n\t\t\tif (!tsc) throw missing(config, 'typescript', 'Install it with `pnpm add -D typescript`');\n\n\t\t\treturn { command: tsc, args: [...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\t}\n}\n\nconst WATCH_ARGS = ['--noEmit', '--watch', '--preserveWatchOutput', '--pretty', 'false'] as const;\n\nfunction missing(config: ResolvedStarsConfig, name: string, install: string): Diagnostic {\n\treturn cliDiagnostics.DEPENDENCY_MISSING({\n\t\tname,\n\t\troot: config.root,\n\t\thint: `${install}, pick another \\`dev.typecheck.checker\\`, or set \\`dev.typecheck\\` to false.`\n\t});\n}\n\nexport type { StarsTypechecker };\n","import { EventEmitter } from 'node:events';\nimport type { Builder, BuildOutcome } from '../builders/types.js';\nimport { displayPath, type ResolvedStarsConfig, type StarsHooks, type StarsRestartReason } from '@wolfstar/schema';\nimport { envImportArgs } from '../utils/env-import.js';\nimport type { StarsHookable } from '../utils/hooks.js';\nimport { classifyAppLine, LogBuffer, type LogLevel, type LogSource } from '../utils/log-buffer.js';\nimport { Locales } from '../utils/locales.js';\nimport { ProcessSupervisor, type ProcessExit, type ProcessState } from '../utils/process-supervisor.js';\nimport { Tunnel, type TunnelState } from './tunnel.js';\nimport { Typechecker, type TypecheckState } from './typechecker.js';\n\nexport type BuildState = 'idle' | 'building' | 'ok' | 'failed';\nexport type HealthState = 'unknown' | 'ok' | 'down';\nexport type RestartReason = StarsRestartReason;\n\nexport interface DevStatus {\n\treadonly progress: { readonly fraction: number; readonly message: string; readonly startedAt: number; readonly readyMs: number | null };\n\treadonly process: ProcessState;\n\treadonly build: BuildState;\n\treadonly health: HealthState;\n\treadonly pid: number | null;\n\treadonly startedAt: number | null;\n\treadonly restarts: number;\n\treadonly lastRestartReason: RestartReason | null;\n\treadonly lastBuild: BuildOutcome | null;\n\treadonly lastExit: ProcessExit | null;\n\treadonly url: string | null;\n\treadonly typecheck: TypecheckState;\n\treadonly typeErrors: number;\n\treadonly tunnel: TunnelState;\n\treadonly tunnelUrl: string | null;\n}\n\nexport interface DevServiceEvents {\n\tstatus: [status: DevStatus];\n}\n\nexport interface DevServiceOptions {\n\tbuilder: Builder;\n\t/** The `stars.config` hooks; `build:*` and `dev:restart` run from here. */\n\thooks?: StarsHookable;\n\tlogs?: LogBuffer;\n\t/** Overrides for tests. */\n\tsupervisor?: ProcessSupervisor;\n\ttypechecker?: Typechecker;\n\ttunnel?: Tunnel;\n\thealthInterval?: number;\n}\n\n/**\n * The headless heart of `stars dev`: builds, (re)starts the bot and exposes state and logs.\n * Renderers (plain or TUI) only subscribe to it, they never own behaviour.\n */\nexport class DevService extends EventEmitter<DevServiceEvents> {\n\tpublic readonly logs: LogBuffer;\n\tpublic readonly builder: Builder;\n\tpublic readonly supervisor: ProcessSupervisor;\n\tpublic readonly typechecker: Typechecker;\n\tpublic readonly tunnel: Tunnel;\n\tpublic readonly locales: Locales;\n\treadonly #hooks: StarsHookable | null;\n\t/** Runs hooks one at a time, so an async `build:done` settles before the next build's hooks or a restart. */\n\t#hookChain: Promise<void> = Promise.resolve();\n\n\t#build: BuildState = 'idle';\n\t#health: HealthState = 'unknown';\n\t#restarts = 0;\n\t#lastRestartReason: RestartReason | null = null;\n\t#lastBuild: BuildOutcome | null = null;\n\t#lastExit: ProcessExit | null = null;\n\t#restartTimer: NodeJS.Timeout | null = null;\n\t#healthTimer: NodeJS.Timeout | null = null;\n\t#pendingReason: RestartReason | null = null;\n\t#stopped = false;\n\t#queue: Promise<void> = Promise.resolve();\n\t#progress = { fraction: 0, message: 'preparing your app', startedAt: Date.now(), readyMs: null as number | null };\n\n\tpublic constructor(\n\t\tpublic readonly config: ResolvedStarsConfig,\n\t\toptions: DevServiceOptions\n\t) {\n\t\tsuper();\n\t\tthis.logs = options.logs ?? new LogBuffer();\n\t\tthis.builder = options.builder;\n\t\tthis.supervisor = options.supervisor ?? createSupervisor(config);\n\t\tthis.typechecker = options.typechecker ?? new Typechecker(config);\n\t\tthis.tunnel = options.tunnel ?? new Tunnel(config);\n\t\tthis.locales = new Locales(config);\n\t\tthis.#hooks = options.hooks ?? null;\n\n\t\tthis.builder.on('start', () => {\n\t\t\tthis.#progress = { fraction: 0, message: 'preparing build', startedAt: Date.now(), readyMs: null };\n\t\t\tthis.#setBuild('building');\n\t\t\tvoid this.#startHook('build:before', this.config);\n\t\t});\n\t\tthis.builder.on('progress', (fraction, message) => {\n\t\t\tthis.#progress = { ...this.#progress, fraction: Math.max(this.#progress.fraction, Math.min(0.75, fraction)), message };\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.builder.on('success', (outcome) => this.#onBuildSuccess(outcome));\n\t\tthis.builder.on('failure', (outcome) => this.#onBuildFailure(outcome));\n\t\tthis.builder.on('log', (level, text) => this.log('build', level, text));\n\n\t\tthis.supervisor.on('state', () => {\n\t\t\tif (this.supervisor.state === 'running') {\n\t\t\t\tthis.#settleProgress();\n\t\t\t\tvoid this.#checkHealth();\n\t\t\t}\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.supervisor.on('stdout', (line) => this.log('app', classifyAppLine(line, 'info'), line));\n\t\tthis.supervisor.on('stderr', (line) => this.log('app', classifyAppLine(line, 'error'), line));\n\t\tthis.supervisor.on('error', (error) => this.log('stars', 'error', `Failed to start the bot: ${error.message}`));\n\t\tthis.supervisor.on('exit', (exit) => this.#onExit(exit));\n\n\t\tthis.typechecker.on('log', (level, text) => this.log('tsc', level, text));\n\t\tthis.typechecker.on('state', () => this.#emitStatus());\n\t\tthis.tunnel.on('log', (level, text) => this.log('tunnel', level, text));\n\t\tthis.tunnel.on('state', () => this.#emitStatus());\n\t\tthis.locales.on('log', (level, text) => this.log('build', level, text));\n\t\tthis.locales.on('change', () => {\n\t\t\tif (this.#build === 'ok') this.#scheduleRestart('build');\n\t\t});\n\n\t\tif (config.dev.url && config.dev.health) {\n\t\t\tconst interval = options.healthInterval ?? 5000;\n\t\t\tthis.#healthTimer = setInterval(() => void this.#checkHealth(), interval);\n\t\t\tthis.#healthTimer.unref();\n\t\t}\n\t}\n\n\tpublic get status(): DevStatus {\n\t\treturn {\n\t\t\tprogress: this.#progress,\n\t\t\tprocess: this.supervisor.state,\n\t\t\tbuild: this.#build,\n\t\t\thealth: this.#health,\n\t\t\tpid: this.supervisor.pid,\n\t\t\tstartedAt: this.supervisor.startedAt,\n\t\t\trestarts: this.#restarts,\n\t\t\tlastRestartReason: this.#lastRestartReason,\n\t\t\tlastBuild: this.#lastBuild,\n\t\t\tlastExit: this.#lastExit,\n\t\t\turl: this.config.dev.url,\n\t\t\ttypecheck: this.typechecker.state,\n\t\t\ttypeErrors: this.typechecker.errors,\n\t\t\ttunnel: this.tunnel.state,\n\t\t\ttunnelUrl: this.tunnel.url\n\t\t};\n\t}\n\n\tpublic log(source: LogSource, level: LogLevel, text: string): void {\n\t\tthis.logs.push({ source, level, text });\n\t}\n\n\t/**\n\t * Starts watching; the bot starts after the first successful build.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tthis.#stopped = false;\n\t\tconst entry = displayPath(this.config.root, this.config.entry);\n\t\tthis.log('stars', 'info', this.config.build.tool === 'none' ? `Watching ${entry}` : `Watching ${entry} with ${this.config.build.tool}`);\n\t\tif (this.config.dev.typecheck.enabled) this.typechecker.start();\n\t\tawait this.locales.watch();\n\t\t// The tunnel comes up next to the build: neither waits for the other, and a failed tunnel never stops the bot.\n\t\tvoid this.tunnel.start();\n\t\tawait this.builder.watch();\n\t}\n\n\t/**\n\t * Restarts the bot immediately (used by the `r` key and by `SIGUSR2`).\n\t */\n\tpublic restart(reason: RestartReason = 'manual'): Promise<void> {\n\t\tthis.#clearRestartTimer();\n\t\treturn this.#enqueue(async () => {\n\t\t\tif (this.#stopped) return;\n\t\t\tawait this.#queueHook('dev:restart', reason, this.config);\n\t\t\tif (this.#stopped) return;\n\t\t\tif (reason === 'manual' || reason === 'crash') {\n\t\t\t\tthis.#progress = { fraction: 0, message: 'restarting the bot', startedAt: Date.now(), readyMs: null };\n\t\t\t}\n\t\t\tthis.#lastRestartReason = reason;\n\t\t\tif (this.supervisor.running) {\n\t\t\t\tthis.#restarts++;\n\t\t\t\tthis.log('stars', 'info', `Restarting (${describeReason(reason)})`);\n\t\t\t\tawait this.supervisor.stop();\n\t\t\t} else {\n\t\t\t\tthis.log('stars', 'info', `Starting (${describeReason(reason)})`);\n\t\t\t}\n\n\t\t\tif (this.#stopped) return;\n\t\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\t\tthis.#health = 'unknown';\n\t\t\tthis.supervisor.start();\n\t\t\tthis.#emitStatus();\n\t\t});\n\t}\n\n\t/** Opens or closes the public tunnel (used by the `t` key). */\n\tpublic toggleTunnel(): Promise<void> {\n\t\treturn this.tunnel.toggle();\n\t}\n\n\t/**\n\t * Stops the watcher and the bot. Safe to call more than once.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tthis.#stopped = true;\n\t\tthis.#clearRestartTimer();\n\t\tif (this.#healthTimer) clearInterval(this.#healthTimer);\n\t\tthis.#healthTimer = null;\n\t\tawait this.#enqueue(async () => {\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.builder.close(),\n\t\t\t\tthis.supervisor.stop(),\n\t\t\t\tthis.typechecker.close(),\n\t\t\t\tthis.tunnel.close(),\n\t\t\t\tthis.locales.close()\n\t\t\t]);\n\t\t});\n\t}\n\n\t/**\n\t * Kills the bot and the helper processes without waiting for them. Only for a forced shutdown, {@link stop} is the graceful path.\n\t */\n\tpublic kill(): void {\n\t\tthis.#stopped = true;\n\t\tthis.#clearRestartTimer();\n\t\tthis.supervisor.kill();\n\t\tvoid this.typechecker.close();\n\t\tvoid this.tunnel.close();\n\t}\n\n\tpublic clearLogs(): void {\n\t\tthis.logs.clear();\n\t}\n\n\t#onBuildSuccess(outcome: BuildOutcome): void {\n\t\ttry {\n\t\t\tthis.locales.copy();\n\t\t} catch (error) {\n\t\t\tthis.#onBuildFailure({\n\t\t\t\t...outcome,\n\t\t\t\tok: false,\n\t\t\t\tmessage: `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.#lastBuild = outcome;\n\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\tthis.#setBuild('ok');\n\t\t// Only once locales are copied: until then the build is not done, and may still fail.\n\t\tvoid this.#queueHook('build:done', outcome, this.config);\n\t\tif (this.#stopped) return;\n\t\t// A checker without a watch mode (`tsz`) only knows about the change once the build is through.\n\t\tthis.typechecker.check();\n\t\tthis.log('stars', 'success', this.builder.tool === 'none' ? 'Sources changed' : `Build succeeded in ${outcome.durationMs}ms`);\n\t\tthis.#scheduleRestart(this.supervisor.state === 'idle' ? 'initial' : 'build');\n\t}\n\n\t#onBuildFailure(outcome: BuildOutcome): void {\n\t\tthis.#lastBuild = outcome;\n\t\tvoid this.#queueHook('build:done', outcome, this.config);\n\t\tthis.#setBuild('failed');\n\t\tthis.#clearRestartTimer();\n\t\tthis.log('stars', 'error', `Build failed${outcome.message ? `: ${outcome.message}` : ''}, waiting for changes`);\n\t}\n\n\t#onExit(exit: ProcessExit): void {\n\t\tthis.#lastExit = exit;\n\t\tthis.#health = 'unknown';\n\t\tif (!exit.requested) {\n\t\t\tconst how = exit.signal ? `signal ${exit.signal}` : `code ${exit.code}`;\n\t\t\tthis.log('stars', exit.code === 0 ? 'warn' : 'error', `The bot exited with ${how}, waiting for changes (press r to restart)`);\n\t\t}\n\t\tthis.#emitStatus();\n\t}\n\n\t#scheduleRestart(reason: RestartReason): void {\n\t\tthis.#pendingReason = reason;\n\t\tthis.#clearRestartTimer();\n\t\tthis.#restartTimer = setTimeout(() => {\n\t\t\tthis.#restartTimer = null;\n\t\t\tconst pending = this.#pendingReason ?? reason;\n\t\t\tthis.#pendingReason = null;\n\t\t\tvoid this.restart(pending);\n\t\t}, this.config.dev.debounce);\n\t}\n\n\t#clearRestartTimer(): void {\n\t\tif (this.#restartTimer) clearTimeout(this.#restartTimer);\n\t\tthis.#restartTimer = null;\n\t}\n\n\t#enqueue(task: () => Promise<void>): Promise<void> {\n\t\tthis.#queue = this.#queue.then(task, task);\n\t\treturn this.#queue;\n\t}\n\n\t#setBuild(state: BuildState): void {\n\t\tif (this.#build === state) return;\n\t\tthis.#build = state;\n\t\tthis.#emitStatus();\n\t}\n\n\tasync #checkHealth(): Promise<void> {\n\t\tif (!this.supervisor.running || !this.config.dev.url || !this.config.dev.health) return;\n\t\tconst pid = this.supervisor.pid;\n\n\t\tlet next: HealthState;\n\t\ttry {\n\t\t\tconst response = await fetch(new URL(this.config.dev.health, this.config.dev.url), { signal: AbortSignal.timeout(2000) });\n\t\t\tnext = response.status < 500 ? 'ok' : 'down';\n\t\t} catch {\n\t\t\tnext = 'down';\n\t\t}\n\n\t\tif (this.#stopped || pid !== this.supervisor.pid) return;\n\t\tif (next !== this.#health) {\n\t\t\tthis.#health = next;\n\t\t\tif (next === 'ok') this.#settleProgress();\n\t\t\tthis.#emitStatus();\n\t\t}\n\t}\n\n\t#settleProgress(): void {\n\t\tif (this.config.dev.health && this.#health !== 'ok') return;\n\t\tif (this.#build !== 'ok') return;\n\t\tthis.#progress = {\n\t\t\t...this.#progress,\n\t\t\tfraction: 1,\n\t\t\tmessage: 'watching for changes',\n\t\t\treadyMs: this.#progress.readyMs ?? Date.now() - this.#progress.startedAt\n\t\t};\n\t}\n\n\t/**\n\t * Runs a hook behind the ones already running (see {@link DevService.#hookChain}), e.g. `dev:close` so shutdown\n\t * waits for an unfinished `build:done`.\n\t */\n\tpublic runHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\treturn this.#queueHook(name, ...args);\n\t}\n\n\t/** Queues a hook behind the ones already running; see {@link DevService.#hookChain}. */\n\t#queueHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tthis.#hookChain = this.#hookChain.then(() => this.#callHook(name, ...args));\n\t\treturn this.#hookChain;\n\t}\n\n\t/**\n\t * Starts a hook right away, at the moment it describes, instead of queueing it: `build:before` belongs to the\n\t * builder's `start` boundary, and a builder such as `none` finishes in the same call stack. Its synchronous part\n\t * runs here; later hooks still wait for the rest.\n\t */\n\t#startHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tconst running = this.#callHook(name, ...args);\n\t\tthis.#hookChain = Promise.all([this.#hookChain, running]).then(() => undefined);\n\t\treturn running;\n\t}\n\n\t/**\n\t * Runs a `stars.config` hook. A failing hook is logged rather than thrown: a broken hook must never stop the\n\t * watcher or keep the bot from restarting.\n\t */\n\tasync #callHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tif (this.#hooks === null) return;\n\t\ttry {\n\t\t\tawait this.#hooks.callHook(name, ...args);\n\t\t} catch (error) {\n\t\t\tthis.log('stars', 'error', `Hook ${name} failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\t#emitStatus(): void {\n\t\tthis.emit('status', this.status);\n\t}\n}\n\nexport function createSupervisor(config: ResolvedStarsConfig): ProcessSupervisor {\n\treturn new ProcessSupervisor({\n\t\tcommand: process.execPath,\n\t\targs: [...envImportArgs(config), ...config.dev.nodeArgs, config.build.output, ...config.dev.args],\n\t\tcwd: config.root,\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...config.dev.env,\n\t\t\tSTARS_DEV: '1',\n\t\t\tNODE_ENV: 'development',\n\t\t\tFORCE_COLOR: process.env.NO_COLOR !== undefined ? undefined : (process.env.FORCE_COLOR ?? (process.stdout.isTTY ? '1' : undefined))\n\t\t},\n\t\tkillTimeout: config.dev.killTimeout\n\t});\n}\n\nexport function describeReason(reason: RestartReason): string {\n\tswitch (reason) {\n\t\tcase 'initial':\n\t\t\treturn 'first build';\n\t\tcase 'build':\n\t\t\treturn 'sources changed';\n\t\tcase 'manual':\n\t\t\treturn 'manual restart';\n\t\tcase 'crash':\n\t\t\treturn 'after crash';\n\t}\n}\n","import { lookup } from 'node:dns/promises';\n\n/**\n * Resolves `localhost` the way Vite's dev server does: Node's default DNS result order (`dns.lookup('localhost')`)\n * can disagree with the OS's own, \"verbatim\" resolution order — a well known source of a dev URL that prints fine\n * but is not the address the bot actually bound to (e.g. an IPv6-first system where the server listens on IPv4\n * only). When the two disagree this returns the OS's own address instead of the literal `localhost` hostname.\n */\nexport async function resolveLocalhost(): Promise<string> {\n\ttry {\n\t\tconst [ordered, verbatim] = await Promise.all([lookup('localhost'), lookup('localhost', { verbatim: true })]);\n\t\treturn ordered.family === verbatim.family && ordered.address === verbatim.address ? 'localhost' : verbatim.address;\n\t} catch {\n\t\treturn 'localhost';\n\t}\n}\n\n/**\n * Replaces a `localhost` hostname in `url` with {@link resolveLocalhost}'s result. Any other hostname (an explicit\n * `dev.url` override, a LAN address, …) is returned untouched.\n */\nexport async function withResolvedLocalhost(url: string): Promise<string> {\n\tconst parsed = new URL(url);\n\tif (parsed.hostname !== 'localhost') return url;\n\n\tconst host = await resolveLocalhost();\n\tif (host === 'localhost') return url;\n\n\tparsed.hostname = host.includes(':') ? `[${host}]` : host;\n\treturn parsed.href;\n}\n","import { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { LogBuffer, LogEntry } from '../utils/log-buffer.js';\n\n/**\n * Mirrors a dev session's logs into a file, so a run can be read back after the terminal UI is gone (the TUI takes\n * over the alternate screen and its scrollback disappears on exit). Seedcord keeps a `logs/` directory for the same\n * reason; this writes a single, truncated-per-run file instead.\n */\nexport class LogFileWriter {\n\t#stream: WriteStream | null = null;\n\n\tpublic constructor(\n\t\tpublic readonly file: string,\n\t\tprivate readonly logs: LogBuffer\n\t) {}\n\n\tpublic open(): void {\n\t\tif (this.#stream) return;\n\n\t\tmkdirSync(dirname(this.file), { recursive: true });\n\t\tthis.#stream = createWriteStream(this.file, { flags: 'w' });\n\t\t// A broken pipe or a read-only directory must never take the dev session down with it.\n\t\tthis.#stream.on('error', () => this.close());\n\n\t\tfor (const entry of this.logs.entries()) this.#write(entry);\n\t\tthis.logs.on('entry', this.#write);\n\t}\n\n\tpublic close(): void {\n\t\tconst stream = this.#stream;\n\t\tthis.#stream = null;\n\t\tif (!stream) return;\n\n\t\tthis.logs.off('entry', this.#write);\n\t\tstream.end();\n\t}\n\n\t#write = (entry: LogEntry): void => {\n\t\tthis.#stream?.write(`${format(entry)}\\n`);\n\t};\n}\n\nfunction format(entry: LogEntry): string {\n\treturn `${new Date(entry.time).toISOString()} ${entry.level.padEnd(7)} ${entry.source.padEnd(6)} ${entry.text}`;\n}\n","import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { defineCommand } from 'citty';\nimport { createBuilder } from '../builders/index.js';\nimport { DevService } from '../dev/dev-service.js';\nimport { withResolvedLocalhost } from '../dev/host.js';\nimport { LogFileWriter } from '../dev/log-file.js';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { ExitCode, renderCrashReport } from '../utils/errors.js';\nimport { applyEnvOptions, loadProject, withProjectEnv } from '../utils/hooks.js';\nimport { prefersReducedMotion, resolveOutputMode, shouldUseColor } from '../utils/output-mode.js';\nimport { THEME_SETTINGS, isThemeSetting, readSavedTheme, resolveThemeSetting, saveTheme } from '../utils/theme.js';\nimport { prepareProject, reportWarnings } from './_shared.js';\n\nexport interface DevTaskOptions extends ProjectArgs {\n\ttui?: boolean;\n\t/** `--theme`. */\n\ttheme?: string;\n}\n\nexport async function runDev(options: DevTaskOptions): Promise<void> {\n\tif (options.theme !== undefined && !isThemeSetting(options.theme)) {\n\t\tthrow cliDiagnostics.INVALID_THEME({ theme: options.theme, themes: THEME_SETTINGS.join(', ') });\n\t}\n\n\t// Dev mode applies to config evaluation, build plugins, and the supervised application — not only the child.\n\tprocess.env.NODE_ENV = 'development';\n\tconst project = await loadProject({ cwd: resolveCwd(options), configFile: options.config, env: { ...process.env, NODE_ENV: 'development' } });\n\tconst hooks = project.hooks;\n\t// `env:options` first: it may pick env files with another `HTTP_PORT`, which `dev.url` is derived from.\n\tconst config = await resolveDevConfig(withProjectEnv(await applyEnvOptions(project.config, hooks)));\n\tconst mode = resolveOutputMode({ tui: options.tui });\n\tconst color = shouldUseColor();\n\tconst theme = resolveThemeSetting({ flag: options.theme, saved: readSavedTheme() });\n\n\tconst builder = await createBuilder(config, hooks);\n\tawait hooks.callHook('builder:created', builder, config);\n\tconst service = new DevService(config, { builder, hooks });\n\tawait reportWarnings(config, (text) => service.log('stars', 'warn', text));\n\tconst logFile = config.dev.logFile ? new LogFileWriter(config.dev.logFile, service.logs) : null;\n\tlogFile?.open();\n\tconst renderer =\n\t\tmode === 'tui'\n\t\t\t? (await import('../dev/tui/tui.js')).createTuiRenderer(service, {\n\t\t\t\t\tcolor,\n\t\t\t\t\ttheme,\n\t\t\t\t\treducedMotion: prefersReducedMotion(),\n\t\t\t\t\tonThemeSave: (setting) => {\n\t\t\t\t\t\tif (!saveTheme(setting)) service.log('stars', 'warn', 'Could not save the theme preference.');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t: (await import('../dev/tui/plain.js')).createPlainRenderer(service, { color });\n\n\tlet exiting: Promise<never> | null = null;\n\tconst shutdown = (code: ExitCode): Promise<never> => {\n\t\texiting ??= (async () => {\n\t\t\trenderer.stop();\n\t\t\t// A failing hook must not keep the bot running.\n\t\t\t// Behind any hook still running (an async `build:done`), and logged rather than thrown if it fails.\n\t\t\tawait service.runHook('dev:close', config);\n\t\t\tawait service.stop();\n\t\t\tlogFile?.close();\n\t\t\tprocess.exit(code);\n\t\t})();\n\t\treturn exiting;\n\t};\n\n\t// Like Turborepo: the first signal shuts down gracefully, a second one gives up waiting and kills everything.\n\tlet signalled = false;\n\tconst onSignal = (code: ExitCode) => () => {\n\t\tif (signalled) {\n\t\t\tprocess.stderr.write('\\nForcing shutdown.\\n');\n\t\t\tservice.kill();\n\t\t\tprocess.exit(code);\n\t\t}\n\n\t\tsignalled = true;\n\t\tvoid shutdown(code);\n\t\tprocess.stderr.write('\\nShutting down gracefully, press Ctrl+C again to force quit.\\n');\n\t};\n\n\tprocess.on('SIGINT', onSignal(ExitCode.Interrupted));\n\tprocess.on('SIGTERM', onSignal(ExitCode.Terminated));\n\tprocess.on('SIGHUP', onSignal(ExitCode.Terminated));\n\tif (process.platform !== 'win32') process.on('SIGUSR2', () => void service.restart('manual'));\n\n\tconst finished = renderer.start().then(() => shutdown(ExitCode.Ok));\n\ttry {\n\t\tawait prepareProject(config, hooks);\n\t\tawait service.start();\n\t\tawait hooks.callHook('dev:start', config);\n\t} catch (error) {\n\t\tservice.log('stars', 'error', error instanceof Error ? await renderCrashReport(error, config.root) : String(error));\n\t\tawait shutdown(ExitCode.Error);\n\t}\n\tawait finished;\n}\n\n/**\n * Resolves `dev.url`'s `localhost` to the address that is actually reachable (see {@link withResolvedLocalhost}),\n * the way Vite's dev server does when it starts. Only `stars dev` pays this DNS lookup; `stars info`/`stars build`\n * show or use the unresolved config as-is, since they never talk to the bot.\n */\nasync function resolveDevConfig(config: ResolvedStarsConfig): Promise<ResolvedStarsConfig> {\n\tif (!config.dev.url) return config;\n\n\tconst url = await withResolvedLocalhost(config.dev.url);\n\treturn url === config.dev.url ? config : { ...config, dev: { ...config.dev, url } };\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'dev',\n\t\tdescription: 'Build, run and restart the bot on changes'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\ttui: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Interactive terminal UI; use --no-tui (or STARS_TUI=plain) for plain line output',\n\t\t\tdefault: true\n\t\t},\n\t\ttheme: {\n\t\t\ttype: 'string',\n\t\t\tdescription: `Colour theme of the interactive UI: ${THEME_SETTINGS.join(', ')} (or STARS_THEME; press T in the UI to pick one)`\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runDev({ config: args.config, cwd: args.cwd, tui: args.tui ? undefined : false, theme: args.theme });\n\t}\n});\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics-CZBVxlpj.js","names":[],"sources":["../src/utils/diagnostics.ts"],"sourcesContent":["import { defineDiagnostics } from 'nostics';\n\n/**\n * Structured, stable diagnostic codes for everything `@wolfstar/cli` itself rejects (as opposed to `stars.config.*`\n * validation, which is `@wolfstar/http-framework`'s own {@link import('@wolfstar/schema').configDiagnostics}).\n *\n * `reporters` stays empty: `runMain` (`src/run.ts`) is the single place that renders a caught `Diagnostic` to the\n * terminal (`formatError`) and picks its exit code (`exitCodeOf`), so nothing here should print on its own — a\n * command that calls e.g. `runBuild` directly (as the test suite does) gets a plain thrown value instead of stray\n * console output.\n *\n * `why` and `fix` are always given the same, fully-typed params object, even when one of them ignores part of it or\n * neither takes any: a bare `() => value` next to a typed sibling loses nostics' param-type inference (a zero-arg\n * function widens to `unknown` params, erasing the sibling's fields from the merged type).\n */\nexport const cliDiagnostics = defineDiagnostics({\n\tdocsBase: (code) => `https://stars-components.js.org/docs/cli/errors#${code.toLowerCase()}`,\n\treporters: [],\n\tcodes: {\n\t\tPREPARE_OUTDATED: {\n\t\t\twhy: (_p: {}) => 'The generated project files are out of date, run `stars prepare` to update it.'\n\t\t},\n\t\tDISCORD_TOKEN_MISSING: {\n\t\t\twhy: (_p: {}) => 'DISCORD_TOKEN is not set',\n\t\t\tfix: (_p: {}) => 'Set DISCORD_TOKEN in the environment or in the project .env file.'\n\t\t},\n\t\tDISCORD_APPLICATION_ID_MISSING: {\n\t\t\twhy: (_p: {}) => 'The Discord application id is not set',\n\t\t\tfix: (_p: {}) => 'Set DISCORD_APPLICATION_ID (or APPLICATION_ID) in the environment or in the project .env file.'\n\t\t},\n\t\tDISCORD_REQUEST_FAILED: {\n\t\t\twhy: (p: { status: number; detail: string }) => `Discord answered ${p.status}${p.detail ? `: ${p.detail}` : ''}`,\n\t\t\tfix: (p: { status: number; detail: string }) =>\n\t\t\t\tp.status === 401 ? 'Check DISCORD_TOKEN.' : 'Check the application id and the bot permissions.'\n\t\t},\n\t\tBUILD_FAILED: {\n\t\t\twhy: (p: { message: string }) => `Build failed${p.message ? `: ${p.message}` : ''}`\n\t\t},\n\t\tCOMMAND_NOT_FOUND: {\n\t\t\twhy: (p: { names: string }) => `No deployed command is named ${p.names}`,\n\t\t\tfix: (_p: { names: string }) => 'Run `stars commands list` to see what is deployed.'\n\t\t},\n\t\tABORTED: {\n\t\t\twhy: (_p: {}) => 'Aborted'\n\t\t},\n\t\tCONFIRMATION_REQUIRED: {\n\t\t\twhy: (_p: {}) => 'Refusing to delete commands without a confirmation',\n\t\t\tfix: (_p: {}) => 'Pass --yes to delete them, or --name to pick one, from a script.'\n\t\t},\n\t\tINVALID_THEME: {\n\t\t\twhy: (p: { theme: string; themes: string }) => `Unknown theme \\`${p.theme}\\`.`,\n\t\t\tfix: (p: { theme: string; themes: string }) => `Use one of: ${p.themes}.`\n\t\t},\n\t\tCODEGEN_OUTDATED: {\n\t\t\twhy: (_p: {}) => 'Generated files are out of date, run `stars codegen` to update them.'\n\t\t},\n\t\tDEPENDENCY_MISSING: {\n\t\t\twhy: (p: { name: string; root: string; hint: string }) => `\"${p.name}\" is not installed in ${p.root}`,\n\t\t\tfix: (p: { name: string; root: string; hint: string }) => p.hint\n\t\t},\n\t\tCODEGEN_FAILED: {\n\t\t\twhy: (p: { code: number | null; stderr: string }) => `i18next-type-generator exited with code ${p.code}${p.stderr ? `: ${p.stderr}` : ''}`\n\t\t}\n\t}\n});\n\nexport type CliDiagnosticCode = keyof typeof cliDiagnostics;\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,iBAAiB,kBAAkB;CAC/C,WAAW,SAAS,mDAAmD,KAAK,YAAY;CACxF,WAAW,CAAC;CACZ,OAAO;EACN,kBAAkB,EACjB,MAAM,OAAW,iFAClB;EACA,uBAAuB;GACtB,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,gCAAgC;GAC/B,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,wBAAwB;GACvB,MAAM,MAA0C,oBAAoB,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,WAAW;GAC5G,MAAM,MACL,EAAE,WAAW,MAAM,yBAAyB;EAC9C;EACA,cAAc,EACb,MAAM,MAA2B,eAAe,EAAE,UAAU,KAAK,EAAE,YAAY,KAChF;EACA,mBAAmB;GAClB,MAAM,MAAyB,gCAAgC,EAAE;GACjE,MAAM,OAA0B;EACjC;EACA,SAAS,EACR,MAAM,OAAW,UAClB;EACA,uBAAuB;GACtB,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,eAAe;GACd,MAAM,MAAyC,mBAAmB,EAAE,MAAM;GAC1E,MAAM,MAAyC,eAAe,EAAE,OAAO;EACxE;EACA,kBAAkB,EACjB,MAAM,OAAW,uEAClB;EACA,oBAAoB;GACnB,MAAM,MAAoD,IAAI,EAAE,KAAK,wBAAwB,EAAE;GAC/F,MAAM,MAAoD,EAAE;EAC7D;EACA,gBAAgB,EACf,MAAM,MAA+C,2CAA2C,EAAE,OAAO,EAAE,SAAS,KAAK,EAAE,WAAW,KACvI;CACD;AACD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors-Crt4hu0b.js","names":[],"sources":["../src/utils/errors.ts"],"sourcesContent":["import { configDiagnostics } from '@wolfstar/schema';\nimport { createColors } from 'colorette';\nimport { Diagnostic } from 'nostics';\nimport { ansiFormatter } from 'nostics/formatters/ansi';\nimport { shouldUseColor } from './output-mode.js';\n\nexport const ExitCode = {\n\tOk: 0,\n\tError: 1,\n\tInvalidConfig: 2,\n\tBuildFailed: 3,\n\tInterrupted: 130,\n\tTerminated: 143\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** Every `stars.config.*` diagnostic code maps to {@link ExitCode.InvalidConfig}; everything else defaults to `Error`. */\nconst CONFIG_DIAGNOSTIC_CODES = new Set<string>(Object.keys(configDiagnostics));\n\n/** CLI-local diagnostic codes whose exit code isn't the default {@link ExitCode.Error}. */\nconst CLI_EXIT_CODES: Partial<Record<string, ExitCode>> = {\n\tBUILD_FAILED: ExitCode.BuildFailed\n};\n\n/**\n * Formats an error for the terminal: a `Diagnostic` (from `stars.config.*` validation, via\n * `@wolfstar/schema`'s `configDiagnostics`, or from the CLI's own `cliDiagnostics`) renders through\n * nostics' own ANSI formatter — message, `fix`, `sources` and `docs` — everything else falls back to a crash report.\n */\nexport async function formatError(error: unknown): Promise<string> {\n\tif (error instanceof Diagnostic) {\n\t\tconst colors = createColors({ useColor: shouldUseColor() });\n\t\treturn ansiFormatter(colors)(error);\n\t}\n\n\t// citty's CLIError (unknown command, missing argument): the message is enough.\n\tif (error instanceof Error && error.name === 'CLIError') return error.message;\n\tif (error instanceof Error) return renderCrashReport(error);\n\treturn String(error);\n}\n\n/**\n * Renders an unexpected error (a bug, not something the CLI already explains through a `Diagnostic`) as a\n * sourcemapped, syntax-highlighted report — frames and a snippet of the original source instead of a stack trace\n * pointing into the bundled `dist/cli.js`.\n */\nexport async function renderCrashReport(error: unknown, cwd: string = process.cwd()): Promise<string> {\n\tconst { createReport, fsLoader, renderAnsi } = await import('my-bad');\n\tconst report = await createReport(error, { cwd, loaders: [fsLoader()] });\n\treturn renderAnsi(report, { cwd });\n}\n\nexport function exitCodeOf(error: unknown): ExitCode {\n\tif (error instanceof Diagnostic) {\n\t\tif (CONFIG_DIAGNOSTIC_CODES.has(error.code)) return ExitCode.InvalidConfig;\n\t\treturn CLI_EXIT_CODES[error.code] ?? ExitCode.Error;\n\t}\n\n\treturn ExitCode.Error;\n}\n"],"mappings":";;;;;;;AAMA,MAAa,WAAW;CACvB,IAAI;CACJ,OAAO;CACP,eAAe;CACf,aAAa;CACb,aAAa;CACb,YAAY;AACb;;AAKA,MAAM,0BAA0B,IAAI,IAAY,OAAO,KAAK,iBAAiB,CAAC;;AAG9E,MAAM,iBAAoD,EACzD,cAAc,SAAS,YACxB;;;;;;AAOA,eAAsB,YAAY,OAAiC;CAClE,IAAI,iBAAiB,YAAY;EAChC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,EAAE,CAAC;EAC1D,OAAO,cAAc,MAAM,CAAC,CAAC,KAAK;CACnC;CAGA,IAAI,iBAAiB,SAAS,MAAM,SAAS,YAAY,OAAO,MAAM;CACtE,IAAI,iBAAiB,OAAO,OAAO,kBAAkB,KAAK;CAC1D,OAAO,OAAO,KAAK;AACpB;;;;;;AAOA,eAAsB,kBAAkB,OAAgB,MAAc,QAAQ,IAAI,GAAoB;CACrG,MAAM,EAAE,cAAc,UAAU,eAAe,MAAM,OAAO;CAE5D,OAAO,WAAW,MADG,aAAa,OAAO;EAAE;EAAK,SAAS,CAAC,SAAS,CAAC;CAAE,CAAC,GAC7C,EAAE,IAAI,CAAC;AAClC;AAEA,SAAgB,WAAW,OAA0B;CACpD,IAAI,iBAAiB,YAAY;EAChC,IAAI,wBAAwB,IAAI,MAAM,IAAI,GAAG,OAAO,SAAS;EAC7D,OAAO,eAAe,MAAM,SAAS,SAAS;CAC/C;CAEA,OAAO,SAAS;AACjB"}
|
package/dist/hooks-H9kjLCMk.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { r as resolveBinary } from "./project-MD4dIo2X.js";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
import { loadConfigFile, readProjectEnvFiles, resolveStarsConfig } from "@wolfstar/schema";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
|
-
import { createHooks } from "hookable";
|
|
6
|
-
|
|
7
|
-
//#region src/utils/args.ts
|
|
8
|
-
/**
|
|
9
|
-
* Arguments shared by every command that reads the project configuration.
|
|
10
|
-
*/
|
|
11
|
-
const projectArgs = {
|
|
12
|
-
config: {
|
|
13
|
-
type: "string",
|
|
14
|
-
alias: "c",
|
|
15
|
-
description: "Path to the configuration file (defaults to stars.config.* in the working directory)"
|
|
16
|
-
},
|
|
17
|
-
cwd: {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "Working directory to run from (defaults to the current directory)"
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
function resolveCwd(args) {
|
|
23
|
-
return args.cwd ? resolve(process.cwd(), args.cwd) : process.cwd();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region src/utils/project-env.ts
|
|
28
|
-
/**
|
|
29
|
-
* The variables the bot will load, for the CLI's own lookups (Discord credentials for the tunnel). With the default
|
|
30
|
-
* loader these are the project's env files, read from `env.path`/`env.env`. With `loader: 'varlock'` they are what
|
|
31
|
-
* `varlock load` resolves from the project's `.env.schema` — a dotenv file may be stale or absent there — and nothing
|
|
32
|
-
* when varlock cannot be run, rather than values the bot never sees.
|
|
33
|
-
*/
|
|
34
|
-
function readProjectEnv(config) {
|
|
35
|
-
const { path, env = "development", loader } = config.env.options;
|
|
36
|
-
if (loader !== "varlock") return readProjectEnvFiles(config.root, env, { path });
|
|
37
|
-
const binary = resolveBinary(config.root, "varlock", "varlock");
|
|
38
|
-
if (binary === null) return {};
|
|
39
|
-
try {
|
|
40
|
-
const output = execFileSync(process.execPath, [
|
|
41
|
-
binary,
|
|
42
|
-
"load",
|
|
43
|
-
"--format",
|
|
44
|
-
"json"
|
|
45
|
-
], {
|
|
46
|
-
cwd: config.root,
|
|
47
|
-
env: {
|
|
48
|
-
...process.env,
|
|
49
|
-
...config.dev.env,
|
|
50
|
-
NODE_ENV: "development"
|
|
51
|
-
},
|
|
52
|
-
encoding: "utf8",
|
|
53
|
-
stdio: [
|
|
54
|
-
"ignore",
|
|
55
|
-
"pipe",
|
|
56
|
-
"ignore"
|
|
57
|
-
],
|
|
58
|
-
timeout: 3e4
|
|
59
|
-
});
|
|
60
|
-
const values = JSON.parse(output);
|
|
61
|
-
return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => [key, String(value)]));
|
|
62
|
-
} catch {
|
|
63
|
-
return {};
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
//#endregion
|
|
68
|
-
//#region src/utils/hooks.ts
|
|
69
|
-
/** What each configuration loaded by {@link loadProject} was resolved from, so `env:options` can re-resolve it. */
|
|
70
|
-
const sources = /* @__PURE__ */ new WeakMap();
|
|
71
|
-
/** Registers the `hooks` of `stars.config` on a fresh `hookable` instance. */
|
|
72
|
-
function createStarsHooks(config) {
|
|
73
|
-
const hooks = createHooks();
|
|
74
|
-
for (const [name, callbacks] of Object.entries(config.hooks)) for (const callback of callbacks) hooks.hook(name, callback);
|
|
75
|
-
return hooks;
|
|
76
|
-
}
|
|
77
|
-
/** Loads `stars.config`, registers its hooks and runs `config:resolved`. */
|
|
78
|
-
async function loadProject(options) {
|
|
79
|
-
const cwd = options.cwd ?? process.cwd();
|
|
80
|
-
const loaded = await loadConfigFile({
|
|
81
|
-
cwd,
|
|
82
|
-
configFile: options.configFile
|
|
83
|
-
});
|
|
84
|
-
const source = {
|
|
85
|
-
cwd,
|
|
86
|
-
configFile: loaded.configFile,
|
|
87
|
-
config: loaded.config,
|
|
88
|
-
env: options.env
|
|
89
|
-
};
|
|
90
|
-
const config = resolveStarsConfig(source);
|
|
91
|
-
sources.set(config, source);
|
|
92
|
-
const hooks = createStarsHooks(config);
|
|
93
|
-
await hooks.callHook("config:resolved", config);
|
|
94
|
-
return {
|
|
95
|
-
config,
|
|
96
|
-
hooks
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Runs `env:options` on a copy of the resolved `env` options and returns a configuration carrying the result, which
|
|
101
|
-
* is what the builders write into the entry. The resolved configuration itself is left untouched.
|
|
102
|
-
*
|
|
103
|
-
* When the hook changes the options, the configuration is resolved again with them, so everything read from the env
|
|
104
|
-
* files — the default `dev.url` port above all — matches what the bot will load.
|
|
105
|
-
*/
|
|
106
|
-
async function applyEnvOptions(config, hooks) {
|
|
107
|
-
if (!config.env.enabled) return config;
|
|
108
|
-
const options = { ...config.env.options };
|
|
109
|
-
await hooks.callHook("env:options", options, config);
|
|
110
|
-
const source = sources.get(config);
|
|
111
|
-
if (source === void 0 || JSON.stringify(options) === JSON.stringify(config.env.options)) return {
|
|
112
|
-
...config,
|
|
113
|
-
env: {
|
|
114
|
-
...config.env,
|
|
115
|
-
options
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
return reresolve(source, { config: {
|
|
119
|
-
...source.config,
|
|
120
|
-
env: {
|
|
121
|
-
...options,
|
|
122
|
-
enabled: true
|
|
123
|
-
}
|
|
124
|
-
} });
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* With `loader: 'varlock'`, resolves the configuration again with the variables `varlock load` returns, so the
|
|
128
|
-
* defaults `stars.config` derives from the environment — the `dev.url` port — match what the bot loads. Every other
|
|
129
|
-
* configuration is returned as-is: the schema reads its env files directly.
|
|
130
|
-
*/
|
|
131
|
-
function withProjectEnv(config) {
|
|
132
|
-
const source = sources.get(config);
|
|
133
|
-
if (source === void 0 || !config.env.enabled || config.env.options.loader !== "varlock") return config;
|
|
134
|
-
return reresolve(source, { projectEnv: readProjectEnv(config) });
|
|
135
|
-
}
|
|
136
|
-
function reresolve(source, change) {
|
|
137
|
-
const next = {
|
|
138
|
-
...source,
|
|
139
|
-
...change
|
|
140
|
-
};
|
|
141
|
-
const config = resolveStarsConfig(next);
|
|
142
|
-
sources.set(config, next);
|
|
143
|
-
return config;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
//#endregion
|
|
147
|
-
export { projectArgs as a, readProjectEnv as i, loadProject as n, resolveCwd as o, withProjectEnv as r, applyEnvOptions as t };
|
|
148
|
-
//# sourceMappingURL=hooks-H9kjLCMk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-H9kjLCMk.js","names":[],"sources":["../src/utils/args.ts","../src/utils/project-env.ts","../src/utils/hooks.ts"],"sourcesContent":["import type { ArgsDef } from 'citty';\nimport { resolve } from 'node:path';\n\n/**\n * Arguments shared by every command that reads the project configuration.\n */\nexport const projectArgs = {\n\tconfig: {\n\t\ttype: 'string',\n\t\talias: 'c',\n\t\tdescription: 'Path to the configuration file (defaults to stars.config.* in the working directory)'\n\t},\n\tcwd: {\n\t\ttype: 'string',\n\t\tdescription: 'Working directory to run from (defaults to the current directory)'\n\t}\n} as const satisfies ArgsDef;\n\nexport interface ProjectArgs {\n\tconfig?: string;\n\tcwd?: string;\n}\n\nexport function resolveCwd(args: ProjectArgs): string {\n\treturn args.cwd ? resolve(process.cwd(), args.cwd) : process.cwd();\n}\n","import { readProjectEnvFiles, type ResolvedStarsConfig } from '@wolfstar/schema';\nimport { execFileSync } from 'node:child_process';\nimport { resolveBinary } from './project.js';\n\n/**\n * The variables the bot will load, for the CLI's own lookups (Discord credentials for the tunnel). With the default\n * loader these are the project's env files, read from `env.path`/`env.env`. With `loader: 'varlock'` they are what\n * `varlock load` resolves from the project's `.env.schema` — a dotenv file may be stale or absent there — and nothing\n * when varlock cannot be run, rather than values the bot never sees.\n */\nexport function readProjectEnv(config: ResolvedStarsConfig): Record<string, string> {\n\tconst { path, env = 'development', loader } = config.env.options;\n\tif (loader !== 'varlock') return readProjectEnvFiles(config.root, env, { path });\n\n\tconst binary = resolveBinary(config.root, 'varlock', 'varlock');\n\tif (binary === null) return {};\n\n\ttry {\n\t\t// The way the bot loads it: `@wolfstar/env-utilities` runs `varlock/auto-load` with no `--env` (it ignores\n\t\t// `env.env` with varlock), in the environment `stars dev` gives the bot.\n\t\tconst output = execFileSync(process.execPath, [binary, 'load', '--format', 'json'], {\n\t\t\tcwd: config.root,\n\t\t\t// Same order as `createSupervisor`: `NODE_ENV` is forced to development after `dev.env`, so it can't differ.\n\t\t\tenv: { ...process.env, ...config.dev.env, NODE_ENV: 'development' },\n\t\t\tencoding: 'utf8',\n\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\ttimeout: 30_000\n\t\t});\n\t\tconst values = JSON.parse(output) as Record<string, unknown>;\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(values)\n\t\t\t\t.filter(([, value]) => value !== undefined && value !== null)\n\t\t\t\t.map(([key, value]) => [key, String(value)])\n\t\t);\n\t} catch {\n\t\treturn {};\n\t}\n}\n","import {\n\tloadConfigFile,\n\tresolveStarsConfig,\n\ttype LoadStarsConfigOptions,\n\ttype ResolveConfigOptions,\n\ttype ResolvedStarsConfig,\n\ttype StarsHookName,\n\ttype StarsHooks\n} from '@wolfstar/schema';\nimport { createHooks, type Hookable } from 'hookable';\nimport { readProjectEnv } from './project-env.js';\n\nexport type StarsHookable = Hookable<StarsHooks>;\n\n/** What each configuration loaded by {@link loadProject} was resolved from, so `env:options` can re-resolve it. */\nconst sources = new WeakMap<ResolvedStarsConfig, ResolveConfigOptions>();\n\n/** Registers the `hooks` of `stars.config` on a fresh `hookable` instance. */\nexport function createStarsHooks(config: ResolvedStarsConfig): StarsHookable {\n\tconst hooks = createHooks<StarsHooks>();\n\tfor (const [name, callbacks] of Object.entries(config.hooks) as [StarsHookName, readonly StarsHooks[StarsHookName][]][]) {\n\t\tfor (const callback of callbacks) hooks.hook(name, callback);\n\t}\n\n\treturn hooks;\n}\n\n/** Loads `stars.config`, registers its hooks and runs `config:resolved`. */\nexport async function loadProject(options: LoadStarsConfigOptions): Promise<{ config: ResolvedStarsConfig; hooks: StarsHookable }> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst loaded = await loadConfigFile({ cwd, configFile: options.configFile });\n\tconst source: ResolveConfigOptions = { cwd, configFile: loaded.configFile, config: loaded.config, env: options.env };\n\tconst config = resolveStarsConfig(source);\n\tsources.set(config, source);\n\n\tconst hooks = createStarsHooks(config);\n\tawait hooks.callHook('config:resolved', config);\n\treturn { config, hooks };\n}\n\n/**\n * Runs `env:options` on a copy of the resolved `env` options and returns a configuration carrying the result, which\n * is what the builders write into the entry. The resolved configuration itself is left untouched.\n *\n * When the hook changes the options, the configuration is resolved again with them, so everything read from the env\n * files — the default `dev.url` port above all — matches what the bot will load.\n */\nexport async function applyEnvOptions(config: ResolvedStarsConfig, hooks: StarsHookable): Promise<ResolvedStarsConfig> {\n\tif (!config.env.enabled) return config;\n\n\tconst options = { ...config.env.options };\n\tawait hooks.callHook('env:options', options, config);\n\n\tconst source = sources.get(config);\n\tif (source === undefined || JSON.stringify(options) === JSON.stringify(config.env.options)) {\n\t\treturn { ...config, env: { ...config.env, options } };\n\t}\n\n\treturn reresolve(source, { config: { ...source.config, env: { ...options, enabled: true } } });\n}\n\n/**\n * With `loader: 'varlock'`, resolves the configuration again with the variables `varlock load` returns, so the\n * defaults `stars.config` derives from the environment — the `dev.url` port — match what the bot loads. Every other\n * configuration is returned as-is: the schema reads its env files directly.\n */\nexport function withProjectEnv(config: ResolvedStarsConfig): ResolvedStarsConfig {\n\tconst source = sources.get(config);\n\tif (source === undefined || !config.env.enabled || config.env.options.loader !== 'varlock') return config;\n\treturn reresolve(source, { projectEnv: readProjectEnv(config) });\n}\n\nfunction reresolve(source: ResolveConfigOptions, change: Partial<ResolveConfigOptions>): ResolvedStarsConfig {\n\tconst next = { ...source, ...change };\n\tconst config = resolveStarsConfig(next);\n\tsources.set(config, next);\n\treturn config;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"info-CdiQajgn.js","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import { displayPath, type ResolvedStarsConfig, type StarsEnvSetupOptions } from '@wolfstar/schema';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { arch, platform } from 'node:os';\nimport { relative } from 'node:path';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { applyEnvOptions, loadProject } from '../utils/hooks.js';\nimport { resolveOutputMode, shouldUseColor } from '../utils/output-mode.js';\nimport { findInstalledVersion } from '../utils/project.js';\nimport { readOwnPackageJson } from '../utils/version.js';\n\nexport interface InfoOptions extends ProjectArgs {\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport interface ProjectInfo {\n\tcli: { version: string; node: string; platform: string; outputMode: 'tui' | 'plain' };\n\tproject: {\n\t\tcwd: string;\n\t\troot: string;\n\t\tconfigFile: string | null;\n\t\tname: string | null;\n\t\tversion: string | null;\n\t\tentry: string;\n\t\tframeworkVersion: string | null;\n\t};\n\tbuild: ResolvedStarsConfig['build'];\n\tdev: ResolvedStarsConfig['dev'];\n\tcodegen: ResolvedStarsConfig['codegen'];\n\timports: ResolvedStarsConfig['imports'];\n\texperimental: ResolvedStarsConfig['experimental'];\n\tfuture: ResolvedStarsConfig['future'];\n\tenv: ResolvedStarsConfig['env'];\n\t/** The names of the hooks registered in `stars.config`, flattened (`build:done`). */\n\thooks: string[];\n\t/** Non-fatal configuration diagnostics, as `CODE: message`. */\n\twarnings: string[];\n\t/**\n\t * The option names set in the `tsdown`/`vite` blocks. Only the names: the values hold plugins and callbacks,\n\t * which neither serialize to JSON nor read usefully on a terminal.\n\t */\n\toptions: { tsdown: string[]; vite: string[] };\n}\n\nexport function collectInfo(config: ResolvedStarsConfig): ProjectInfo {\n\treturn {\n\t\tcli: {\n\t\t\tversion: readOwnPackageJson().version,\n\t\t\tnode: process.version,\n\t\t\tplatform: `${platform()} ${arch()}`,\n\t\t\toutputMode: resolveOutputMode()\n\t\t},\n\t\tproject: {\n\t\t\tcwd: config.cwd,\n\t\t\troot: config.root,\n\t\t\tconfigFile: config.configFile,\n\t\t\tname: config.packageJson?.name ?? null,\n\t\t\tversion: config.packageJson?.version ?? null,\n\t\t\tentry: config.entry,\n\t\t\tframeworkVersion: findInstalledVersion(config.root, '@wolfstar/http-framework')\n\t\t},\n\t\tbuild: config.build,\n\t\tdev: config.dev,\n\t\tcodegen: config.codegen,\n\t\timports: config.imports,\n\t\texperimental: config.experimental,\n\t\tfuture: config.future,\n\t\tenv: config.env,\n\t\thooks: Object.keys(config.hooks),\n\t\twarnings: config.warnings.map((warning) => `${warning.code}: ${warning.message}`),\n\t\toptions: { tsdown: Object.keys(config.tsdown), vite: Object.keys(config.vite) }\n\t};\n}\n\nexport function formatInfo(info: ProjectInfo, useColor: boolean): string {\n\tconst colors = createColors({ useColor });\n\tconst { root } = info.project;\n\tconst show = (path: string | null) => (path === null ? colors.dim('none') : displayPath(root, path));\n\tconst row = (label: string, value: string) => ` ${colors.dim(label.padEnd(12))}${value}`;\n\tconst section = (title: string, rows: string[]) => [colors.bold(title), ...rows].join('\\n');\n\n\treturn [\n\t\tsection(`stars ${colors.green(`v${info.cli.version}`)}`, [\n\t\t\trow('node', info.cli.node),\n\t\t\trow('platform', info.cli.platform),\n\t\t\trow('output', info.cli.outputMode),\n\t\t\trow(\n\t\t\t\t'framework',\n\t\t\t\tinfo.project.frameworkVersion\n\t\t\t\t\t? `@wolfstar/http-framework v${info.project.frameworkVersion}`\n\t\t\t\t\t: colors.yellow('@wolfstar/http-framework not installed')\n\t\t\t)\n\t\t]),\n\t\tsection('Project', [\n\t\t\trow(\n\t\t\t\t'name',\n\t\t\t\tinfo.project.name\n\t\t\t\t\t? `${info.project.name}${info.project.version ? colors.dim(` v${info.project.version}`) : ''}`\n\t\t\t\t\t: colors.dim('unnamed')\n\t\t\t),\n\t\t\trow('root', root),\n\t\t\trow(\n\t\t\t\t'config',\n\t\t\t\tinfo.project.configFile ? relative(root, info.project.configFile) || info.project.configFile : colors.dim('none (defaults)')\n\t\t\t),\n\t\t\trow('entry', show(info.project.entry))\n\t\t]),\n\t\tsection('Build', [\n\t\t\trow('tool', info.build.tool),\n\t\t\t// Which file the build tool is configured from: its own, or this project's `stars.config`.\n\t\t\trow('config', info.build.configFile ? show(info.build.configFile) : colors.dim('stars.config')),\n\t\t\trow('options', describeOptions(info, colors)),\n\t\t\trow('outDir', show(info.build.outDir)),\n\t\t\trow('tsconfig', show(info.build.tsconfig)),\n\t\t\trow('runs', show(info.build.output))\n\t\t]),\n\t\tsection('Dev', [\n\t\t\trow('watch', info.dev.watch.map(show).join(', ')),\n\t\t\trow('debounce', `${info.dev.debounce}ms`),\n\t\t\trow('node args', info.dev.nodeArgs.join(' ') || colors.dim('none')),\n\t\t\trow('args', info.dev.args.join(' ') || colors.dim('none')),\n\t\t\trow('url', info.dev.url ?? colors.dim('unknown, set dev.url or HTTP_PORT')),\n\t\t\trow('health', info.dev.health ?? colors.dim('none')),\n\t\t\trow(\n\t\t\t\t'typecheck',\n\t\t\t\tinfo.dev.typecheck.enabled ? `${info.dev.typecheck.checker} → ${show(info.dev.typecheck.tsconfig)}` : colors.dim('disabled')\n\t\t\t),\n\t\t\trow('tunnel', describeTunnel(info.dev.tunnel, colors)),\n\t\t\trow('log file', info.dev.logFile ? show(info.dev.logFile) : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Codegen', [\n\t\t\trow('i18n', info.codegen.i18n ? `${show(info.codegen.i18n.locales)} → ${show(info.codegen.i18n.output)}` : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Future', [\n\t\t\trow('compat', `v${info.future.compatibilityVersion} defaults`),\n\t\t\t...info.warnings.map((warning) => row('warning', colors.yellow(warning)))\n\t\t]),\n\t\tsection('Env', [row('register', info.env.enabled ? colors.green(describeEnvOptions(info.env.options)) : colors.dim('disabled'))]),\n\t\tsection('Hooks', [row('registered', info.hooks.join(', ') || colors.dim('none'))]),\n\t\tsection('Experimental', [\n\t\t\trow('vite', flag(info.experimental.enableVite, colors)),\n\t\t\trow('nitro', flag(info.experimental.enableNitro, colors)),\n\t\t\t...(info.experimental.enableNitro ? [row('nitro preset', info.experimental.nitro.preset)] : []),\n\t\t\trow('external', flag(info.experimental.enableExternalVite, colors))\n\t\t]),\n\t\tsection('Imports', [\n\t\t\trow('auto', info.imports.enabled ? colors.green('enabled') : colors.dim('disabled')),\n\t\t\trow('dirs', info.imports.dirs.map(show).join(', ')),\n\t\t\trow('presets', info.imports.presets.join(', ') || colors.dim('none')),\n\t\t\trow('dts', show(info.imports.dts))\n\t\t])\n\t].join('\\n\\n');\n}\n\nfunction describeOptions(info: ProjectInfo, colors: ReturnType<typeof createColors>): string {\n\tconst names = info.build.tool === 'vite' ? info.options.vite : info.options.tsdown;\n\treturn names.length > 0 ? names.join(', ') : colors.dim('none');\n}\n\nfunction describeEnvOptions(options: Readonly<StarsEnvSetupOptions>): string {\n\tconst entries = Object.entries(options).map(([key, value]) => `${key} ${String(value)}`);\n\treturn entries.length > 0 ? `enabled (${entries.join(', ')})` : 'enabled';\n}\n\nfunction flag(enabled: boolean, colors: ReturnType<typeof createColors>): string {\n\treturn enabled ? colors.green('enabled') : colors.dim('disabled');\n}\n\nfunction describeTunnel(tunnel: ResolvedStarsConfig['dev']['tunnel'], colors: ReturnType<typeof createColors>): string {\n\tswitch (tunnel.mode) {\n\t\tcase 'quick':\n\t\t\treturn 'cloudflared quick tunnel';\n\t\tcase 'url':\n\t\t\treturn tunnel.url;\n\t\tdefault:\n\t\t\treturn colors.dim('disabled');\n\t}\n}\n\nexport async function runInfo(options: InfoOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst project = await loadProject({ cwd: resolveCwd(options), configFile: options.config });\n\t// What the build would use: `env:options` may change the env files.\n\tconst config = await applyEnvOptions(project.config, project.hooks);\n\tconst info = collectInfo(config);\n\tstdout.write(`${options.json ? JSON.stringify(info, null, 2) : formatInfo(info, shouldUseColor())}\\n`);\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'info',\n\t\tdescription: 'Print the resolved project configuration and environment'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Print machine-readable JSON',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runInfo({ config: args.config, cwd: args.cwd, json: args.json });\n\t}\n});\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"locales-C7X8VNmK.js","names":[],"sources":["../src/builders/index.ts","../src/utils/locales.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport type { StarsHookable } from '../utils/hooks.js';\nimport type { Builder } from './types.js';\n\n/**\n * Creates the builder for `build.tool`. `hooks` reach the builders that expose hooks of their own (`tsdown:options`).\n */\nexport async function createBuilder(config: ResolvedStarsConfig, hooks?: StarsHookable): Promise<Builder> {\n\t// The project runs its own build, so the CLI only watches what it writes (see `ExternalBuilder`) — including when\n\t// it is driving `vite build` with its own `nitro()` plugin itself; `build.output` already points at Nitro's\n\t// `server/index.mjs` in that case (see `resolveBuild`).\n\tif (config.experimental.enableExternalVite) {\n\t\tconst { ExternalBuilder } = await import('./external.js');\n\t\treturn new ExternalBuilder(config);\n\t}\n\n\t// Nitro is itself a Vite plugin — there is no separate `nitro build` step — so it is handled before the\n\t// `build.tool` switch below, the same way `enableExternalVite` is.\n\tif (config.experimental.enableNitro) {\n\t\tconst { NitroBuilder } = await import('./nitro.js');\n\t\treturn new NitroBuilder(config);\n\t}\n\n\tswitch (config.build.tool) {\n\t\tcase 'tsdown': {\n\t\t\tconst { TsdownBuilder } = await import('./tsdown.js');\n\t\t\treturn new TsdownBuilder(config, hooks);\n\t\t}\n\t\tcase 'vite': {\n\t\t\tconst { ViteBuilder } = await import('./vite.js');\n\t\t\treturn new ViteBuilder(config);\n\t\t}\n\t\tcase 'tsc': {\n\t\t\tconst { TscBuilder } = await import('./tsc.js');\n\t\t\treturn new TscBuilder(config);\n\t\t}\n\t\tcase 'none': {\n\t\t\tconst { NoneBuilder } = await import('./none.js');\n\t\t\treturn new NoneBuilder(config);\n\t\t}\n\t}\n}\n\nexport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n","import { EventEmitter } from 'node:events';\nimport { cpSync, existsSync, mkdirSync, rmSync } from 'node:fs';\nimport { dirname, join, relative } from 'node:path';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport type { LogLevel } from './log-buffer.js';\n\nexport interface LocalesEvents {\n\tchange: [];\n\tlog: [level: LogLevel, text: string];\n}\n\n/** Keeps the conventional `src/locales` data directory next to the compiled application. */\nexport class Locales extends EventEmitter<LocalesEvents> {\n\treadonly source: string;\n\treadonly destination: string;\n\t#watcher: { close(): Promise<void> } | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t\tthis.source = join(config.root, 'src', 'locales');\n\t\tthis.destination = join(config.build.outDir, 'locales');\n\t}\n\n\tpublic copy(): boolean {\n\t\tif (this.config.build.tool === 'none' || !existsSync(this.source)) return false;\n\t\tmkdirSync(this.destination, { recursive: true });\n\t\tcpSync(this.source, this.destination, { recursive: true, force: true });\n\t\treturn true;\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tif (this.config.build.tool === 'none' || !existsSync(this.source) || this.#watcher) return;\n\t\tconst { watch } = await import('chokidar');\n\t\tconst watcher = watch(this.source, { ignoreInitial: true });\n\t\tthis.#watcher = watcher;\n\n\t\twatcher.on('all', (event, path) => {\n\t\t\ttry {\n\t\t\t\tconst target = join(this.destination, relative(this.source, path));\n\t\t\t\tif (event === 'unlink' || event === 'unlinkDir') rmSync(target, { recursive: event === 'unlinkDir', force: true });\n\t\t\t\telse if (existsSync(path)) {\n\t\t\t\t\tmkdirSync(dirname(target), { recursive: true });\n\t\t\t\t\tcpSync(path, target, { recursive: event === 'addDir', force: true });\n\t\t\t\t}\n\t\t\t\tthis.emit('change');\n\t\t\t} catch (error) {\n\t\t\t\tthis.emit('log', 'error', `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t});\n\t\twatcher.on('error', (error) => this.emit('log', 'error', error instanceof Error ? error.message : String(error)));\n\t\tawait new Promise<void>((resolve) => watcher.once('ready', resolve));\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst watcher = this.#watcher;\n\t\tthis.#watcher = null;\n\t\tawait watcher?.close();\n\t}\n}\n"],"mappings":";;;;;;;;AAOA,eAAsB,cAAc,QAA6B,OAAyC;CAIzG,IAAI,OAAO,aAAa,oBAAoB;EAC3C,MAAM,EAAE,oBAAoB,MAAM,OAAO;EACzC,OAAO,IAAI,gBAAgB,MAAM;CAClC;CAIA,IAAI,OAAO,aAAa,aAAa;EACpC,MAAM,EAAE,iBAAiB,MAAM,OAAO;EACtC,OAAO,IAAI,aAAa,MAAM;CAC/B;CAEA,QAAQ,OAAO,MAAM,MAArB;EACC,KAAK,UAAU;GACd,MAAM,EAAE,kBAAkB,MAAM,OAAO;GACvC,OAAO,IAAI,cAAc,QAAQ,KAAK;EACvC;EACA,KAAK,QAAQ;GACZ,MAAM,EAAE,gBAAgB,MAAM,OAAO;GACrC,OAAO,IAAI,YAAY,MAAM;EAC9B;EACA,KAAK,OAAO;GACX,MAAM,EAAE,eAAe,MAAM,OAAO;GACpC,OAAO,IAAI,WAAW,MAAM;EAC7B;EACA,KAAK,QAAQ;GACZ,MAAM,EAAE,gBAAgB,MAAM,OAAO;GACrC,OAAO,IAAI,YAAY,MAAM;EAC9B;CACD;AACD;;;;;AC7BA,IAAa,UAAb,cAA6B,aAA4B;CAKpB;CAJpC,AAAS;CACT,AAAS;CACT,WAA8C;CAE9C,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;EAEnC,KAAK,SAAS,KAAK,OAAO,MAAM,OAAO,SAAS;EAChD,KAAK,cAAc,KAAK,OAAO,MAAM,QAAQ,SAAS;CACvD;CAEA,AAAO,OAAgB;EACtB,IAAI,KAAK,OAAO,MAAM,SAAS,UAAU,CAAC,WAAW,KAAK,MAAM,GAAG,OAAO;EAC1E,UAAU,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;EAC/C,OAAO,KAAK,QAAQ,KAAK,aAAa;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACtE,OAAO;CACR;CAEA,MAAa,QAAuB;EACnC,IAAI,KAAK,OAAO,MAAM,SAAS,UAAU,CAAC,WAAW,KAAK,MAAM,KAAK,KAAK,UAAU;EACpF,MAAM,EAAE,UAAU,MAAM,OAAO;EAC/B,MAAM,UAAU,MAAM,KAAK,QAAQ,EAAE,eAAe,KAAK,CAAC;EAC1D,KAAK,WAAW;EAEhB,QAAQ,GAAG,QAAQ,OAAO,SAAS;GAClC,IAAI;IACH,MAAM,SAAS,KAAK,KAAK,aAAa,SAAS,KAAK,QAAQ,IAAI,CAAC;IACjE,IAAI,UAAU,YAAY,UAAU,aAAa,OAAO,QAAQ;KAAE,WAAW,UAAU;KAAa,OAAO;IAAK,CAAC;SAC5G,IAAI,WAAW,IAAI,GAAG;KAC1B,UAAU,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;KAC9C,OAAO,MAAM,QAAQ;MAAE,WAAW,UAAU;MAAU,OAAO;KAAK,CAAC;IACpE;IACA,KAAK,KAAK,QAAQ;GACnB,SAAS,OAAO;IACf,KAAK,KAAK,OAAO,SAAS,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;GAC9G;EACD,CAAC;EACD,QAAQ,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;EAChH,MAAM,IAAI,SAAe,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;CACpE;CAEA,MAAa,QAAuB;EACnC,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW;EAChB,MAAM,SAAS,MAAM;CACtB;AACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nitro-sP2F3SQu.js","names":["ServerBuilder"],"sources":["../src/builders/nitro.ts"],"sourcesContent":["import { NitroBuilder as ServerBuilder } from '@wolfstar/nitro-server';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { pluginRegistrations } from '../utils/plugin-registrations.js';\nimport { importFromProject } from '../utils/project.js';\n\n/** Connect the server integration to the CLI's diagnostics and plugin discovery. */\nexport class NitroBuilder extends ServerBuilder {\n\tpublic constructor(config: ResolvedStarsConfig) {\n\t\tsuper(config, { importFromProject, pluginRegistrations });\n\t}\n}\n"],"mappings":";;;;;;AAMA,IAAa,eAAb,cAAkCA,eAAc;CAC/C,AAAO,YAAY,QAA6B;EAC/C,MAAM,QAAQ;GAAE;GAAmB;EAAoB,CAAC;CACzD;AACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prepare-B4ysyG6H.js","names":[],"sources":["../src/commands/prepare.ts"],"sourcesContent":["import { displayPath } from '@wolfstar/schema';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { loadProject } from '../utils/hooks.js';\nimport { prepareProject, reportWarnings } from './_shared.js';\n\nexport { prepareProject } from './_shared.js';\n\nexport interface PrepareTaskOptions extends ProjectArgs {\n\tcheck?: boolean;\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\n/**\n * Generates `.stars/tsconfig.json` and `imports.dts` (see {@link StarsImportsConfig} in `@wolfstar/schema`), the way `nuxt\n * prepare` regenerates `.nuxt/imports.d.ts`. Run automatically by `stars dev` and `stars build` before the first\n * build; `--check` fails instead of writing, for CI.\n */\nexport async function runPrepare(options: PrepareTaskOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { config, hooks } = await loadProject({ cwd: resolveCwd(options), configFile: options.config });\n\tawait reportWarnings(config, (text) => process.stderr.write(`${text}\\n`));\n\tconst result = await prepareProject(config, hooks, Boolean(options.check));\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n\t} else {\n\t\tconst paintConfig = result.tsconfig.status === 'outdated' ? colors.red : colors.green;\n\t\tstdout.write(`${colors.dim('stars')} tsconfig: ${paintConfig(result.tsconfig.status)} ${displayPath(config.root, result.tsconfig.path)}\\n`);\n\t\tif (result.enabled) {\n\t\t\tconst paint = result.status === 'outdated' ? colors.red : colors.green;\n\t\t\tstdout.write(`${colors.dim('stars')} imports: ${paint(result.status)} ${displayPath(config.root, result.dts)}\\n`);\n\t\t}\n\t}\n\n\tif (result.status === 'outdated' || result.tsconfig.status === 'outdated') {\n\t\tthrow cliDiagnostics.PREPARE_OUTDATED({});\n\t}\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'prepare',\n\t\tdescription: 'Generate TypeScript configuration and auto imports declarations'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\tcheck: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Fail when the generated files are out of date instead of writing it',\n\t\t\tdefault: false\n\t\t},\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Print machine-readable JSON',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runPrepare({ config: args.config, cwd: args.cwd, check: args.check, json: args.json });\n\t}\n});\n"],"mappings":";;;;;;;;;;;;;;AAsBA,eAAsB,WAAW,SAA4C;CAC5E,MAAM,SAAS,QAAQ,UAAU,QAAQ;CACzC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,KAAK,CAAC,QAAQ,KAAK,CAAC;CAC3E,MAAM,EAAE,QAAQ,UAAU,MAAM,YAAY;EAAE,KAAK,WAAW,OAAO;EAAG,YAAY,QAAQ;CAAO,CAAC;CACpG,MAAM,eAAe,SAAS,SAAS,QAAQ,OAAO,MAAM,GAAG,KAAK,GAAG,CAAC;CACxE,MAAM,SAAS,MAAM,eAAe,QAAQ,OAAO,QAAQ,QAAQ,KAAK,CAAC;CAEzE,IAAI,QAAQ,MACX,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,GAAG;MAC7C;EACN,MAAM,cAAc,OAAO,SAAS,WAAW,aAAa,OAAO,MAAM,OAAO;EAChF,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,aAAa,YAAY,OAAO,SAAS,MAAM,EAAE,GAAG,YAAY,OAAO,MAAM,OAAO,SAAS,IAAI,EAAE,GAAG;EAC1I,IAAI,OAAO,SAAS;GACnB,MAAM,QAAQ,OAAO,WAAW,aAAa,OAAO,MAAM,OAAO;GACjE,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,YAAY,MAAM,OAAO,MAAM,EAAE,GAAG,YAAY,OAAO,MAAM,OAAO,GAAG,EAAE,GAAG;EACjH;CACD;CAEA,IAAI,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW,YAC9D,MAAM,eAAe,iBAAiB,CAAC,CAAC;AAE1C;AAEA,sBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,OAAO;GACN,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,MAAM;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,WAAW;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,OAAO,KAAK;GAAO,MAAM,KAAK;EAAK,CAAC;CAC5F;AACD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project-MD4dIo2X.js","names":[],"sources":["../src/utils/project.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { cliDiagnostics } from './diagnostics.js';\n\n/**\n * Resolves a module id from the project root, the way the project itself would.\n */\nexport function resolveFromProject(root: string, id: string): string | null {\n\ttry {\n\t\treturn createRequire(join(root, 'package.json')).resolve(id);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Imports a module from the project root, failing with an actionable error when it is not installed.\n */\nexport async function importFromProject<T>(root: string, id: string, hint: string): Promise<T> {\n\tconst resolved = resolveFromProject(root, id);\n\tif (!resolved) {\n\t\tthrow cliDiagnostics.DEPENDENCY_MISSING({ name: id, root, hint });\n\t}\n\n\treturn (await import(pathToFileURL(resolved).href)) as T;\n}\n\n/**\n * Resolves an executable a package declares in its `package.json#bin`, from the project's own `node_modules`.\n *\n * Going through `bin` rather than a hardcoded path is what makes this work across layouts: TypeScript 7 hides\n * `lib/tsc.js` behind its `exports` map, and packages move their entry points between releases.\n */\nexport function resolveBinary(root: string, packageName: string, binName: string): string | null {\n\tconst packageJsonPath = resolveFromProject(root, `${packageName}/package.json`);\n\tif (!packageJsonPath) return null;\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { bin?: string | Record<string, string> };\n\t\tconst bin = typeof packageJson.bin === 'string' ? packageJson.bin : packageJson.bin?.[binName];\n\t\treturn bin ? join(dirname(packageJsonPath), bin) : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the version of an installed package by walking `node_modules` up from `root`.\n */\nexport function findInstalledVersion(root: string, name: string): string | null {\n\tlet directory = root;\n\tfor (;;) {\n\t\tconst file = join(directory, 'node_modules', name, 'package.json');\n\t\tif (existsSync(file)) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(readFileSync(file, 'utf-8')) as { version?: string };\n\t\t\t\treturn parsed.version ?? null;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tconst parent = dirname(directory);\n\t\tif (parent === directory) return null;\n\t\tdirectory = parent;\n\t}\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,mBAAmB,MAAc,IAA2B;CAC3E,IAAI;EACH,OAAO,cAAc,KAAK,MAAM,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC5D,QAAQ;EACP,OAAO;CACR;AACD;;;;AAKA,eAAsB,kBAAqB,MAAc,IAAY,MAA0B;CAC9F,MAAM,WAAW,mBAAmB,MAAM,EAAE;CAC5C,IAAI,CAAC,UACJ,MAAM,eAAe,mBAAmB;EAAE,MAAM;EAAI;EAAM;CAAK,CAAC;CAGjE,OAAQ,MAAM,OAAO,cAAc,QAAQ,CAAC,CAAC;AAC9C;;;;;;;AAQA,SAAgB,cAAc,MAAc,aAAqB,SAAgC;CAChG,MAAM,kBAAkB,mBAAmB,MAAM,GAAG,YAAY,cAAc;CAC9E,IAAI,CAAC,iBAAiB,OAAO;CAE7B,IAAI;EACH,MAAM,cAAc,KAAK,MAAM,aAAa,iBAAiB,OAAO,CAAC;EACrE,MAAM,MAAM,OAAO,YAAY,QAAQ,WAAW,YAAY,MAAM,YAAY,MAAM;EACtF,OAAO,MAAM,KAAK,QAAQ,eAAe,GAAG,GAAG,IAAI;CACpD,QAAQ;EACP,OAAO;CACR;AACD;;;;AAKA,SAAgB,qBAAqB,MAAc,MAA6B;CAC/E,IAAI,YAAY;CAChB,SAAS;EACR,MAAM,OAAO,KAAK,WAAW,gBAAgB,MAAM,cAAc;EACjE,IAAI,WAAW,IAAI,GAClB,IAAI;GAEH,OADe,KAAK,MAAM,aAAa,MAAM,OAAO,CACxC,CAAC,CAAC,WAAW;EAC1B,QAAQ;GACP,OAAO;EACR;EAGD,MAAM,SAAS,QAAQ,SAAS;EAChC,IAAI,WAAW,WAAW,OAAO;EACjC,YAAY;CACb;AACD"}
|
package/dist/run-Ddwrxe1O.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-Ddwrxe1O.js","names":["_runCommand"],"sources":["../src/commands/index.ts","../src/main.ts","../src/run.ts"],"sourcesContent":["import type { CommandDef } from 'citty';\n\n// citty types each command by its own arguments; the registry needs the erased form.\n// oxlint-disable-next-line typescript/no-explicit-any\ntype AnyCommand = CommandDef<any>;\n\nexport const commands: Record<string, () => Promise<AnyCommand>> = {\n\tdev: () => import('./dev.js').then((module) => module.default),\n\tbuild: () => import('./build.js').then((module) => module.default),\n\tinfo: () => import('./info.js').then((module) => module.default),\n\tcodegen: () => import('./codegen.js').then((module) => module.default),\n\tprepare: () => import('./prepare.js').then((module) => module.default),\n\tcommands: () => import('./commands.js').then((module) => module.default)\n};\n","import { defineCommand, type CommandDef } from 'citty';\nimport { commands } from './commands/index.js';\nimport { readOwnPackageJson } from './utils/version.js';\n\n// citty types each command by its own arguments; the registry needs the erased form.\n// oxlint-disable-next-line typescript/no-explicit-any\ntype AnyCommand = CommandDef<any>;\n\nconst packageJson = readOwnPackageJson();\n\nexport const main = defineCommand({\n\tmeta: {\n\t\tname: 'stars',\n\t\tversion: packageJson.version,\n\t\tdescription: packageJson.description\n\t},\n\tsubCommands: commands\n}) as AnyCommand;\n","import { renderUsage, runCommand as _runCommand, type CommandDef } from 'citty';\nimport process from 'node:process';\nimport { commands } from './commands/index.js';\nimport { main } from './main.js';\nimport { exitCodeOf, formatError } from './utils/errors.js';\nimport { readOwnPackageJson } from './utils/version.js';\n\n// citty types each command by its own arguments; the registry needs the erased form.\n// oxlint-disable-next-line typescript/no-explicit-any\ntype AnyCommand = CommandDef<any>;\n\n/**\n * Walks the command names of `stars <command> [<subcommand>] --help` so nested commands (`stars commands clean`)\n * render their own usage instead of their parent's.\n */\nasync function resolveHelpTarget(names: string[]): Promise<AnyCommand | null> {\n\tconst [first, ...rest] = names;\n\tif (!first || !Object.hasOwn(commands, first)) return null;\n\n\tlet command = await commands[first]!();\n\tfor (const name of rest) {\n\t\tconst resolved = typeof command.subCommands === 'function' ? await command.subCommands() : await command.subCommands;\n\t\tconst child: unknown = (resolved as Record<string, unknown> | undefined)?.[name];\n\t\tif (!child) break;\n\t\tcommand = (typeof child === 'function' ? await child() : child) as AnyCommand;\n\t}\n\n\treturn command;\n}\n\nexport async function runMain(argv: string[] = process.argv.slice(2)): Promise<void> {\n\tif (argv.includes('--version') || argv.includes('-V')) {\n\t\tconsole.log(readOwnPackageJson().version);\n\t\tprocess.exit(0);\n\t}\n\n\tif (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) {\n\t\t// citty's showUsage logs through consola, which is muted in some environments; render and print directly.\n\t\tconst command = await resolveHelpTarget(argv.filter((argument) => !argument.startsWith('-')));\n\t\tconsole.log(await (command ? renderUsage(command, main) : renderUsage(main)));\n\t\tprocess.exit(0);\n\t}\n\n\ttry {\n\t\tawait _runCommand(main, { rawArgs: argv });\n\t} catch (error) {\n\t\tconsole.error(await formatError(error));\n\t\tprocess.exit(exitCodeOf(error));\n\t}\n}\n"],"mappings":";;;;;;AAMA,MAAa,WAAsD;CAClE,WAAW,OAAO,oBAAW,CAAC,MAAM,WAAW,OAAO,OAAO;CAC7D,aAAa,OAAO,sBAAa,CAAC,MAAM,WAAW,OAAO,OAAO;CACjE,YAAY,OAAO,qBAAY,CAAC,MAAM,WAAW,OAAO,OAAO;CAC/D,eAAe,OAAO,wBAAe,CAAC,MAAM,WAAW,OAAO,OAAO;CACrE,eAAe,OAAO,wBAAe,CAAC,MAAM,WAAW,OAAO,OAAO;CACrE,gBAAgB,OAAO,yBAAgB,CAAC,MAAM,WAAW,OAAO,OAAO;AACxE;;;;ACLA,MAAM,cAAc,mBAAmB;AAEvC,MAAa,OAAO,cAAc;CACjC,MAAM;EACL,MAAM;EACN,SAAS,YAAY;EACrB,aAAa,YAAY;CAC1B;CACA,aAAa;AACd,CAAC;;;;;;;;ACFD,eAAe,kBAAkB,OAA6C;CAC7E,MAAM,CAAC,OAAO,GAAG,QAAQ;CACzB,IAAI,CAAC,SAAS,CAAC,OAAO,OAAO,UAAU,KAAK,GAAG,OAAO;CAEtD,IAAI,UAAU,MAAM,SAAS,MAAM,CAAE;CACrC,KAAK,MAAM,QAAQ,MAAM;EAExB,MAAM,SADW,OAAO,QAAQ,gBAAgB,aAAa,MAAM,QAAQ,YAAY,IAAI,MAAM,QAAQ,YACzE,GAA2C;EAC3E,IAAI,CAAC,OAAO;EACZ,UAAW,OAAO,UAAU,aAAa,MAAM,MAAM,IAAI;CAC1D;CAEA,OAAO;AACR;AAEA,eAAsB,QAAQ,OAAiB,QAAQ,KAAK,MAAM,CAAC,GAAkB;CACpF,IAAI,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,IAAI,GAAG;EACtD,QAAQ,IAAI,mBAAmB,CAAC,CAAC,OAAO;EACxC,QAAQ,KAAK,CAAC;CACf;CAEA,IAAI,KAAK,WAAW,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;EAExE,MAAM,UAAU,MAAM,kBAAkB,KAAK,QAAQ,aAAa,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC;EAC5F,QAAQ,IAAI,OAAO,UAAU,YAAY,SAAS,IAAI,IAAI,YAAY,IAAI,EAAE;EAC5E,QAAQ,KAAK,CAAC;CACf;CAEA,IAAI;EACH,MAAMA,WAAY,MAAM,EAAE,SAAS,KAAK,CAAC;CAC1C,SAAS,OAAO;EACf,QAAQ,MAAM,MAAM,YAAY,KAAK,CAAC;EACtC,QAAQ,KAAK,WAAW,KAAK,CAAC;CAC/B;AACD"}
|
package/dist/tsc-DO7D_uCl.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tsc-DO7D_uCl.js","names":[],"sources":["../src/utils/process-supervisor.ts","../src/builders/tsc.ts"],"sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\n\nexport type ProcessState = 'idle' | 'starting' | 'running' | 'stopping' | 'stopped' | 'crashed';\n\nexport interface ProcessExit {\n\tcode: number | null;\n\tsignal: NodeJS.Signals | null;\n\t/** Whether the exit was requested through {@link ProcessSupervisor.stop}. */\n\trequested: boolean;\n}\n\nexport interface ProcessSupervisorOptions {\n\tcommand: string;\n\targs: readonly string[];\n\tcwd: string;\n\tenv: NodeJS.ProcessEnv;\n\t/** Milliseconds to wait after `SIGTERM` before sending `SIGKILL`. */\n\tkillTimeout: number;\n}\n\nexport interface ProcessSupervisorEvents {\n\tstate: [state: ProcessState];\n\tstdout: [line: string];\n\tstderr: [line: string];\n\texit: [exit: ProcessExit];\n\terror: [error: Error];\n}\n\n/**\n * Owns a single child process: starts it, streams its output line by line and stops it gracefully.\n */\nexport class ProcessSupervisor extends EventEmitter<ProcessSupervisorEvents> {\n\t#child: ChildProcess | null = null;\n\t#state: ProcessState = 'idle';\n\t#startedAt: number | null = null;\n\t#stopping: Promise<void> | null = null;\n\n\tpublic constructor(private readonly options: ProcessSupervisorOptions) {\n\t\tsuper();\n\t}\n\n\tpublic get state(): ProcessState {\n\t\treturn this.#state;\n\t}\n\n\tpublic get pid(): number | null {\n\t\treturn this.#child?.pid ?? null;\n\t}\n\n\tpublic get startedAt(): number | null {\n\t\treturn this.#startedAt;\n\t}\n\n\tpublic get running(): boolean {\n\t\treturn this.#state === 'starting' || this.#state === 'running';\n\t}\n\n\tpublic start(): void {\n\t\tif (this.#child) throw new Error('The process is already running, call stop() or restart() first.');\n\n\t\tconst { command, args, cwd, env } = this.options;\n\t\tthis.#setState('starting');\n\n\t\tconst child = spawn(command, args, { cwd, env, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });\n\t\tthis.#child = child;\n\t\tthis.#startedAt = Date.now();\n\n\t\tlet requested = false;\n\t\tconst stdout = createLineSplitter((line) => this.emit('stdout', line));\n\t\tconst stderr = createLineSplitter((line) => this.emit('stderr', line));\n\t\tchild.stdout?.on('data', stdout.push);\n\t\tchild.stderr?.on('data', stderr.push);\n\n\t\tchild.once('spawn', () => {\n\t\t\tif (this.#child === child) this.#setState('running');\n\t\t});\n\n\t\tchild.once('error', (error) => {\n\t\t\tthis.emit('error', error);\n\t\t});\n\n\t\tchild.once('exit', (code, signal) => {\n\t\t\tstdout.flush();\n\t\t\tstderr.flush();\n\t\t\trequested = this.#state === 'stopping';\n\t\t\tthis.#child = null;\n\t\t\tthis.#startedAt = null;\n\t\t\tthis.#setState(requested || code === 0 ? 'stopped' : 'crashed');\n\t\t\tthis.emit('exit', { code, signal, requested });\n\t\t});\n\t}\n\n\t/**\n\t * Sends `SIGTERM`, escalates to `SIGKILL` after `killTimeout` and resolves once the process exited.\n\t */\n\tpublic stop(): Promise<void> {\n\t\tconst child = this.#child;\n\t\tif (!child) return Promise.resolve();\n\t\tif (this.#stopping) return this.#stopping;\n\n\t\tthis.#setState('stopping');\n\t\tthis.#stopping = new Promise<void>((resolve) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tif (child.exitCode === null && child.signalCode === null) child.kill('SIGKILL');\n\t\t\t}, this.options.killTimeout);\n\t\t\ttimer.unref();\n\n\t\t\tchild.once('exit', () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.#stopping = null;\n\t\t\t\tresolve();\n\t\t\t});\n\n\t\t\tif (!child.kill('SIGTERM')) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.#stopping = null;\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\n\t\treturn this.#stopping;\n\t}\n\n\t/**\n\t * Sends `SIGKILL` right away, without waiting for the process to exit. Used to force a shutdown that is taking too long.\n\t */\n\tpublic kill(): void {\n\t\tconst child = this.#child;\n\t\tif (child && child.exitCode === null && child.signalCode === null) child.kill('SIGKILL');\n\t}\n\n\tpublic async restart(): Promise<void> {\n\t\tawait this.stop();\n\t\tthis.start();\n\t}\n\n\t#setState(state: ProcessState): void {\n\t\tif (this.#state === state) return;\n\t\tthis.#state = state;\n\t\tthis.emit('state', state);\n\t}\n}\n\n/**\n * Splits a byte stream into complete lines, keeping the trailing partial line until the next chunk.\n */\nexport function createLineSplitter(onLine: (line: string) => void) {\n\tlet remainder = '';\n\treturn {\n\t\tpush(chunk: Buffer | string) {\n\t\t\tremainder += chunk.toString();\n\t\t\tconst lines = remainder.split(/\\r?\\n/);\n\t\t\tremainder = lines.pop() ?? '';\n\t\t\tfor (const line of lines) onLine(line);\n\t\t},\n\t\tflush() {\n\t\t\tif (remainder.length > 0) onLine(remainder);\n\t\t\tremainder = '';\n\t\t}\n\t};\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { createLineSplitter } from '../utils/process-supervisor.js';\nimport { resolveBinary } from '../utils/project.js';\nimport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n\nconst INSTALL_HINT = \"Install it with `pnpm add -D typescript`, or set `build.tool` to 'tsdown' or 'none'.\";\nconst WATCH_START = /Starting (incremental )?compilation/;\nconst WATCH_DONE = /Found (\\d+) errors?\\. Watching for file changes/;\nconst ERROR_LINE = /error TS\\d+:/;\n\n/**\n * Builds through the project's `tsc -b`, parsing its output to report progress.\n */\nexport class TscBuilder extends EventEmitter<BuilderEvents> implements Builder {\n\tpublic readonly tool = 'tsc' as const;\n\t#child: ChildProcess | null = null;\n\t#startedAt = 0;\n\t#firstError: string | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t}\n\n\tpublic build(): Promise<BuildOutcome> {\n\t\tconst child = this.#spawn([]);\n\t\tthis.#begin();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once('exit', (code) => {\n\t\t\t\tthis.#child = null;\n\t\t\t\tresolve(this.#finish(code === 0 ? null : (this.#firstError ?? `tsc exited with code ${code}`)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic watch(): Promise<void> {\n\t\tthis.#spawn(['--watch', '--preserveWatchOutput']);\n\t\tthis.#begin();\n\t\treturn Promise.resolve();\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tconst child = this.#child;\n\t\tthis.#child = null;\n\t\tif (!child || child.exitCode !== null) return Promise.resolve();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once('exit', () => resolve());\n\t\t\tchild.kill();\n\t\t});\n\t}\n\n\t#spawn(extraArgs: string[]): ChildProcess {\n\t\tconst tsc = resolveTscBinary(this.config.root);\n\t\tif (!tsc) throw cliDiagnostics.DEPENDENCY_MISSING({ name: 'typescript', root: this.config.root, hint: INSTALL_HINT });\n\n\t\tconst child = spawn(process.execPath, [tsc, '-b', this.config.build.tsconfig!, '--pretty', 'false', ...extraArgs], {\n\t\t\tcwd: this.config.root,\n\t\t\tenv: process.env,\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\twindowsHide: true\n\t\t});\n\t\tthis.#child = child;\n\n\t\tconst handleLine = (line: string) => this.#handleLine(line);\n\t\tconst stdout = createLineSplitter(handleLine);\n\t\tconst stderr = createLineSplitter(handleLine);\n\t\tchild.stdout?.on('data', stdout.push);\n\t\tchild.stderr?.on('data', stderr.push);\n\t\tchild.once('exit', () => {\n\t\t\tstdout.flush();\n\t\t\tstderr.flush();\n\t\t});\n\t\tchild.once('error', (error) => this.emit('log', 'error', error.message));\n\n\t\treturn child;\n\t}\n\n\t#handleLine(line: string): void {\n\t\tconst text = line.trim();\n\t\tif (text.length === 0) return;\n\n\t\tif (WATCH_START.test(text)) {\n\t\t\tif (this.#startedAt === 0) this.#begin();\n\t\t\treturn;\n\t\t}\n\n\t\tif (ERROR_LINE.test(text)) {\n\t\t\tthis.#firstError ??= text;\n\t\t\tthis.emit('log', 'error', text);\n\t\t\treturn;\n\t\t}\n\n\t\tconst done = WATCH_DONE.exec(text);\n\t\tif (done) {\n\t\t\tconst errors = Number(done[1]);\n\t\t\tthis.emit('log', errors === 0 ? 'success' : 'error', text);\n\t\t\tthis.#finish(errors === 0 ? null : (this.#firstError ?? text));\n\t\t\treturn;\n\t\t}\n\n\t\tthis.emit('log', 'info', text);\n\t}\n\n\t#begin(): void {\n\t\tthis.#firstError = null;\n\t\tthis.#startedAt = performance.now();\n\t\tthis.emit('start');\n\t}\n\n\t#finish(message: string | null): BuildOutcome {\n\t\tconst outcome: BuildOutcome = { ok: message === null, durationMs: Math.round(performance.now() - this.#startedAt), message };\n\t\tthis.#startedAt = 0;\n\t\tthis.emit(outcome.ok ? 'success' : 'failure', outcome);\n\t\treturn outcome;\n\t}\n}\n\n/**\n * Locates the `tsc` script of the project's TypeScript through its `package.json#bin`, which works for both the\n * classic `lib/tsc.js` layout (TypeScript ≤ 6) and the native `bin/tsc` launcher (TypeScript 7, whose `exports` map\n * hides `lib/`).\n */\nexport function resolveTscBinary(root: string): string | null {\n\treturn resolveBinary(root, 'typescript', 'tsc');\n}\n"],"mappings":"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"}
|
package/dist/tsc-YnAWKn3n.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tsdown-CD68G8_U.js","names":[],"sources":["../src/builders/tsdown.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport { dirname, extname, relative, resolve } from 'node:path';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { loadAutoImportsModule } from '../utils/framework-auto-imports.js';\nimport type { StarsHookable } from '../utils/hooks.js';\nimport { pluginRegistrations } from '../utils/plugin-registrations.js';\nimport { importFromProject } from '../utils/project.js';\nimport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n\ntype TsdownModule = typeof import('tsdown');\ntype TsdownLogger = import('tsdown').Logger;\ntype TsdownHandle = import('tsdown').TsdownHandle;\ntype TsdownInlineConfig = NonNullable<Parameters<TsdownModule['build']>[0]>;\ntype TsdownOptions = Record<string, unknown>;\ntype AnyFunction = (...args: never[]) => unknown;\n\nconst INSTALL_HINT = \"Install it with `pnpm add -D tsdown`, or set `build.tool` to 'tsc' or 'none'.\";\nconst TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.mts', '.cts']);\n/** `./src/lib` and `../shared` are paths; `preact/compat` is a module id and must be left alone. */\nconst RELATIVE_PATH = /^\\.\\.?[/\\\\]/;\n\n/**\n * Builds through the project's own `tsdown`, configured from `stars.config`.\n *\n * From `future.compatibilityVersion` 4 on this is the whole configuration: the entry's directory, `build.outDir` and\n * `build.tsconfig` produce the defaults a bot needs, the project's `tsdown` block is layered on top, and the auto\n * imports plugin is wired in — one configuration file instead of two. At 3 the project's own `tsdown.config.*` is\n * still loaded and everything here is merged over it by `tsdown` itself: scalars from `stars.config` win, and\n * `plugins` are appended rather than replaced.\n */\nexport class TsdownBuilder extends EventEmitter<BuilderEvents> implements Builder {\n\tpublic readonly tool = 'tsdown' as const;\n\t#handle: TsdownHandle | null = null;\n\t#hadError = false;\n\t#startedAt = 0;\n\n\tpublic constructor(\n\t\tprivate readonly config: ResolvedStarsConfig,\n\t\tprivate readonly hooks?: StarsHookable\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic async build(): Promise<BuildOutcome> {\n\t\tconst tsdown = await this.#load();\n\t\tconst options = await this.#options();\n\t\tthis.#begin();\n\n\t\ttry {\n\t\t\tthis.#handle = await tsdown.build(options as TsdownInlineConfig);\n\t\t\treturn this.#finish(this.#hadError ? 'The build reported errors' : null);\n\t\t} catch (error) {\n\t\t\treturn this.#finish(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tconst tsdown = await this.#load();\n\t\tconst options = await this.#options();\n\n\t\tthis.#begin();\n\t\tthis.#handle = await tsdown.build(this.#watchOptions(options) as TsdownInlineConfig);\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst handle = this.#handle;\n\t\tthis.#handle = null;\n\t\tawait handle?.watch.close();\n\t}\n\n\t#load(): Promise<TsdownModule> {\n\t\treturn importFromProject<TsdownModule>(this.config.root, 'tsdown', INSTALL_HINT);\n\t}\n\n\t/**\n\t * The options handed to `tsdown.build()`, with the project's own `tsdown` block already layered on top of the\n\t * defaults (and of the plugins `stars` contributes).\n\t */\n\tasync #options(): Promise<TsdownOptions> {\n\t\tconst user = this.config.tsdown as TsdownOptions;\n\t\t// A `tsdown.config.*` (or `package.json#tsdown`) is the project's own; `build.configFile` is `null` from\n\t\t// compatibility version 4 on, where loading one is a configuration error rather than a fallback.\n\t\tconst defaults = this.config.build.configFile === null ? this.#defaults() : {};\n\t\tconst plugins = [pluginRegistrations(this.config), ...(await this.#plugins()), ...toArray(user.plugins)];\n\t\t// `plugins` and `alias` are added to rather than replaced: a project declaring one of its own would\n\t\t// otherwise silently drop the auto imports transform, or every `~`/`@` import in its sources.\n\t\tconst alias = { ...(defaults.alias as object), ...this.#alias(user.alias) };\n\n\t\tconst options: TsdownOptions = {\n\t\t\t...defaults,\n\t\t\t...user,\n\t\t\t...(plugins.length > 0 ? { plugins } : {}),\n\t\t\t...(Object.keys(alias).length > 0 ? { alias } : {})\n\t\t};\n\t\tawait this.hooks?.callHook('tsdown:options', options, this.config);\n\n\t\treturn {\n\t\t\t...options,\n\t\t\t// Last, and so not overridable (not even by `tsdown:options`): these are how the CLI talks to `tsdown` rather\n\t\t\t// than project build options — the project root it resolves from, its own compact progress UI, and the logger\n\t\t\t// that feeds diagnostics to the dev panel. `logLevel` also covers the few lifecycle messages tsdown writes\n\t\t\t// through its global logger.\n\t\t\tcwd: this.config.root,\n\t\t\tlogLevel: 'warn',\n\t\t\tcustomLogger: this.#logger()\n\t\t};\n\t}\n\n\t/**\n\t * What `stars.config` alone says the build is — the configuration a bot would otherwise write out by hand, taken\n\t * from the ones the WolfStar bots already keep next to theirs:\n\t *\n\t * - every source file next to the entry (minus tests), emitted one-to-one (`unbundle`) so the stores keep\n\t * loading pieces from `dist/commands` and friends at runtime;\n\t * - ESM on `platform: 'node'`, with the extension `build.output` — and so `stars dev`, `package.json#main` and\n\t * `node dist/…` — expects;\n\t * - sourcemaps and treeshaking on, minification off: a bot is deployed, not shipped, so readable stack traces\n\t * are worth more than bytes;\n\t * - dependencies left in `node_modules` rather than bundled into the output;\n\t * - Nuxt's own alias prefixes: `~` and `@` for the entry's directory, `~~` and `@@` for the project root;\n\t * - no declaration files: nothing consumes a bot's `dist/`, and emitting them roughly doubles the build. A\n\t * project that wants them sets `tsdown: { dts: true }`.\n\t *\n\t * Every one of these is overridable through the project's `tsdown` block.\n\t */\n\t#defaults(): TsdownOptions {\n\t\tconst { root, entry, build } = this.config;\n\t\tconst source = dirname(entry);\n\t\tconst sourceDir = relative(root, source) || '.';\n\t\tconst extensions = TYPESCRIPT_EXTENSIONS.has(extname(entry)) ? '{ts,mts,cts}' : '{js,mjs,cjs}';\n\n\t\treturn {\n\t\t\tconfig: false,\n\t\t\tentry: [`${sourceDir}/**/*.${extensions}`, `!${sourceDir}/**/*.{test,spec}.${extensions}`],\n\t\t\t// The prefixes Nuxt gives every project, pointing at the same two places its own do: the source\n\t\t\t// directory and the project root. A project's tsconfig needs the matching `paths` for them to type.\n\t\t\talias: { '~': source, '@': source, '~~': root, '@@': root },\n\t\t\tformat: 'esm',\n\t\t\tplatform: 'node',\n\t\t\tunbundle: true,\n\t\t\toutDir: build.outDir,\n\t\t\toutExtensions: () => ({ js: extname(build.output) }),\n\t\t\tsourcemap: true,\n\t\t\tclean: true,\n\t\t\ttreeshake: true,\n\t\t\tminify: false,\n\t\t\tdts: false,\n\t\t\tdeps: { neverBundle: true },\n\t\t\t...(build.tsconfig === null ? {} : { tsconfig: build.tsconfig })\n\t\t};\n\t}\n\n\t/**\n\t * The project's own aliases, with relative targets resolved against the project root the way every other path in\n\t * `stars.config` is. Module ids (`preact/compat`) and absolute paths are passed through untouched.\n\t */\n\t#alias(alias: unknown): Record<string, unknown> {\n\t\tif (alias === null || typeof alias !== 'object' || Array.isArray(alias)) return {};\n\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(alias as Record<string, unknown>).map(([key, value]) => [\n\t\t\t\tkey,\n\t\t\t\ttypeof value === 'string' && RELATIVE_PATH.test(value) ? resolve(this.config.root, value) : value\n\t\t\t])\n\t\t);\n\t}\n\n\t/**\n\t * The auto imports transform, the way `nuxt dev` wires its own into the build rather than asking the project to.\n\t * `stars dev`/`stars build` regenerate its declaration file (`stars prepare`) before the first build.\n\t */\n\tasync #plugins(): Promise<unknown[]> {\n\t\tif (!this.config.imports.enabled) return [];\n\n\t\tconst { autoImports } = await loadAutoImportsModule(this.config.root);\n\t\tconst { dirs, presets, exclude, dts } = this.config.imports;\n\t\treturn [await autoImports({ root: this.config.root, dirs, presets, exclude, dts })];\n\t}\n\n\t/**\n\t * Watch mode reports through the same events a single build does. The project's own `hooks`/`onSuccess` still\n\t * run: they are the reason a build is watched at all in some projects.\n\t */\n\t#watchOptions(options: TsdownOptions): TsdownOptions {\n\t\tconst hooks = (options.hooks ?? {}) as Record<string, unknown>;\n\t\tconst prepare = hooks['build:prepare'];\n\t\tconst before = hooks['build:before'];\n\t\tconst done = hooks['build:done'];\n\t\tconst success = options.onSuccess;\n\n\t\treturn {\n\t\t\t...options,\n\t\t\twatch: true,\n\t\t\t// tsdown's build:before runs once when the watcher is configured, not on every rebuild. Rolldown's\n\t\t\t// buildStart is the actual per-build boundary, including recovery after a failed compilation.\n\t\t\tplugins: [\n\t\t\t\t{\n\t\t\t\t\tname: 'stars:dev-progress',\n\t\t\t\t\tbuildStart: () => {\n\t\t\t\t\t\tif (this.#startedAt === 0) this.#begin();\n\t\t\t\t\t\tthis.emit('progress', 0.25, 'bundling app');\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t...toArray(options.plugins)\n\t\t\t],\n\t\t\thooks: {\n\t\t\t\t...hooks,\n\t\t\t\t'build:prepare': async (...args: never[]) => {\n\t\t\t\t\tif (this.#startedAt === 0) this.#begin();\n\t\t\t\t\tif (typeof prepare === 'function') await (prepare as AnyFunction)(...args);\n\t\t\t\t},\n\t\t\t\t'build:before': async (...args: never[]) => {\n\t\t\t\t\tif (typeof before === 'function') await (before as AnyFunction)(...args);\n\t\t\t\t},\n\t\t\t\t'build:done': async (...args: never[]) => {\n\t\t\t\t\tthis.emit('progress', 0.5, 'finishing build');\n\t\t\t\t\tif (typeof done === 'function') await (done as AnyFunction)(...args);\n\t\t\t\t}\n\t\t\t},\n\t\t\tonSuccess: async (...args: never[]) => {\n\t\t\t\tif (typeof success === 'function') await (success as AnyFunction)(...args);\n\t\t\t\tthis.#finish(null);\n\t\t\t}\n\t\t};\n\t}\n\n\t#begin(): void {\n\t\tthis.#hadError = false;\n\t\tthis.#startedAt = performance.now();\n\t\tthis.emit('start');\n\t}\n\n\t#finish(message: string | null): BuildOutcome {\n\t\tconst outcome: BuildOutcome = {\n\t\t\tok: message === null && !this.#hadError,\n\t\t\tdurationMs: Math.round(performance.now() - this.#startedAt),\n\t\t\tmessage\n\t\t};\n\t\tthis.#startedAt = 0;\n\t\tthis.emit(outcome.ok ? 'success' : 'failure', outcome);\n\t\treturn outcome;\n\t}\n\n\t#logger(): TsdownLogger {\n\t\tconst log = (level: 'info' | 'warn' | 'error' | 'success', args: unknown[]) => {\n\t\t\t// tsdown passes its (possibly undefined) name label and other blanks as separate arguments.\n\t\t\tconst text = args\n\t\t\t\t.filter((argument) => argument !== undefined && argument !== null && argument !== false && argument !== '')\n\t\t\t\t.map((argument) => (argument instanceof Error ? (argument.stack ?? argument.message) : String(argument)))\n\t\t\t\t.join(' ');\n\t\t\tthis.emit('log', level, text);\n\t\t};\n\n\t\tconst warned = new Set<string>();\n\t\treturn {\n\t\t\t// `stars` owns the build progress and completion messages. Keeping tsdown at `warn` avoids copying its\n\t\t\t// entry list, target, output table and completion line into the dev session while preserving diagnostics\n\t\t\t// that need action from the project.\n\t\t\tlevel: 'warn',\n\t\t\tinfo: () => {},\n\t\t\twarn: (...args) => log('warn', args),\n\t\t\twarnOnce: (...args) => {\n\t\t\t\tconst key = args.map(String).join(' ');\n\t\t\t\tif (warned.has(key)) return;\n\t\t\t\twarned.add(key);\n\t\t\t\tlog('warn', args);\n\t\t\t},\n\t\t\terror: (...args) => {\n\t\t\t\tthis.#hadError = true;\n\t\t\t\tlog('error', args);\n\t\t\t\t// In watch mode tsdown never calls `onSuccess` after an error, report the failure now.\n\t\t\t\tif (this.#startedAt !== 0) this.#finish(errorSummary(args));\n\t\t\t},\n\t\t\tsuccess: () => {},\n\t\t\tclearScreen: () => {}\n\t\t};\n\t}\n}\n\nfunction toArray(value: unknown): unknown[] {\n\tif (value === undefined || value === null || value === false) return [];\n\treturn Array.isArray(value) ? value : [value];\n}\n\nfunction errorSummary(args: unknown[]): string {\n\tconst first = args[0];\n\tif (first instanceof Error) return first.message.split('\\n')[0] ?? 'Build failed';\n\treturn String(first ?? 'Build failed').split('\\n')[0] ?? 'Build failed';\n}\n"],"mappings":";;;;;;;AAgBA,MAAM,eAAe;AACrB,MAAM,wCAAwB,IAAI,IAAI;CAAC;CAAO;CAAQ;AAAM,CAAC;;AAE7D,MAAM,gBAAgB;;;;;;;;;;AAWtB,IAAa,gBAAb,cAAmC,aAA+C;CAO/D;CACA;CAPlB,AAAgB,OAAO;CACvB,UAA+B;CAC/B,YAAY;CACZ,aAAa;CAEb,AAAO,YACN,AAAiB,QACjB,AAAiB,OAChB;EACD,MAAM;EAHW;EACA;CAGlB;CAEA,MAAa,QAA+B;EAC3C,MAAM,SAAS,MAAM,KAAK,MAAM;EAChC,MAAM,UAAU,MAAM,KAAK,SAAS;EACpC,KAAK,OAAO;EAEZ,IAAI;GACH,KAAK,UAAU,MAAM,OAAO,MAAM,OAA6B;GAC/D,OAAO,KAAK,QAAQ,KAAK,YAAY,8BAA8B,IAAI;EACxE,SAAS,OAAO;GACf,OAAO,KAAK,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EAC3E;CACD;CAEA,MAAa,QAAuB;EACnC,MAAM,SAAS,MAAM,KAAK,MAAM;EAChC,MAAM,UAAU,MAAM,KAAK,SAAS;EAEpC,KAAK,OAAO;EACZ,KAAK,UAAU,MAAM,OAAO,MAAM,KAAK,cAAc,OAAO,CAAuB;CACpF;CAEA,MAAa,QAAuB;EACnC,MAAM,SAAS,KAAK;EACpB,KAAK,UAAU;EACf,MAAM,QAAQ,MAAM,MAAM;CAC3B;CAEA,QAA+B;EAC9B,OAAO,kBAAgC,KAAK,OAAO,MAAM,UAAU,YAAY;CAChF;;;;;CAMA,MAAM,WAAmC;EACxC,MAAM,OAAO,KAAK,OAAO;EAGzB,MAAM,WAAW,KAAK,OAAO,MAAM,eAAe,OAAO,KAAK,UAAU,IAAI,CAAC;EAC7E,MAAM,UAAU;GAAC,oBAAoB,KAAK,MAAM;GAAG,GAAI,MAAM,KAAK,SAAS;GAAI,GAAG,QAAQ,KAAK,OAAO;EAAC;EAGvG,MAAM,QAAQ;GAAE,GAAI,SAAS;GAAkB,GAAG,KAAK,OAAO,KAAK,KAAK;EAAE;EAE1E,MAAM,UAAyB;GAC9B,GAAG;GACH,GAAG;GACH,GAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;GACxC,GAAI,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;EAClD;EACA,MAAM,KAAK,OAAO,SAAS,kBAAkB,SAAS,KAAK,MAAM;EAEjE,OAAO;GACN,GAAG;GAKH,KAAK,KAAK,OAAO;GACjB,UAAU;GACV,cAAc,KAAK,QAAQ;EAC5B;CACD;;;;;;;;;;;;;;;;;;CAmBA,YAA2B;EAC1B,MAAM,EAAE,MAAM,OAAO,UAAU,KAAK;EACpC,MAAM,SAAS,QAAQ,KAAK;EAC5B,MAAM,YAAY,SAAS,MAAM,MAAM,KAAK;EAC5C,MAAM,aAAa,sBAAsB,IAAI,QAAQ,KAAK,CAAC,IAAI,iBAAiB;EAEhF,OAAO;GACN,QAAQ;GACR,OAAO,CAAC,GAAG,UAAU,QAAQ,cAAc,IAAI,UAAU,oBAAoB,YAAY;GAGzF,OAAO;IAAE,KAAK;IAAQ,KAAK;IAAQ,MAAM;IAAM,MAAM;GAAK;GAC1D,QAAQ;GACR,UAAU;GACV,UAAU;GACV,QAAQ,MAAM;GACd,sBAAsB,EAAE,IAAI,QAAQ,MAAM,MAAM,EAAE;GAClD,WAAW;GACX,OAAO;GACP,WAAW;GACX,QAAQ;GACR,KAAK;GACL,MAAM,EAAE,aAAa,KAAK;GAC1B,GAAI,MAAM,aAAa,OAAO,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;EAC/D;CACD;;;;;CAMA,OAAO,OAAyC;EAC/C,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;EAEjF,OAAO,OAAO,YACb,OAAO,QAAQ,KAAgC,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACtE,KACA,OAAO,UAAU,YAAY,cAAc,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,MAAM,KAAK,IAAI,KAC7F,CAAC,CACF;CACD;;;;;CAMA,MAAM,WAA+B;EACpC,IAAI,CAAC,KAAK,OAAO,QAAQ,SAAS,OAAO,CAAC;EAE1C,MAAM,EAAE,gBAAgB,MAAM,sBAAsB,KAAK,OAAO,IAAI;EACpE,MAAM,EAAE,MAAM,SAAS,SAAS,QAAQ,KAAK,OAAO;EACpD,OAAO,CAAC,MAAM,YAAY;GAAE,MAAM,KAAK,OAAO;GAAM;GAAM;GAAS;GAAS;EAAI,CAAC,CAAC;CACnF;;;;;CAMA,cAAc,SAAuC;EACpD,MAAM,QAAS,QAAQ,SAAS,CAAC;EACjC,MAAM,UAAU,MAAM;EACtB,MAAM,SAAS,MAAM;EACrB,MAAM,OAAO,MAAM;EACnB,MAAM,UAAU,QAAQ;EAExB,OAAO;GACN,GAAG;GACH,OAAO;GAGP,SAAS,CACR;IACC,MAAM;IACN,kBAAkB;KACjB,IAAI,KAAK,eAAe,GAAG,KAAK,OAAO;KACvC,KAAK,KAAK,YAAY,KAAM,cAAc;IAC3C;GACD,GACA,GAAG,QAAQ,QAAQ,OAAO,CAC3B;GACA,OAAO;IACN,GAAG;IACH,iBAAiB,OAAO,GAAG,SAAkB;KAC5C,IAAI,KAAK,eAAe,GAAG,KAAK,OAAO;KACvC,IAAI,OAAO,YAAY,YAAY,MAAO,QAAwB,GAAG,IAAI;IAC1E;IACA,gBAAgB,OAAO,GAAG,SAAkB;KAC3C,IAAI,OAAO,WAAW,YAAY,MAAO,OAAuB,GAAG,IAAI;IACxE;IACA,cAAc,OAAO,GAAG,SAAkB;KACzC,KAAK,KAAK,YAAY,IAAK,iBAAiB;KAC5C,IAAI,OAAO,SAAS,YAAY,MAAO,KAAqB,GAAG,IAAI;IACpE;GACD;GACA,WAAW,OAAO,GAAG,SAAkB;IACtC,IAAI,OAAO,YAAY,YAAY,MAAO,QAAwB,GAAG,IAAI;IACzE,KAAK,QAAQ,IAAI;GAClB;EACD;CACD;CAEA,SAAe;EACd,KAAK,YAAY;EACjB,KAAK,aAAa,YAAY,IAAI;EAClC,KAAK,KAAK,OAAO;CAClB;CAEA,QAAQ,SAAsC;EAC7C,MAAM,UAAwB;GAC7B,IAAI,YAAY,QAAQ,CAAC,KAAK;GAC9B,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,KAAK,UAAU;GAC1D;EACD;EACA,KAAK,aAAa;EAClB,KAAK,KAAK,QAAQ,KAAK,YAAY,WAAW,OAAO;EACrD,OAAO;CACR;CAEA,UAAwB;EACvB,MAAM,OAAO,OAA8C,SAAoB;GAE9E,MAAM,OAAO,KACX,QAAQ,aAAa,aAAa,UAAa,aAAa,QAAQ,aAAa,SAAS,aAAa,EAAE,CAAC,CAC1G,KAAK,aAAc,oBAAoB,QAAS,SAAS,SAAS,SAAS,UAAW,OAAO,QAAQ,CAAE,CAAC,CACxG,KAAK,GAAG;GACV,KAAK,KAAK,OAAO,OAAO,IAAI;EAC7B;EAEA,MAAM,yBAAS,IAAI,IAAY;EAC/B,OAAO;GAIN,OAAO;GACP,YAAY,CAAC;GACb,OAAO,GAAG,SAAS,IAAI,QAAQ,IAAI;GACnC,WAAW,GAAG,SAAS;IACtB,MAAM,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,KAAK,GAAG;IACrC,IAAI,OAAO,IAAI,GAAG,GAAG;IACrB,OAAO,IAAI,GAAG;IACd,IAAI,QAAQ,IAAI;GACjB;GACA,QAAQ,GAAG,SAAS;IACnB,KAAK,YAAY;IACjB,IAAI,SAAS,IAAI;IAEjB,IAAI,KAAK,eAAe,GAAG,KAAK,QAAQ,aAAa,IAAI,CAAC;GAC3D;GACA,eAAe,CAAC;GAChB,mBAAmB,CAAC;EACrB;CACD;AACD;AAEA,SAAS,QAAQ,OAA2B;CAC3C,IAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,OAAO,OAAO,CAAC;CACtE,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC7C;AAEA,SAAS,aAAa,MAAyB;CAC9C,MAAM,QAAQ,KAAK;CACnB,IAAI,iBAAiB,OAAO,OAAO,MAAM,QAAQ,MAAM,IAAI,CAAC,CAAC,MAAM;CACnE,OAAO,OAAO,SAAS,cAAc,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM;AAC1D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel-DT1FH6oA.js","names":[],"sources":["../src/dev/tunnel.ts"],"sourcesContent":["import type { ResolvedStarsConfig, ResolvedTunnelConfig } from '@wolfstar/schema';\nimport { readProjectEnv } from '../utils/project-env.js';\nimport { EventEmitter } from 'node:events';\nimport { startTunnel, type Tunnel as UntunTunnel } from 'untun';\nimport type { LogLevel } from '../utils/log-buffer.js';\n\nexport type TunnelState = 'off' | 'starting' | 'up' | 'failed';\n\nexport interface TunnelEvents {\n\tlog: [level: LogLevel, text: string];\n\tstate: [state: TunnelState, url: string | null];\n}\n\nexport interface TunnelOptions {\n\t/** Override for tests. */\n\tstartTunnel?: typeof startTunnel;\n}\n\n/**\n * Exposes the bot's interactions endpoint publicly while `stars dev` runs.\n *\n * `dev.tunnel: true` opens a `cloudflared` quick tunnel via `untun` (it changes on every run); a configured https\n * URL is only probed, since the user already serves it. Writing the URL to the Discord application is opt-in\n * through `dev.tunnel.updateEndpoint`, because it edits a live application.\n */\nexport class Tunnel extends EventEmitter<TunnelEvents> {\n\t#startTunnel: typeof startTunnel;\n\t#tunnel: UntunTunnel | null = null;\n\t#state: TunnelState = 'off';\n\t#url: string | null = null;\n\t#wanted = false;\n\n\tpublic constructor(\n\t\tprivate readonly config: ResolvedStarsConfig,\n\t\toptions: TunnelOptions = {}\n\t) {\n\t\tsuper();\n\t\tthis.#startTunnel = options.startTunnel ?? startTunnel;\n\t}\n\n\tpublic get state(): TunnelState {\n\t\treturn this.#state;\n\t}\n\n\t/** The public URL of the interactions endpoint, `null` until the tunnel is up. */\n\tpublic get url(): string | null {\n\t\treturn this.#url;\n\t}\n\n\tpublic async start(forceQuick = false): Promise<void> {\n\t\tif (this.#state === 'starting' || this.#state === 'up') return;\n\t\tconst configured = this.config.dev.tunnel;\n\t\tconst tunnel: ResolvedTunnelConfig =\n\t\t\tforceQuick && configured.mode === 'off' ? { mode: 'quick', path: '/', updateEndpoint: false } : configured;\n\t\tif (tunnel.mode === 'off') return;\n\n\t\tthis.#wanted = true;\n\t\tthis.#setState('starting', null);\n\t\tconst url = tunnel.mode === 'url' ? await this.#useConfiguredUrl(tunnel) : await this.#openQuickTunnel();\n\t\tif (!url || !this.#wanted) return;\n\n\t\tthis.#setState('up', endpointUrl(url, tunnel.path));\n\t\tthis.emit('log', 'success', `Tunnel ready at ${this.#url}`);\n\t\tif (tunnel.updateEndpoint) await this.#updateInteractionsEndpoint(this.#url!);\n\t}\n\n\t/** Toggles the configured tunnel, opening a quick tunnel when the project did not configure one. */\n\tpublic toggle(): Promise<void> {\n\t\treturn this.#state === 'starting' || this.#state === 'up' ? this.close() : this.start(true);\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tthis.#wanted = false;\n\t\tconst tunnel = this.#tunnel;\n\t\tthis.#tunnel = null;\n\t\tthis.#setState('off', null);\n\t\tif (tunnel) await tunnel.close();\n\t}\n\n\tasync #useConfiguredUrl(tunnel: Extract<ResolvedTunnelConfig, { mode: 'url' }>): Promise<string | null> {\n\t\tconst reachable = await probe(endpointUrl(tunnel.url, tunnel.path));\n\t\tif (!reachable) {\n\t\t\tthis.emit('log', 'warn', `${tunnel.url} did not answer; make sure it forwards to ${this.config.dev.url ?? 'the bot'}`);\n\t\t}\n\n\t\treturn tunnel.url;\n\t}\n\n\tasync #openQuickTunnel(): Promise<string | null> {\n\t\tconst target = this.config.dev.url;\n\t\tif (!target) {\n\t\t\tthis.emit('log', 'error', 'A quick tunnel needs `dev.url` to know what to forward to');\n\t\t\tthis.#setState('failed', null);\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.emit('log', 'info', 'Opening a cloudflared quick tunnel…');\n\n\t\ttry {\n\t\t\tconst tunnel = await this.#startTunnel({ url: target, acceptCloudflareNotice: true });\n\t\t\tif (!this.#wanted) {\n\t\t\t\tawait tunnel?.close();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!tunnel) {\n\t\t\t\tthis.emit('log', 'error', 'cloudflared setup was cancelled');\n\t\t\t\tthis.#setState('failed', null);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tthis.#tunnel = tunnel;\n\t\t\treturn await tunnel.getURL();\n\t\t} catch (error) {\n\t\t\tthis.emit('log', 'error', `cloudflared failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\tthis.#setState('failed', null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Points the Discord application's interactions endpoint at the tunnel. Discord validates the endpoint with a\n\t * signed ping before accepting it, so the bot has to be up already — this runs after the first successful build.\n\t */\n\tasync #updateInteractionsEndpoint(url: string): Promise<void> {\n\t\tconst credentials = readDiscordCredentials(this.config);\n\t\tif (!credentials) {\n\t\t\tthis.emit('log', 'warn', 'Skipped the interactions endpoint update: DISCORD_TOKEN is not set');\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch('https://discord.com/api/v10/applications/@me', {\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\theaders: { authorization: `Bot ${credentials.token}`, 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ interactions_endpoint_url: url }),\n\t\t\t\tsignal: AbortSignal.timeout(10_000)\n\t\t\t});\n\n\t\t\tif (response.ok) this.emit('log', 'success', `Interactions endpoint set to ${url}`);\n\t\t\telse\n\t\t\t\tthis.emit(\n\t\t\t\t\t'log',\n\t\t\t\t\t'error',\n\t\t\t\t\t`Discord rejected the interactions endpoint (${response.status}): ${(await response.text()).slice(0, 300)}`\n\t\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.emit('log', 'error', `Failed to update the interactions endpoint: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\t#setState(state: TunnelState, url: string | null): void {\n\t\tthis.#state = state;\n\t\tthis.#url = url;\n\t\tthis.emit('state', state, url);\n\t}\n}\n\n/**\n * Joins the tunnel's origin with the path the interactions endpoint is served on.\n */\nexport function endpointUrl(origin: string, path: string): string {\n\treturn path === '/' ? origin : new URL(path, origin.endsWith('/') ? origin : `${origin}/`).href;\n}\n\nasync function probe(url: string): Promise<boolean> {\n\ttry {\n\t\tconst response = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(5000) });\n\t\treturn response.status < 500;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport interface DiscordCredentials {\n\ttoken: string;\n\tapplicationId: string | null;\n}\n\n/**\n * Reads the Discord credentials the CLI needs from the environment, falling back to the project's `.env` files the\n * way the bot itself does once it starts.\n */\nexport function readDiscordCredentials(config: ResolvedStarsConfig, env: NodeJS.ProcessEnv = process.env): DiscordCredentials | null {\n\tconst fromFiles = readProjectEnvFilesCached(config);\n\tconst read = (...keys: string[]): string | null => {\n\t\tfor (const key of keys) {\n\t\t\tconst value = config.dev.env[key] ?? env[key] ?? fromFiles[key];\n\t\t\tif (value) return value;\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst token = read('DISCORD_TOKEN', 'TOKEN');\n\tif (!token) return null;\n\n\treturn { token, applicationId: read('DISCORD_APPLICATION_ID', 'APPLICATION_ID', 'DISCORD_CLIENT_ID', 'CLIENT_ID') };\n}\n\nlet envFileCache: { key: string; values: Record<string, string> } | null = null;\n\n/** The variables the bot loads (see {@link readProjectEnv}), once per project and `env` options. */\nfunction readProjectEnvFilesCached(config: ResolvedStarsConfig): Record<string, string> {\n\tconst key = JSON.stringify([config.root, config.env.options]);\n\tif (envFileCache?.key !== key) envFileCache = { key, values: readProjectEnv(config) };\n\treturn envFileCache.values;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vite-CLyB6wl7.js","names":["ServerBuilder"],"sources":["../src/builders/vite.ts"],"sourcesContent":["import { ViteBuilder as ServerBuilder } from '@wolfstar/vite-server';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { pluginRegistrations } from '../utils/plugin-registrations.js';\nimport { importFromProject } from '../utils/project.js';\n\n/** Connect the server integration to the CLI's diagnostics and plugin discovery. */\nexport class ViteBuilder extends ServerBuilder {\n\tpublic constructor(config: ResolvedStarsConfig) {\n\t\tsuper(config, { importFromProject, pluginRegistrations });\n\t}\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,cAAiCA,cAAc;CAC9C,AAAO,YAAY,QAA6B;EAC/C,MAAM,QAAQ;GAAE;GAAmB;EAAoB,CAAC;CACzD;AACD"}
|