@korajs/cli 0.6.0 → 1.0.0-beta.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 +21 -0
- package/dist/bin.cjs +2582 -202
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +152 -96
- package/dist/bin.js.map +1 -1
- package/dist/chunk-5NI2FEQL.js +92 -0
- package/dist/chunk-5NI2FEQL.js.map +1 -0
- package/dist/chunk-6C4BHSRA.js +82 -0
- package/dist/chunk-6C4BHSRA.js.map +1 -0
- package/dist/{chunk-VLTPEATY.js → chunk-B5YS4STN.js} +9 -96
- package/dist/chunk-B5YS4STN.js.map +1 -0
- package/dist/{chunk-EEZNRI5W.js → chunk-BWTKRKNJ.js} +13 -5
- package/dist/{chunk-EEZNRI5W.js.map → chunk-BWTKRKNJ.js.map} +1 -1
- package/dist/{chunk-Q2FBCOQD.js → chunk-EOWLAAIV.js} +5 -3
- package/dist/{chunk-Q2FBCOQD.js.map → chunk-EOWLAAIV.js.map} +1 -1
- package/dist/create.cjs +8 -2
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +3 -2
- package/dist/create.js.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lab-manager-KUDII6BT.js +280 -0
- package/dist/lab-manager-KUDII6BT.js.map +1 -0
- package/dist/schema-loader-GGHECMTM.js +9 -0
- package/dist/schema-loader-GGHECMTM.js.map +1 -0
- package/dist/spectator-manager-E2LH2P54.js +142 -0
- package/dist/spectator-manager-E2LH2P54.js.map +1 -0
- package/dist/studio-server-NIFKZI4F.js +1738 -0
- package/dist/studio-server-NIFKZI4F.js.map +1 -0
- package/package.json +8 -6
- package/templates/react-basic/AGENTS.md +87 -0
- package/templates/react-sync/AGENTS.md +87 -0
- package/templates/react-sync/src/App.tsx +8 -0
- package/templates/react-sync/src/index.css +11 -0
- package/templates/react-tailwind/AGENTS.md +87 -0
- package/templates/react-tailwind-sync/AGENTS.md +87 -0
- package/templates/react-tailwind-sync/src/App.tsx +28 -0
- package/templates/svelte-basic/AGENTS.md +76 -0
- package/templates/svelte-basic/src/App.svelte +27 -31
- package/templates/svelte-basic/src/Root.svelte +4 -4
- package/templates/svelte-basic/src/modules/todos/useTodos.ts +1 -1
- package/templates/svelte-basic/vite.config.ts +1 -1
- package/templates/svelte-sync/AGENTS.md +76 -0
- package/templates/svelte-sync/src/App.svelte +31 -35
- package/templates/svelte-sync/src/Root.svelte +6 -6
- package/templates/svelte-sync/src/modules/todos/useTodos.ts +1 -1
- package/templates/svelte-tailwind/AGENTS.md +76 -0
- package/templates/svelte-tailwind/src/App.svelte +17 -21
- package/templates/svelte-tailwind/src/Root.svelte +4 -4
- package/templates/svelte-tailwind/src/modules/todos/useTodos.ts +1 -1
- package/templates/svelte-tailwind/vite.config.ts +2 -2
- package/templates/svelte-tailwind-sync/AGENTS.md +76 -0
- package/templates/svelte-tailwind-sync/src/App.svelte +52 -56
- package/templates/svelte-tailwind-sync/src/Root.svelte +6 -6
- package/templates/svelte-tailwind-sync/src/modules/todos/useTodos.ts +1 -1
- package/templates/svelte-tailwind-sync/vite.config.ts +1 -1
- package/templates/tauri-react/AGENTS.md +91 -0
- package/templates/vue-basic/AGENTS.md +84 -0
- package/templates/vue-basic/src/modules/todos/useTodos.ts +1 -1
- package/templates/vue-sync/AGENTS.md +84 -0
- package/templates/vue-sync/src/main.ts +5 -1
- package/templates/vue-sync/src/modules/todos/useTodos.ts +1 -1
- package/templates/vue-tailwind/AGENTS.md +84 -0
- package/templates/vue-tailwind/src/App.vue +1 -8
- package/templates/vue-tailwind/src/modules/todos/useTodos.ts +1 -1
- package/templates/vue-tailwind-sync/AGENTS.md +84 -0
- package/templates/vue-tailwind-sync/src/modules/todos/useTodos.ts +1 -1
- package/dist/chunk-VLTPEATY.js.map +0 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working in this project. Humans: this is useful for you too.
|
|
4
|
+
|
|
5
|
+
## What this project is
|
|
6
|
+
|
|
7
|
+
This is a **Kora.js** application: an offline-first app where all data lives in a local SQLite database (WASM + OPFS in the browser) and optionally syncs across devices through a Kora sync server. Offline is the normal state, not an error state. Full docs: https://korajs.dev and machine-readable index at https://korajs.dev/llms.txt (complete docs in one file: https://korajs.dev/llms-full.txt).
|
|
8
|
+
|
|
9
|
+
## Golden rules
|
|
10
|
+
|
|
11
|
+
1. **The schema is the source of truth.** All collections are defined in `src/schema.ts` with `defineSchema` and the `t.*` field builders. To add or change data shapes, edit the schema first; types flow from it automatically. Never hand-write types for records.
|
|
12
|
+
2. **Never fetch application data over HTTP.** Do not add REST or GraphQL calls for app data, and do not talk to the sync server directly. Read and write through Kora collections only; sync happens automatically in the background.
|
|
13
|
+
3. **Await readiness before direct collection access.** Outside the UI bindings, `await app.ready` before calling `app.<collection>` methods. The bindings handle this for you inside components.
|
|
14
|
+
4. **Offline must keep working.** Any feature you add must function with the network off. Never gate a write or a read on connectivity. If you find yourself checking `navigator.onLine` before a data operation, you are doing it wrong.
|
|
15
|
+
5. **Surface mutation errors.** Fire-and-forget mutate calls swallow errors into the mutation state. Always render the mutation's `error` in the UI or handle the promise from the async variant. Silent failure is the worst failure.
|
|
16
|
+
6. **Do not touch `src/kora-worker.ts`.** It wires the SQLite WASM binary URL for both dev and production builds. Changing it breaks production builds in ways that only show up after deploy.
|
|
17
|
+
7. **Do not add a state management library for server or app data.** Kora's reactive queries are the store. Local UI state (form inputs, toggles) can use the framework's normal state tools.
|
|
18
|
+
|
|
19
|
+
## Data API cheat sheet
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
await app.ready
|
|
23
|
+
const rec = await app.todos.insert({ title: 'x' }) // defaults and .auto() fields applied
|
|
24
|
+
await app.todos.update(rec.id, { completed: true }) // partial update, changed fields only
|
|
25
|
+
await app.todos.delete(rec.id)
|
|
26
|
+
const one = await app.todos.findById(rec.id)
|
|
27
|
+
const unsubscribe = app.todos
|
|
28
|
+
.where({ completed: false })
|
|
29
|
+
.orderBy('createdAt', 'desc')
|
|
30
|
+
.subscribe((rows) => {/* fires immediately, then on every change */})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Schema example (`src/schema.ts`):
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { defineSchema, t } from 'korajs'
|
|
37
|
+
|
|
38
|
+
export default defineSchema({
|
|
39
|
+
version: 1,
|
|
40
|
+
collections: {
|
|
41
|
+
todos: {
|
|
42
|
+
fields: {
|
|
43
|
+
title: t.string(),
|
|
44
|
+
completed: t.boolean().default(false),
|
|
45
|
+
tags: t.array(t.string()).default([]),
|
|
46
|
+
priority: t.enum(['low', 'medium', 'high']).default('medium'),
|
|
47
|
+
createdAt: t.timestamp().auto(), // set automatically; never pass it on insert
|
|
48
|
+
},
|
|
49
|
+
indexes: ['completed', 'createdAt'],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If you bump collections in a way that changes shapes, increment `version` and run `npx kora migrate`.
|
|
56
|
+
|
|
57
|
+
## Project conventions
|
|
58
|
+
|
|
59
|
+
- Feature code lives in `src/modules/<feature>/` with the pattern: `<feature>.schema.ts` (collection definition, imported into `src/schema.ts`), `<feature>.queries.ts` (query builders), `<feature>.mutations.ts` (mutation functions taking a collection accessor).
|
|
60
|
+
- Conflict handling is declarative. Concurrent edits merge automatically (last-write-wins per field, add-wins for arrays). If a field needs domain-specific merging (counters, quantities), add a `resolve` function in the schema rather than writing sync logic.
|
|
61
|
+
- `kora.config.ts` controls the dev environment (ports, sync server, schema watcher).
|
|
62
|
+
|
|
63
|
+
## Commands
|
|
64
|
+
|
|
65
|
+
- `npm run dev` starts everything: Vite dev server (port 5173), local sync server (port 3001), and the schema watcher.
|
|
66
|
+
- `npm run build` type-checks and builds for production.
|
|
67
|
+
- `npx kora doctor` diagnoses a broken setup.
|
|
68
|
+
- DevTools overlay: press Ctrl+Shift+K (Cmd+Shift+K on macOS) in the running app to inspect operations, merges, and sync status.
|
|
69
|
+
|
|
70
|
+
## Sync and auth
|
|
71
|
+
|
|
72
|
+
Sync is configured in `src/main.*` via `createApp({ sync: { url, authClient } })`. In dev, the sync URL is derived from the page host and proxied by Vite; in production set `VITE_SYNC_URL`. Auth (if present in this template) uses `@korajs/auth`; the client is created in `src/auth.ts`. Local writes work without sign-in; sync requires the server to accept the connection.
|
|
73
|
+
|
|
74
|
+
## Vue bindings
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/vue'
|
|
78
|
+
|
|
79
|
+
const todos = useCollection('todos')
|
|
80
|
+
const rows = useQuery(orderedTodos(todos)) // readonly reactive ref
|
|
81
|
+
const addTodo = useMutation((data) => todos.insert(data))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Rules: always surface the mutation's error state in the UI. `useQuery` reads synchronously from the local store, so avoid loading spinners for local data. The Kora context is provided by the `KoraProvider` component wired in `src/main.ts`.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/prompts/preferences.ts","../src/prompts/prompt-client.ts","../src/utils/prompt.ts","../src/types.ts","../src/commands/create/options.ts","../src/commands/create/preferences-flow.ts","../src/commands/create/project-name.ts","../src/commands/create/sync-provider-preset.ts","../src/utils/logger.ts","../src/utils/fs-helpers.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\n\n/**\n * Base error class for all CLI errors.\n */\nexport class CliError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'CLI_ERROR', context)\n\t\tthis.name = 'CliError'\n\t}\n}\n\n/**\n * Thrown when the target project directory already exists.\n */\nexport class ProjectExistsError extends KoraError {\n\tconstructor(public readonly directory: string) {\n\t\tsuper(\n\t\t\t`Directory \"${directory}\" already exists. Choose a different name or remove the existing directory.`,\n\t\t\t'PROJECT_EXISTS',\n\t\t\t{ directory },\n\t\t)\n\t\tthis.name = 'ProjectExistsError'\n\t}\n}\n\n/**\n * Thrown when a schema file cannot be found in the project.\n */\nexport class SchemaNotFoundError extends KoraError {\n\tconstructor(public readonly searchedPaths: string[]) {\n\t\tsuper(\n\t\t\t`Could not find a schema file. Searched: ${searchedPaths.join(', ')}. Create a schema file using defineSchema() from @korajs/core.`,\n\t\t\t'SCHEMA_NOT_FOUND',\n\t\t\t{ searchedPaths },\n\t\t)\n\t\tthis.name = 'SchemaNotFoundError'\n\t}\n}\n\n/**\n * Thrown when a command is run outside a valid Kora project.\n */\nexport class InvalidProjectError extends KoraError {\n\tconstructor(public readonly directory: string) {\n\t\tsuper(\n\t\t\t`\"${directory}\" is not a valid Kora project. No package.json with a kora dependency found. Run this command from inside a Kora project.`,\n\t\t\t'INVALID_PROJECT',\n\t\t\t{ directory },\n\t\t)\n\t\tthis.name = 'InvalidProjectError'\n\t}\n}\n\n/**\n * Thrown when a required local dev server binary cannot be found.\n */\nexport class DevServerError extends KoraError {\n\tconstructor(\n\t\tpublic readonly binary: string,\n\t\tpublic readonly searchPath: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not find required binary \"${binary}\" at ${searchPath}. Install project dependencies and try again.`,\n\t\t\t'DEV_SERVER_ERROR',\n\t\t\t{ binary, searchPath },\n\t\t)\n\t\tthis.name = 'DevServerError'\n\t}\n}\n","import Conf from 'conf'\nimport type {\n\tAuthOption,\n\tDatabaseOption,\n\tDatabaseProviderOption,\n\tFrameworkOption,\n\tPlatformOption,\n} from '../commands/create/options'\nimport type { PackageManager } from '../types'\n\nexport interface CreatePreferences {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\ttailwind: boolean\n\tsync: boolean\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n\tauth: AuthOption\n\tpackageManager: PackageManager\n}\n\nconst DEFAULT_PREFERENCES: CreatePreferences = {\n\tplatform: 'web',\n\tframework: 'react',\n\ttailwind: true,\n\tsync: true,\n\tdb: 'sqlite',\n\tdbProvider: 'none',\n\tauth: 'none',\n\tpackageManager: 'pnpm',\n}\n\nconst PREFERENCES_KEY = 'create.defaults'\n\n/**\n * Preference store for scaffold-time defaults in `create-kora-app`.\n */\nexport class PreferenceStore {\n\tprivate readonly store: Conf<{ [PREFERENCES_KEY]?: CreatePreferences }>\n\n\tpublic constructor() {\n\t\tthis.store = new Conf<{ [PREFERENCES_KEY]?: CreatePreferences }>({\n\t\t\tprojectName: 'korajs-cli',\n\t\t})\n\t}\n\n\tpublic getCreatePreferences(): CreatePreferences | null {\n\t\treturn this.store.get(PREFERENCES_KEY) ?? null\n\t}\n\n\tpublic saveCreatePreferences(preferences: CreatePreferences): void {\n\t\tthis.store.set(PREFERENCES_KEY, preferences)\n\t}\n\n\tpublic clearCreatePreferences(): void {\n\t\tthis.store.delete(PREFERENCES_KEY)\n\t}\n}\n\n/**\n * Gets preferences from storage or returns defaults when not available.\n */\nexport function getCreatePreferencesOrDefault(store: PreferenceStore): CreatePreferences {\n\treturn store.getCreatePreferences() ?? DEFAULT_PREFERENCES\n}\n\nexport function getDefaultCreatePreferences(): CreatePreferences {\n\treturn { ...DEFAULT_PREFERENCES }\n}\n","import {\n\tcancel as clackCancel,\n\tconfirm as clackConfirm,\n\tintro as clackIntro,\n\tisCancel as clackIsCancel,\n\toutro as clackOutro,\n\tselect as clackSelect,\n\ttext as clackText,\n} from '@clack/prompts'\nimport { promptConfirm, promptSelect, promptText } from '../utils/prompt'\n\nexport interface SelectOption<T extends string> {\n\tlabel: string\n\tvalue: T\n\thint?: string\n\tdisabled?: boolean\n}\n\ntype ClackSelectOption<T extends string> = {\n\tvalue: T\n\tlabel?: string\n\thint?: string\n\tdisabled?: boolean\n}\n\nexport interface PromptClient {\n\ttext(message: string, defaultValue?: string): Promise<string>\n\tselect<T extends string>(message: string, options: readonly SelectOption<T>[]): Promise<T>\n\tconfirm(message: string, defaultValue?: boolean): Promise<boolean>\n\tintro(message: string): void\n\toutro(message: string): void\n}\n\nexport class PromptCancelledError extends Error {\n\tpublic constructor(message = 'Prompt cancelled by user') {\n\t\tsuper(message)\n\t\tthis.name = 'PromptCancelledError'\n\t}\n}\n\n/**\n * Prompt client backed by the current readline helpers.\n *\n * Phase 12 will introduce a richer prompt backend. This adapter keeps command\n * logic decoupled from the prompt implementation so we can migrate without\n * reshaping command behavior.\n */\nexport class ReadlinePromptClient implements PromptClient {\n\tpublic async text(message: string, defaultValue?: string): Promise<string> {\n\t\treturn promptText(message, defaultValue)\n\t}\n\n\tpublic async select<T extends string>(\n\t\tmessage: string,\n\t\toptions: readonly SelectOption<T>[],\n\t): Promise<T> {\n\t\treturn promptSelect(\n\t\t\tmessage,\n\t\t\toptions\n\t\t\t\t.filter((option) => option.disabled !== true)\n\t\t\t\t.map((option) => ({ label: option.label, value: option.value })),\n\t\t)\n\t}\n\n\tpublic async confirm(message: string, defaultValue = false): Promise<boolean> {\n\t\treturn promptConfirm(message, defaultValue)\n\t}\n\n\tpublic intro(message: string): void {\n\t\t// The readline backend does not provide intro/outro framing.\n\t\t// Keep no-op semantics for compatibility.\n\t\tvoid message\n\t}\n\n\tpublic outro(message: string): void {\n\t\t// The readline backend does not provide intro/outro framing.\n\t\t// Keep no-op semantics for compatibility.\n\t\tvoid message\n\t}\n}\n\n/**\n * Returns the default prompt client for interactive CLI flows.\n */\nexport function createPromptClient(): PromptClient {\n\tconst canUseInteractiveClack =\n\t\ttypeof process !== 'undefined' && process.stdin.isTTY && process.stdout.isTTY\n\tif (canUseInteractiveClack) {\n\t\treturn new ClackPromptClient()\n\t}\n\treturn new ReadlinePromptClient()\n}\n\n/**\n * Prompt client backed by @clack/prompts for richer interactive UX.\n * Falls back to readline in non-interactive contexts.\n */\nexport class ClackPromptClient implements PromptClient {\n\tpublic async text(message: string, defaultValue?: string): Promise<string> {\n\t\tconst result = await clackText({\n\t\t\tmessage,\n\t\t\tplaceholder: defaultValue,\n\t\t\tdefaultValue,\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\tconst value = result.trim()\n\t\tif (value.length > 0) return value\n\t\treturn defaultValue ?? ''\n\t}\n\n\tpublic async select<T extends string>(\n\t\tmessage: string,\n\t\toptions: readonly SelectOption<T>[],\n\t): Promise<T> {\n\t\tconst mappedOptions: ClackSelectOption<T>[] = options.map((option) => ({\n\t\t\tlabel: option.label,\n\t\t\tvalue: option.value,\n\t\t\thint: option.hint,\n\t\t\tdisabled: option.disabled,\n\t\t}))\n\t\tconst result = await clackSelect({\n\t\t\tmessage,\n\t\t\toptions: mappedOptions as unknown as Parameters<typeof clackSelect>[0]['options'],\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\treturn result as T\n\t}\n\n\tpublic async confirm(message: string, defaultValue = false): Promise<boolean> {\n\t\tconst result = await clackConfirm({\n\t\t\tmessage,\n\t\t\tinitialValue: defaultValue,\n\t\t})\n\t\tif (clackIsCancel(result)) {\n\t\t\tclackCancel('Operation cancelled.')\n\t\t\tthrow new PromptCancelledError()\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic intro(message: string): void {\n\t\tclackIntro(message)\n\t}\n\n\tpublic outro(message: string): void {\n\t\tclackOutro(message)\n\t}\n}\n","import { type Interface as ReadlineInterface, createInterface } from 'node:readline'\n\nexport interface PromptOptions {\n\t/** Input stream (defaults to process.stdin) */\n\tinput?: NodeJS.ReadableStream\n\t/** Output stream (defaults to process.stdout) */\n\toutput?: NodeJS.WritableStream\n}\n\n/**\n * Prompts the user for text input.\n *\n * @param message - The prompt message to display\n * @param defaultValue - Optional default value shown in brackets\n * @param options - Optional input/output streams for testing\n */\nexport function promptText(\n\tmessage: string,\n\tdefaultValue?: string,\n\toptions?: PromptOptions,\n): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst suffix = defaultValue !== undefined ? ` (${defaultValue})` : ''\n\t\trl.question(` ? ${message}${suffix}: `, (answer) => {\n\t\t\trl.close()\n\t\t\tconst trimmed = answer.trim()\n\t\t\tresolve(trimmed || defaultValue || '')\n\t\t})\n\t})\n}\n\n/**\n * Prompts the user to select from a numbered list of options.\n *\n * @param message - The prompt message to display\n * @param choices - Array of { label, value } options\n * @param options - Optional input/output streams for testing\n */\nexport function promptSelect<T extends string>(\n\tmessage: string,\n\tchoices: readonly { label: string; value: T }[],\n\toptions?: PromptOptions,\n): Promise<T> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst out = options?.output ?? process.stdout\n\n\t\tout.write(` ? ${message}\\n`)\n\t\tfor (let i = 0; i < choices.length; i++) {\n\t\t\tconst choice = choices[i]\n\t\t\tif (choice) {\n\t\t\t\tout.write(` ${i + 1}) ${choice.label}\\n`)\n\t\t\t}\n\t\t}\n\n\t\tconst ask = (): void => {\n\t\t\trl.question(' > ', (answer) => {\n\t\t\t\tconst index = Number.parseInt(answer.trim(), 10) - 1\n\t\t\t\tconst selected = choices[index]\n\t\t\t\tif (selected) {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(selected.value)\n\t\t\t\t} else {\n\t\t\t\t\tout.write(` Please enter a number between 1 and ${choices.length}\\n`)\n\t\t\t\t\task()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\task()\n\t})\n}\n\n/**\n * Prompts the user with a yes/no confirmation.\n *\n * @param message - The prompt message to display\n * @param defaultValue - Default when input is empty (true => yes)\n * @param options - Optional input/output streams for testing\n */\nexport function promptConfirm(\n\tmessage: string,\n\tdefaultValue = false,\n\toptions?: PromptOptions,\n): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst rl = createReadline(options)\n\t\tconst suffix = defaultValue ? 'Y/n' : 'y/N'\n\n\t\tconst ask = (): void => {\n\t\t\trl.question(` ? ${message} (${suffix}): `, (answer) => {\n\t\t\t\tconst normalized = answer.trim().toLowerCase()\n\t\t\t\tif (normalized.length === 0) {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(defaultValue)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (normalized === 'y' || normalized === 'yes') {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (normalized === 'n' || normalized === 'no') {\n\t\t\t\t\trl.close()\n\t\t\t\t\tresolve(false)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t;(options?.output ?? process.stdout).write(' Please answer with y or n\\n')\n\t\t\t\task()\n\t\t\t})\n\t\t}\n\n\t\task()\n\t})\n}\n\nfunction createReadline(options?: PromptOptions): ReadlineInterface {\n\treturn createInterface({\n\t\tinput: options?.input ?? process.stdin,\n\t\toutput: options?.output ?? process.stdout,\n\t})\n}\n","/** Supported package managers */\nexport const PACKAGE_MANAGERS = ['pnpm', 'npm', 'yarn', 'bun'] as const\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number]\n\n/** Available project templates */\nexport const TEMPLATES = [\n\t'react-tailwind-sync',\n\t'react-tailwind',\n\t'react-sync',\n\t'react-basic',\n\t'vue-sync',\n\t'vue-basic',\n\t'vue-tailwind-sync',\n\t'vue-tailwind',\n\t'svelte-sync',\n\t'svelte-basic',\n\t'svelte-tailwind-sync',\n\t'svelte-tailwind',\n\t'tauri-react',\n] as const\nexport type TemplateName = (typeof TEMPLATES)[number]\n\n/** Metadata for a project template */\nexport interface TemplateInfo {\n\tname: TemplateName\n\tlabel: string\n\tdescription: string\n}\n\n/** Available templates with their descriptions */\nexport const TEMPLATE_INFO: readonly TemplateInfo[] = [\n\t{\n\t\tname: 'react-tailwind-sync',\n\t\tlabel: 'React + Tailwind (with sync)',\n\t\tdescription: 'Polished dark-themed app with Tailwind CSS and sync server (Recommended)',\n\t},\n\t{\n\t\tname: 'react-tailwind',\n\t\tlabel: 'React + Tailwind (local-only)',\n\t\tdescription: 'Polished dark-themed app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'react-sync',\n\t\tlabel: 'React + CSS (with sync)',\n\t\tdescription: 'Clean CSS app with sync server included',\n\t},\n\t{\n\t\tname: 'react-basic',\n\t\tlabel: 'React + CSS (local-only)',\n\t\tdescription: 'Clean CSS app — no sync server',\n\t},\n\t{\n\t\tname: 'vue-sync',\n\t\tlabel: 'Vue 3 + CSS (with sync)',\n\t\tdescription: 'Vue composables with sync server included',\n\t},\n\t{\n\t\tname: 'vue-basic',\n\t\tlabel: 'Vue 3 + CSS (local-only)',\n\t\tdescription: 'Vue composables — no sync server',\n\t},\n\t{\n\t\tname: 'vue-tailwind-sync',\n\t\tlabel: 'Vue 3 + Tailwind (with sync)',\n\t\tdescription: 'Polished Vue app with Tailwind CSS and sync server',\n\t},\n\t{\n\t\tname: 'vue-tailwind',\n\t\tlabel: 'Vue 3 + Tailwind (local-only)',\n\t\tdescription: 'Polished Vue app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'svelte-sync',\n\t\tlabel: 'Svelte 5 + CSS (with sync)',\n\t\tdescription: 'Svelte stores with sync server included',\n\t},\n\t{\n\t\tname: 'svelte-basic',\n\t\tlabel: 'Svelte 5 + CSS (local-only)',\n\t\tdescription: 'Svelte stores — no sync server',\n\t},\n\t{\n\t\tname: 'svelte-tailwind-sync',\n\t\tlabel: 'Svelte 5 + Tailwind (with sync)',\n\t\tdescription: 'Polished Svelte app with Tailwind CSS and sync server',\n\t},\n\t{\n\t\tname: 'svelte-tailwind',\n\t\tlabel: 'Svelte 5 + Tailwind (local-only)',\n\t\tdescription: 'Polished Svelte app with Tailwind CSS — no sync server',\n\t},\n\t{\n\t\tname: 'tauri-react',\n\t\tlabel: 'Tauri Desktop (native SQLite)',\n\t\tdescription: 'Desktop app with native SQLite — no WASM, includes sync server',\n\t},\n] as const\n\n/** Variables available for template substitution */\nexport interface TemplateContext {\n\tprojectName: string\n\tpackageManager: PackageManager\n\tkoraVersion: string\n\tdbProvider?: string\n}\n","import type { TemplateName } from '../../types'\n\nexport type PlatformOption = 'web' | 'desktop-tauri'\nexport type FrameworkOption = 'react' | 'vue' | 'svelte' | 'solid'\nexport type AuthOption = 'none' | 'email-password' | 'oauth'\nexport type DatabaseOption = 'none' | 'sqlite' | 'postgres'\nexport type DatabaseProviderOption =\n\t| 'none'\n\t| 'local'\n\t| 'supabase'\n\t| 'neon'\n\t| 'railway'\n\t| 'vercel-postgres'\n\t| 'custom'\n\nexport interface TemplateSelectionInput {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\ttailwind: boolean\n\tsync: boolean\n\tdb: DatabaseOption\n}\n\n/**\n * Converts high-level scaffold selections into a concrete template name.\n */\nexport function determineTemplateFromSelections(input: TemplateSelectionInput): TemplateName {\n\tif (input.platform === 'desktop-tauri') return 'tauri-react'\n\n\tconst shouldSync = input.sync && input.db !== 'none'\n\n\tif (input.framework === 'vue') {\n\t\tif (input.tailwind && shouldSync) return 'vue-tailwind-sync'\n\t\tif (input.tailwind && !shouldSync) return 'vue-tailwind'\n\t\treturn shouldSync ? 'vue-sync' : 'vue-basic'\n\t}\n\n\tif (input.framework === 'svelte') {\n\t\tif (input.tailwind && shouldSync) return 'svelte-tailwind-sync'\n\t\tif (input.tailwind && !shouldSync) return 'svelte-tailwind'\n\t\treturn shouldSync ? 'svelte-sync' : 'svelte-basic'\n\t}\n\n\tif (input.framework === 'solid') {\n\t\tthrow new Error('Solid templates are not available yet. Use react, vue, or svelte.')\n\t}\n\n\tif (input.tailwind && shouldSync) return 'react-tailwind-sync'\n\tif (input.tailwind && !shouldSync) return 'react-tailwind'\n\tif (!input.tailwind && shouldSync) return 'react-sync'\n\treturn 'react-basic'\n}\n\nexport function isPlatformValue(value: string): value is PlatformOption {\n\treturn value === 'web' || value === 'desktop-tauri'\n}\n\nexport function isFrameworkValue(value: string): value is FrameworkOption {\n\treturn value === 'react' || value === 'vue' || value === 'svelte' || value === 'solid'\n}\n\nexport function isAuthValue(value: string): value is AuthOption {\n\treturn value === 'none' || value === 'email-password' || value === 'oauth'\n}\n\nexport function isDatabaseValue(value: string): value is DatabaseOption {\n\treturn value === 'none' || value === 'sqlite' || value === 'postgres'\n}\n\nexport function isDatabaseProviderValue(value: string): value is DatabaseProviderOption {\n\treturn (\n\t\tvalue === 'none' ||\n\t\tvalue === 'local' ||\n\t\tvalue === 'supabase' ||\n\t\tvalue === 'neon' ||\n\t\tvalue === 'railway' ||\n\t\tvalue === 'vercel-postgres' ||\n\t\tvalue === 'custom'\n\t)\n}\n\nexport function isSupportedWebFramework(framework: FrameworkOption): boolean {\n\treturn framework === 'react' || framework === 'vue' || framework === 'svelte'\n}\n","import {\n\ttype CreatePreferences,\n\ttype PreferenceStore,\n\tgetCreatePreferencesOrDefault,\n\tgetDefaultCreatePreferences,\n} from '../../prompts/preferences'\nimport type { PromptClient } from '../../prompts/prompt-client'\nimport {\n\ttype AuthOption,\n\ttype DatabaseOption,\n\ttype DatabaseProviderOption,\n\ttype FrameworkOption,\n\ttype PlatformOption,\n\tdetermineTemplateFromSelections,\n\tisAuthValue,\n\tisDatabaseProviderValue,\n\tisDatabaseValue,\n\tisFrameworkValue,\n\tisPlatformValue,\n} from './options'\n\nexport interface CreateFlags {\n\tplatform?: string\n\tframework?: string\n\tauth?: string\n\tdb?: string\n\tdbProvider?: string\n\ttailwind?: boolean\n\tsync?: boolean\n\tuseDefaults: boolean\n}\n\nexport interface PreferenceResolutionResult {\n\tplatform: PlatformOption\n\tframework: FrameworkOption\n\tauth: AuthOption\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n\ttailwind: boolean\n\tsync: boolean\n\ttemplate: ReturnType<typeof determineTemplateFromSelections>\n\tusedStoredPreferences: boolean\n}\n\n/**\n * Resolves scaffold options with precedence:\n * CLI flags > --yes defaults > stored preferences > interactive prompts.\n */\nexport async function resolveCreatePreferencesFlow(params: {\n\tflags: CreateFlags\n\tprompts: PromptClient\n\tstore: PreferenceStore\n}): Promise<PreferenceResolutionResult> {\n\tconst { flags, prompts, store } = params\n\tconst stored = store.getCreatePreferences()\n\tconst base = getCreatePreferencesOrDefault(store)\n\tconst hasExplicitFlags = hasExplicitPreferenceFlags(flags)\n\tconst canOfferStored =\n\t\t!flags.useDefaults && !hasExplicitFlags && stored !== null && promptSupportsRichOptions()\n\n\tlet effective: CreatePreferences = { ...base }\n\tlet usedStoredPreferences = false\n\n\tif (flags.useDefaults) {\n\t\teffective = getDefaultCreatePreferences()\n\t} else if (canOfferStored && stored !== null) {\n\t\tconst reuseStored = await prompts.select('Welcome back! Choose setup mode:', [\n\t\t\t{ label: formatStoredPreferenceLabel(stored), value: 'reuse' },\n\t\t\t{ label: 'Customize', value: 'customize' },\n\t\t])\n\t\tif (reuseStored === 'reuse') {\n\t\t\teffective = { ...stored }\n\t\t\tusedStoredPreferences = true\n\t\t}\n\t}\n\n\tif (flags.platform !== undefined) {\n\t\tif (!isPlatformValue(flags.platform)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid --platform value \"${flags.platform}\". Expected one of: web, desktop-tauri.`,\n\t\t\t)\n\t\t}\n\t\teffective.platform = flags.platform\n\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\teffective.platform = await prompts.select('Platform:', [\n\t\t\t{ label: 'Web (browser)', value: 'web' },\n\t\t\t{ label: 'Desktop (Tauri — native SQLite)', value: 'desktop-tauri' },\n\t\t])\n\t}\n\n\tconst isTauri = effective.platform === 'desktop-tauri'\n\n\tif (isTauri) {\n\t\t// Tauri currently uses React and native SQLite on the client.\n\t\t// The sync server remains configurable so the same desktop scaffold can\n\t\t// run local-only, LAN sync, or cloud sync without switching templates.\n\t\teffective.framework = 'react'\n\t\teffective.tailwind = false\n\t\teffective.auth = 'none'\n\n\t\tif (flags.sync !== undefined) {\n\t\t\teffective.sync = flags.sync\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.sync = await prompts.confirm('Enable multi-device sync?', true)\n\t\t}\n\n\t\tif (flags.db !== undefined) {\n\t\t\tif (!isDatabaseValue(flags.db)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db value \"${flags.db}\". Expected one of: none, sqlite, postgres.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.db = flags.db\n\t\t} else if (!effective.sync) {\n\t\t\teffective.db = 'none'\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.db = await prompts.select('Sync server database:', [\n\t\t\t\t{ label: 'SQLite (zero-config; local, LAN, small teams)', value: 'sqlite' },\n\t\t\t\t{ label: 'PostgreSQL (production-scale)', value: 'postgres' },\n\t\t\t])\n\t\t}\n\n\t\tif (effective.db === 'none') {\n\t\t\teffective.sync = false\n\t\t}\n\n\t\tif (effective.db !== 'postgres') {\n\t\t\teffective.dbProvider = 'none'\n\t\t} else if (flags.dbProvider !== undefined) {\n\t\t\tif (!isDatabaseProviderValue(flags.dbProvider)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db-provider value \"${flags.dbProvider}\". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.dbProvider = flags.dbProvider\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.dbProvider = await prompts.select('Database provider:', [\n\t\t\t\t{ label: 'Local Postgres', value: 'local' },\n\t\t\t\t{ label: 'Supabase', value: 'supabase' },\n\t\t\t\t{ label: 'Neon', value: 'neon' },\n\t\t\t\t{ label: 'Railway', value: 'railway' },\n\t\t\t\t{ label: 'Vercel Postgres', value: 'vercel-postgres' },\n\t\t\t\t{ label: 'Custom connection string', value: 'custom' },\n\t\t\t])\n\t\t}\n\t} else {\n\t\tif (flags.framework !== undefined) {\n\t\t\tif (!isFrameworkValue(flags.framework)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --framework value \"${flags.framework}\". Expected one of: react, vue, svelte, solid.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.framework = flags.framework\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.framework = await prompts.select('UI framework:', [\n\t\t\t\t{ label: 'React', value: 'react' },\n\t\t\t\t{ label: 'Vue 3', value: 'vue' },\n\t\t\t\t{ label: 'Svelte 5', value: 'svelte' },\n\t\t\t\t{ label: 'Solid (coming soon)', value: 'solid', disabled: true },\n\t\t\t])\n\t\t}\n\n\t\tif (flags.auth !== undefined) {\n\t\t\tif (!isAuthValue(flags.auth)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --auth value \"${flags.auth}\". Expected one of: none, email-password, oauth.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.auth = flags.auth\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.auth = await prompts.select('Authentication:', [\n\t\t\t\t{ label: 'None', value: 'none' },\n\t\t\t\t{ label: 'Email + Password (coming soon)', value: 'email-password', disabled: true },\n\t\t\t\t{ label: 'OAuth (coming soon)', value: 'oauth', disabled: true },\n\t\t\t])\n\t\t}\n\n\t\tif (flags.tailwind !== undefined) {\n\t\t\teffective.tailwind = flags.tailwind\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.tailwind = await prompts.confirm('Use Tailwind CSS?', true)\n\t\t}\n\n\t\tif (flags.sync !== undefined) {\n\t\t\teffective.sync = flags.sync\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.sync = await prompts.confirm('Enable multi-device sync?', true)\n\t\t}\n\n\t\tif (flags.db !== undefined) {\n\t\t\tif (!isDatabaseValue(flags.db)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db value \"${flags.db}\". Expected one of: none, sqlite, postgres.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.db = flags.db\n\t\t} else if (!effective.sync) {\n\t\t\teffective.db = 'none'\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.db = await prompts.select('Server-side database:', [\n\t\t\t\t{ label: 'SQLite (zero-config)', value: 'sqlite' },\n\t\t\t\t{ label: 'PostgreSQL (production-scale)', value: 'postgres' },\n\t\t\t])\n\t\t}\n\n\t\tif (effective.db !== 'postgres') {\n\t\t\teffective.dbProvider = 'none'\n\t\t} else if (flags.dbProvider !== undefined) {\n\t\t\tif (!isDatabaseProviderValue(flags.dbProvider)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid --db-provider value \"${flags.dbProvider}\". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\teffective.dbProvider = flags.dbProvider\n\t\t} else if (!flags.useDefaults && !usedStoredPreferences) {\n\t\t\teffective.dbProvider = await prompts.select('Database provider:', [\n\t\t\t\t{ label: 'Local Postgres', value: 'local' },\n\t\t\t\t{ label: 'Supabase', value: 'supabase' },\n\t\t\t\t{ label: 'Neon', value: 'neon' },\n\t\t\t\t{ label: 'Railway', value: 'railway' },\n\t\t\t\t{ label: 'Vercel Postgres', value: 'vercel-postgres' },\n\t\t\t\t{ label: 'Custom connection string', value: 'custom' },\n\t\t\t])\n\t\t}\n\t}\n\n\tconst template = determineTemplateFromSelections({\n\t\tplatform: effective.platform,\n\t\tframework: effective.framework,\n\t\ttailwind: effective.tailwind,\n\t\tsync: effective.sync,\n\t\tdb: effective.db,\n\t})\n\n\treturn {\n\t\tplatform: effective.platform,\n\t\tframework: effective.framework,\n\t\tauth: effective.auth,\n\t\tdb: effective.db,\n\t\tdbProvider: effective.dbProvider,\n\t\ttailwind: effective.tailwind,\n\t\tsync: effective.sync,\n\t\ttemplate,\n\t\tusedStoredPreferences,\n\t}\n}\n\nexport function shouldSavePreferences(flags: CreateFlags): boolean {\n\treturn !flags.useDefaults\n}\n\nexport function saveResolvedPreferences(\n\tstore: PreferenceStore,\n\tresolution: Omit<PreferenceResolutionResult, 'template' | 'usedStoredPreferences'> & {\n\t\tpackageManager: CreatePreferences['packageManager']\n\t},\n): void {\n\tstore.saveCreatePreferences({\n\t\tplatform: resolution.platform,\n\t\tframework: resolution.framework,\n\t\ttailwind: resolution.tailwind,\n\t\tsync: resolution.sync,\n\t\tdb: resolution.db,\n\t\tdbProvider: resolution.dbProvider,\n\t\tauth: resolution.auth,\n\t\tpackageManager: resolution.packageManager,\n\t})\n}\n\nfunction hasExplicitPreferenceFlags(flags: CreateFlags): boolean {\n\treturn (\n\t\tflags.platform !== undefined ||\n\t\tflags.framework !== undefined ||\n\t\tflags.auth !== undefined ||\n\t\tflags.db !== undefined ||\n\t\tflags.dbProvider !== undefined ||\n\t\tflags.tailwind !== undefined ||\n\t\tflags.sync !== undefined\n\t)\n}\n\nfunction promptSupportsRichOptions(): boolean {\n\treturn typeof process !== 'undefined' && process.stdin.isTTY && process.stdout.isTTY\n}\n\nfunction formatStoredPreferenceLabel(preferences: CreatePreferences): string {\n\tif (preferences.platform === 'desktop-tauri') {\n\t\treturn `Use previous settings (tauri-desktop + ${preferences.packageManager})`\n\t}\n\tconst syncLabel = preferences.sync ? `sync/${preferences.db}` : 'local-only'\n\tconst styleLabel = preferences.tailwind ? 'tailwind' : 'css'\n\treturn `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`\n}\n","import validateNpmPackageName from 'validate-npm-package-name'\n\nexport interface ProjectNameValidationResult {\n\tvalid: boolean\n\tissues: readonly string[]\n}\n\n/**\n * Validates a project name for scaffolded package creation.\n *\n * The create command uses this validation before writing files so users get a\n * clear, early error if the name cannot be used as an npm package name.\n */\nexport function validateProjectName(name: string): ProjectNameValidationResult {\n\tconst trimmedName = name.trim()\n\tif (trimmedName.length === 0) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\tissues: ['Project name cannot be empty.'],\n\t\t}\n\t}\n\n\tconst validation = validateNpmPackageName(trimmedName)\n\tconst issues = [...(validation.errors ?? []), ...(validation.warnings ?? [])]\n\tif (!validation.validForNewPackages && issues.length === 0) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\tissues: ['Project name is not a valid npm package name.'],\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: validation.validForNewPackages,\n\t\tissues,\n\t}\n}\n","import { readFile, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { TemplateName } from '../../types'\nimport type { DatabaseOption, DatabaseProviderOption } from './options'\n\ninterface SyncProviderPresetOptions {\n\ttargetDir: string\n\ttemplate: TemplateName\n\tdb: DatabaseOption\n\tdbProvider: DatabaseProviderOption\n}\n\n/**\n * Applies provider-specific sync scaffolding adjustments after template copy.\n *\n * The sync server template is environment-driven: SQLite is used when\n * DATABASE_URL is absent, and PostgreSQL is used when DATABASE_URL is present.\n * Provider presets only add provider-specific guidance.\n */\nexport async function applySyncProviderPreset(options: SyncProviderPresetOptions): Promise<void> {\n\tif (!isSyncTemplate(options.template)) {\n\t\treturn\n\t}\n\tif (options.db !== 'postgres') {\n\t\treturn\n\t}\n\n\tconst providerName = getProviderDisplayName(options.dbProvider)\n\tconst providerConnectionString = getProviderConnectionStringExample(options.dbProvider)\n\tconst envPath = join(options.targetDir, '.env.example')\n\tconst readmePath = join(options.targetDir, 'README.md')\n\n\tconst existingReadme = await readFile(readmePath, 'utf-8')\n\tconst existingEnv = await readFile(envPath, 'utf-8')\n\tconst trimmedReadme = existingReadme.trimEnd()\n\tconst trimmedEnv = existingEnv.trimEnd()\n\tconst envSuffix = [\n\t\t'',\n\t\t`# PostgreSQL provider preset: ${providerName}`,\n\t\t`# Example: ${providerConnectionString}`,\n\t].join('\\n')\n\tconst readmeSuffix = [\n\t\t'',\n\t\t'## PostgreSQL Provider Preset',\n\t\t'',\n\t\t`Selected DB provider: ${options.dbProvider}`,\n\t\t'',\n\t\t'This scaffold keeps one sync server entrypoint. When `DATABASE_URL` is set, `server.ts` uses PostgreSQL. When it is empty, the same server uses SQLite at `KORA_SERVER_DB`.',\n\t\t'',\n\t\t'The generated server uses `createPostgresServerStore` automatically when `DATABASE_URL` is present.',\n\t\t'',\n\t].join('\\n')\n\tconst readmeTemplate = `${trimmedReadme}${readmeSuffix}`\n\n\tawait writeFile(envPath, `${trimmedEnv}${envSuffix}\\n`, 'utf-8')\n\tawait writeFile(readmePath, readmeTemplate, 'utf-8')\n}\n\nfunction isSyncTemplate(template: TemplateName): boolean {\n\treturn (\n\t\ttemplate === 'react-sync' ||\n\t\ttemplate === 'react-tailwind-sync' ||\n\t\ttemplate === 'vue-sync' ||\n\t\ttemplate === 'vue-tailwind-sync' ||\n\t\ttemplate === 'svelte-sync' ||\n\t\ttemplate === 'svelte-tailwind-sync' ||\n\t\ttemplate === 'tauri-react'\n\t)\n}\n\nfunction getProviderDisplayName(provider: DatabaseProviderOption): string {\n\tswitch (provider) {\n\t\tcase 'supabase':\n\t\t\treturn 'Supabase'\n\t\tcase 'neon':\n\t\t\treturn 'Neon'\n\t\tcase 'railway':\n\t\t\treturn 'Railway'\n\t\tcase 'vercel-postgres':\n\t\t\treturn 'Vercel Postgres'\n\t\tcase 'custom':\n\t\t\treturn 'Custom'\n\t\tcase 'local':\n\t\t\treturn 'Local Postgres'\n\t\tcase 'none':\n\t\t\treturn 'PostgreSQL'\n\t}\n}\n\nfunction getProviderConnectionStringExample(provider: DatabaseProviderOption): string {\n\tswitch (provider) {\n\t\tcase 'supabase':\n\t\t\treturn 'postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=require'\n\t\tcase 'neon':\n\t\t\treturn 'postgresql://<user>:<password>@<branch>.<project>.neon.tech/neondb?sslmode=require'\n\t\tcase 'railway':\n\t\t\treturn 'postgresql://postgres:<password>@<host>.railway.app:<port>/railway?sslmode=require'\n\t\tcase 'vercel-postgres':\n\t\t\treturn 'postgresql://<user>:<password>@<host>.pooler.vercel-storage.com:5432/verceldb?sslmode=require'\n\t\tcase 'custom':\n\t\t\treturn 'postgresql://<user>:<password>@<host>:5432/<database>'\n\t\tcase 'local':\n\t\t\treturn 'postgresql://postgres:postgres@localhost:5432/kora'\n\t\tcase 'none':\n\t\t\treturn 'postgresql://postgres:postgres@localhost:5432/kora'\n\t}\n}\n","/** ANSI escape codes for terminal colors */\nconst RESET = '\\x1b[0m'\nconst BOLD = '\\x1b[1m'\nconst DIM = '\\x1b[2m'\nconst GREEN = '\\x1b[32m'\nconst YELLOW = '\\x1b[33m'\nconst RED = '\\x1b[31m'\nconst CYAN = '\\x1b[36m'\n\nexport interface LoggerOptions {\n\t/** Disable ANSI colors */\n\tnoColor?: boolean\n}\n\nexport interface Logger {\n\tinfo(message: string): void\n\tsuccess(message: string): void\n\twarn(message: string): void\n\terror(message: string): void\n\tstep(message: string): void\n\tblank(): void\n\tbanner(): void\n}\n\n/**\n * Creates a logger with optional ANSI color support.\n * Respects the NO_COLOR environment variable and TTY detection.\n */\nexport function createLogger(options?: LoggerOptions): Logger {\n\tconst colorDisabled =\n\t\toptions?.noColor === true || process.env.NO_COLOR !== undefined || !process.stdout.isTTY\n\n\tfunction color(code: string, text: string): string {\n\t\treturn colorDisabled ? text : `${code}${text}${RESET}`\n\t}\n\n\treturn {\n\t\tinfo(message: string): void {\n\t\t\tconsole.log(color(CYAN, message))\n\t\t},\n\t\tsuccess(message: string): void {\n\t\t\tconsole.log(color(GREEN, ` ✓ ${message}`))\n\t\t},\n\t\twarn(message: string): void {\n\t\t\tconsole.warn(color(YELLOW, ` ⚠ ${message}`))\n\t\t},\n\t\terror(message: string): void {\n\t\t\tconsole.error(color(RED, ` ✗ ${message}`))\n\t\t},\n\t\tstep(message: string): void {\n\t\t\tconsole.log(color(DIM, ` ${message}`))\n\t\t},\n\t\tblank(): void {\n\t\t\tconsole.log()\n\t\t},\n\t\tbanner(): void {\n\t\t\tconsole.log()\n\t\t\tconsole.log(\n\t\t\t\tcolor(BOLD + CYAN, ' Kora.js') + color(DIM, ' — Offline-first application framework'),\n\t\t\t)\n\t\t\tconsole.log()\n\t\t},\n\t}\n}\n","import { access, readFile } from 'node:fs/promises'\nimport { dirname, join, resolve } from 'node:path'\n\n/** Checks if a directory exists at the given path */\nexport async function directoryExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Walks up the directory tree from startDir looking for a package.json\n * that contains a kora or @korajs/* dependency.\n *\n * @param startDir - Directory to start searching from (defaults to cwd)\n * @returns Absolute path to the project root, or null if not found\n */\nexport async function findProjectRoot(startDir?: string): Promise<string | null> {\n\tlet current = resolve(startDir ?? process.cwd())\n\n\t// Walk up until the filesystem root (where dirname(x) === x)\n\tfor (;;) {\n\t\tconst pkgPath = join(current, 'package.json')\n\t\ttry {\n\t\t\tconst content = await readFile(pkgPath, 'utf-8')\n\t\t\tconst pkg: unknown = JSON.parse(content)\n\t\t\tif (isKoraProject(pkg)) {\n\t\t\t\treturn current\n\t\t\t}\n\t\t} catch {\n\t\t\t// No package.json at this level, keep walking up\n\t\t}\n\t\tconst parent = dirname(current)\n\t\tif (parent === current) break\n\t\tcurrent = parent\n\t}\n\n\treturn null\n}\n\n/**\n * Searches for a schema file in common locations within a project.\n *\n * @param projectRoot - The project root directory\n * @returns Absolute path to the schema file, or null if not found\n */\nexport async function findSchemaFile(projectRoot: string): Promise<string | null> {\n\tconst candidates = [\n\t\tjoin(projectRoot, 'src', 'schema.ts'),\n\t\tjoin(projectRoot, 'schema.ts'),\n\t\tjoin(projectRoot, 'src', 'schema.js'),\n\t\tjoin(projectRoot, 'schema.js'),\n\t]\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tawait access(candidate)\n\t\t\treturn candidate\n\t\t} catch {\n\t\t\t// Not found, try next\n\t\t}\n\t}\n\n\treturn null\n}\n\n/**\n * Resolves a binary from a project's local node_modules/.bin directory.\n * On Windows, npm creates .cmd shims instead of extensionless files.\n *\n * @param projectRoot - The project root directory\n * @param binaryName - Binary filename (for example: vite, tsx, kora)\n * @returns Absolute path to the binary, or null if not found\n */\nexport async function resolveProjectBinary(\n\tprojectRoot: string,\n\tbinaryName: string,\n): Promise<string | null> {\n\tconst binDir = join(projectRoot, 'node_modules', '.bin')\n\t// On Windows, try .cmd first (npm/pnpm create .cmd shims)\n\tconst candidates =\n\t\tprocess.platform === 'win32'\n\t\t\t? [join(binDir, `${binaryName}.cmd`), join(binDir, binaryName)]\n\t\t\t: [join(binDir, binaryName)]\n\n\tfor (const candidate of candidates) {\n\t\ttry {\n\t\t\tawait access(candidate)\n\t\t\treturn candidate\n\t\t} catch {\n\t\t\t// continue\n\t\t}\n\t}\n\treturn null\n}\n\n/**\n * Checks whether the `tsx` package is installed in the project's node_modules.\n * Used to determine if we can use `--import tsx` with process.execPath.\n */\nexport async function hasTsxInstalled(projectRoot: string): Promise<boolean> {\n\ttry {\n\t\tawait access(join(projectRoot, 'node_modules', 'tsx', 'package.json'))\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Resolves the JS entry point for a package binary.\n * Reads the package.json bin field to find the actual JS file,\n * avoiding .cmd shims and shell:true on Windows.\n *\n * @returns Absolute path to the JS entry point, or null if not found\n */\nexport async function resolveProjectBinaryEntryPoint(\n\tprojectRoot: string,\n\tpackageName: string,\n\tbinaryName: string,\n): Promise<string | null> {\n\tconst pkgJsonPath = join(projectRoot, 'node_modules', packageName, 'package.json')\n\ttry {\n\t\tconst content = await readFile(pkgJsonPath, 'utf-8')\n\t\tconst pkg = JSON.parse(content) as { bin?: string | Record<string, string> }\n\t\tlet binPath: string | undefined\n\t\tif (typeof pkg.bin === 'string') {\n\t\t\tbinPath = pkg.bin\n\t\t} else if (typeof pkg.bin === 'object' && pkg.bin !== null) {\n\t\t\tbinPath = pkg.bin[binaryName]\n\t\t}\n\t\tif (!binPath) return null\n\t\tconst fullPath = join(projectRoot, 'node_modules', packageName, binPath)\n\t\tawait access(fullPath)\n\t\treturn fullPath\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction isKoraProject(pkg: unknown): boolean {\n\tif (typeof pkg !== 'object' || pkg === null) return false\n\tconst record = pkg as Record<string, unknown>\n\treturn hasKoraDep(record.dependencies) || hasKoraDep(record.devDependencies)\n}\n\nfunction hasKoraDep(deps: unknown): boolean {\n\tif (typeof deps !== 'object' || deps === null) return false\n\treturn Object.keys(deps).some((key) => key === 'kora' || key.startsWith('@korajs/'))\n}\n"],"mappings":"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","names":["resolve","readFile","join","join","readFile"]}
|