@korajs/cli 1.0.0-beta.1 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +474 -253
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +15 -5
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-EOWLAAIV.js → chunk-4IKCHRJ6.js} +273 -57
- package/dist/chunk-4IKCHRJ6.js.map +1 -0
- package/dist/{chunk-B5YS4STN.js → chunk-G2PBYMMA.js} +2 -2
- package/dist/{chunk-B5YS4STN.js.map → chunk-G2PBYMMA.js.map} +1 -1
- package/dist/{chunk-BWTKRKNJ.js → chunk-ZTVVAYHJ.js} +2 -2
- package/dist/create.cjs +1 -1
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +2 -2
- package/dist/index.cjs +389 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -1
- package/dist/index.d.ts +58 -1
- package/dist/index.js +12 -2
- package/package.json +8 -8
- package/dist/chunk-EOWLAAIV.js.map +0 -1
- /package/dist/{chunk-BWTKRKNJ.js.map → chunk-ZTVVAYHJ.js.map} +0 -0
package/dist/bin.cjs
CHANGED
|
@@ -32,25 +32,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
32
32
|
// src/utils/fs-helpers.ts
|
|
33
33
|
async function directoryExists(path) {
|
|
34
34
|
try {
|
|
35
|
-
await (0,
|
|
35
|
+
await (0, import_promises.access)(path);
|
|
36
36
|
return true;
|
|
37
37
|
} catch {
|
|
38
38
|
return false;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
async function findProjectRoot(startDir) {
|
|
42
|
-
let current = (0,
|
|
42
|
+
let current = (0, import_node_path.resolve)(startDir ?? process.cwd());
|
|
43
43
|
for (; ; ) {
|
|
44
|
-
const pkgPath = (0,
|
|
44
|
+
const pkgPath = (0, import_node_path.join)(current, "package.json");
|
|
45
45
|
try {
|
|
46
|
-
const content = await (0,
|
|
46
|
+
const content = await (0, import_promises.readFile)(pkgPath, "utf-8");
|
|
47
47
|
const pkg = JSON.parse(content);
|
|
48
48
|
if (isKoraProject(pkg)) {
|
|
49
49
|
return current;
|
|
50
50
|
}
|
|
51
51
|
} catch {
|
|
52
52
|
}
|
|
53
|
-
const parent = (0,
|
|
53
|
+
const parent = (0, import_node_path.dirname)(current);
|
|
54
54
|
if (parent === current) break;
|
|
55
55
|
current = parent;
|
|
56
56
|
}
|
|
@@ -58,14 +58,14 @@ async function findProjectRoot(startDir) {
|
|
|
58
58
|
}
|
|
59
59
|
async function findSchemaFile(projectRoot) {
|
|
60
60
|
const candidates = [
|
|
61
|
-
(0,
|
|
62
|
-
(0,
|
|
63
|
-
(0,
|
|
64
|
-
(0,
|
|
61
|
+
(0, import_node_path.join)(projectRoot, "src", "schema.ts"),
|
|
62
|
+
(0, import_node_path.join)(projectRoot, "schema.ts"),
|
|
63
|
+
(0, import_node_path.join)(projectRoot, "src", "schema.js"),
|
|
64
|
+
(0, import_node_path.join)(projectRoot, "schema.js")
|
|
65
65
|
];
|
|
66
66
|
for (const candidate of candidates) {
|
|
67
67
|
try {
|
|
68
|
-
await (0,
|
|
68
|
+
await (0, import_promises.access)(candidate);
|
|
69
69
|
return candidate;
|
|
70
70
|
} catch {
|
|
71
71
|
}
|
|
@@ -74,16 +74,16 @@ async function findSchemaFile(projectRoot) {
|
|
|
74
74
|
}
|
|
75
75
|
async function hasTsxInstalled(projectRoot) {
|
|
76
76
|
try {
|
|
77
|
-
await (0,
|
|
77
|
+
await (0, import_promises.access)((0, import_node_path.join)(projectRoot, "node_modules", "tsx", "package.json"));
|
|
78
78
|
return true;
|
|
79
79
|
} catch {
|
|
80
80
|
return false;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
async function resolveProjectBinaryEntryPoint(projectRoot, packageName, binaryName) {
|
|
84
|
-
const pkgJsonPath = (0,
|
|
84
|
+
const pkgJsonPath = (0, import_node_path.join)(projectRoot, "node_modules", packageName, "package.json");
|
|
85
85
|
try {
|
|
86
|
-
const content = await (0,
|
|
86
|
+
const content = await (0, import_promises.readFile)(pkgJsonPath, "utf-8");
|
|
87
87
|
const pkg = JSON.parse(content);
|
|
88
88
|
let binPath;
|
|
89
89
|
if (typeof pkg.bin === "string") {
|
|
@@ -92,8 +92,8 @@ async function resolveProjectBinaryEntryPoint(projectRoot, packageName, binaryNa
|
|
|
92
92
|
binPath = pkg.bin[binaryName];
|
|
93
93
|
}
|
|
94
94
|
if (!binPath) return null;
|
|
95
|
-
const fullPath = (0,
|
|
96
|
-
await (0,
|
|
95
|
+
const fullPath = (0, import_node_path.join)(projectRoot, "node_modules", packageName, binPath);
|
|
96
|
+
await (0, import_promises.access)(fullPath);
|
|
97
97
|
return fullPath;
|
|
98
98
|
} catch {
|
|
99
99
|
return null;
|
|
@@ -108,12 +108,12 @@ function hasKoraDep(deps) {
|
|
|
108
108
|
if (typeof deps !== "object" || deps === null) return false;
|
|
109
109
|
return Object.keys(deps).some((key) => key === "kora" || key.startsWith("@korajs/"));
|
|
110
110
|
}
|
|
111
|
-
var
|
|
111
|
+
var import_promises, import_node_path;
|
|
112
112
|
var init_fs_helpers = __esm({
|
|
113
113
|
"src/utils/fs-helpers.ts"() {
|
|
114
114
|
"use strict";
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
import_promises = require("fs/promises");
|
|
116
|
+
import_node_path = require("path");
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
|
|
@@ -123,7 +123,7 @@ __export(schema_loader_exports, {
|
|
|
123
123
|
loadSchemaDefinition: () => loadSchemaDefinition
|
|
124
124
|
});
|
|
125
125
|
async function loadSchemaDefinition(schemaPath, projectRoot) {
|
|
126
|
-
const ext = (0,
|
|
126
|
+
const ext = (0, import_node_path5.extname)(schemaPath);
|
|
127
127
|
const moduleValue = ext === ".ts" || ext === ".mts" || ext === ".cts" ? await loadTypeScriptModule(schemaPath, projectRoot) : await import(`${(0, import_node_url2.pathToFileURL)(schemaPath).href}?t=${Date.now()}-${Math.random()}`);
|
|
128
128
|
return extractSchema(moduleValue);
|
|
129
129
|
}
|
|
@@ -190,12 +190,12 @@ async function runCommand2(command, args, cwd) {
|
|
|
190
190
|
});
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
|
-
var import_node_child_process2,
|
|
193
|
+
var import_node_child_process2, import_node_path5, import_node_url2;
|
|
194
194
|
var init_schema_loader = __esm({
|
|
195
195
|
"src/commands/migrate/schema-loader.ts"() {
|
|
196
196
|
"use strict";
|
|
197
197
|
import_node_child_process2 = require("child_process");
|
|
198
|
-
|
|
198
|
+
import_node_path5 = require("path");
|
|
199
199
|
import_node_url2 = require("url");
|
|
200
200
|
init_fs_helpers();
|
|
201
201
|
}
|
|
@@ -1981,13 +1981,13 @@ var spectator_manager_exports = {};
|
|
|
1981
1981
|
__export(spectator_manager_exports, {
|
|
1982
1982
|
SpectatorManager: () => SpectatorManager
|
|
1983
1983
|
});
|
|
1984
|
-
var import_node_fs6, import_node_os,
|
|
1984
|
+
var import_node_fs6, import_node_os, import_node_path28, FORWARDED_EVENTS, MAX_EVENT_BUFFER, SpectatorManager;
|
|
1985
1985
|
var init_spectator_manager = __esm({
|
|
1986
1986
|
"src/commands/studio/spectator-manager.ts"() {
|
|
1987
1987
|
"use strict";
|
|
1988
1988
|
import_node_fs6 = require("fs");
|
|
1989
1989
|
import_node_os = require("os");
|
|
1990
|
-
|
|
1990
|
+
import_node_path28 = require("path");
|
|
1991
1991
|
FORWARDED_EVENTS = [
|
|
1992
1992
|
"merge:started",
|
|
1993
1993
|
"merge:conflict",
|
|
@@ -2001,8 +2001,8 @@ var init_spectator_manager = __esm({
|
|
|
2001
2001
|
SpectatorManager = class {
|
|
2002
2002
|
constructor(options) {
|
|
2003
2003
|
this.options = options;
|
|
2004
|
-
this.tmpDir = (0, import_node_fs6.mkdtempSync)((0,
|
|
2005
|
-
this.dbPath = (0,
|
|
2004
|
+
this.tmpDir = (0, import_node_fs6.mkdtempSync)((0, import_node_path28.join)((0, import_node_os.tmpdir)(), "kora-studio-spectator-"));
|
|
2005
|
+
this.dbPath = (0, import_node_path28.join)(this.tmpDir, "spectator-replica.db");
|
|
2006
2006
|
}
|
|
2007
2007
|
options;
|
|
2008
2008
|
runtime = null;
|
|
@@ -2182,13 +2182,13 @@ function summarizeEvent(type, payload) {
|
|
|
2182
2182
|
return type.replace("lab:", "");
|
|
2183
2183
|
}
|
|
2184
2184
|
}
|
|
2185
|
-
var import_node_fs7, import_node_os2,
|
|
2185
|
+
var import_node_fs7, import_node_os2, import_node_path29, import_core3, DEFAULT_CHAOS, FORWARDED_EVENTS2, MAX_EVENT_BUFFER2, LabManager;
|
|
2186
2186
|
var init_lab_manager = __esm({
|
|
2187
2187
|
"src/commands/studio/lab-manager.ts"() {
|
|
2188
2188
|
"use strict";
|
|
2189
2189
|
import_node_fs7 = require("fs");
|
|
2190
2190
|
import_node_os2 = require("os");
|
|
2191
|
-
|
|
2191
|
+
import_node_path29 = require("path");
|
|
2192
2192
|
import_core3 = require("@korajs/core");
|
|
2193
2193
|
DEFAULT_CHAOS = {
|
|
2194
2194
|
dropRate: 0,
|
|
@@ -2246,7 +2246,7 @@ var init_lab_manager = __esm({
|
|
|
2246
2246
|
}
|
|
2247
2247
|
async start(initialDevices = 2) {
|
|
2248
2248
|
const harness = await this.loadHarness();
|
|
2249
|
-
this.tmpDir = (0, import_node_fs7.mkdtempSync)((0,
|
|
2249
|
+
this.tmpDir = (0, import_node_fs7.mkdtempSync)((0, import_node_path29.join)((0, import_node_os2.tmpdir)(), "kora-studio-lab-"));
|
|
2250
2250
|
this.server = new harness.TestServer(this.schema);
|
|
2251
2251
|
for (let i = 0; i < initialDevices; i++) {
|
|
2252
2252
|
await this.addDevice();
|
|
@@ -2298,7 +2298,7 @@ var init_lab_manager = __esm({
|
|
|
2298
2298
|
nodeId: entry.device.getNodeId(),
|
|
2299
2299
|
connected: entry.device.isConnected(),
|
|
2300
2300
|
chaos: { ...entry.chaos },
|
|
2301
|
-
dbPath: (0,
|
|
2301
|
+
dbPath: (0, import_node_path29.join)(this.tmpDir ?? "", `test-device-${name}.db`),
|
|
2302
2302
|
pendingOperations: entry.device.getSyncEngine()?.getStatus().pendingOperations ?? 0
|
|
2303
2303
|
};
|
|
2304
2304
|
}
|
|
@@ -2409,12 +2409,13 @@ var init_lab_manager = __esm({
|
|
|
2409
2409
|
});
|
|
2410
2410
|
|
|
2411
2411
|
// src/bin.ts
|
|
2412
|
-
var
|
|
2412
|
+
var import_citty13 = require("citty");
|
|
2413
2413
|
|
|
2414
|
-
// src/commands/
|
|
2415
|
-
var
|
|
2416
|
-
var
|
|
2414
|
+
// src/commands/agents/agents-command.ts
|
|
2415
|
+
var import_promises2 = require("fs/promises");
|
|
2416
|
+
var import_node_path2 = require("path");
|
|
2417
2417
|
var import_citty = require("citty");
|
|
2418
|
+
init_fs_helpers();
|
|
2418
2419
|
|
|
2419
2420
|
// src/utils/logger.ts
|
|
2420
2421
|
var RESET = "\x1B[0m";
|
|
@@ -2451,22 +2452,233 @@ function createLogger(options) {
|
|
|
2451
2452
|
banner() {
|
|
2452
2453
|
console.log();
|
|
2453
2454
|
console.log(
|
|
2454
|
-
color(BOLD + CYAN, " Kora.js") + color(DIM, "
|
|
2455
|
+
color(BOLD + CYAN, " Kora.js") + color(DIM, ", the offline-first application framework")
|
|
2455
2456
|
);
|
|
2456
2457
|
console.log();
|
|
2457
2458
|
}
|
|
2458
2459
|
};
|
|
2459
2460
|
}
|
|
2460
2461
|
|
|
2462
|
+
// src/commands/agents/agents-md-content.ts
|
|
2463
|
+
var AGENTS_FRAMEWORKS = ["react", "vue", "svelte"];
|
|
2464
|
+
function isAgentsFramework(value) {
|
|
2465
|
+
return AGENTS_FRAMEWORKS.includes(value);
|
|
2466
|
+
}
|
|
2467
|
+
function detectFrameworkFromManifest(manifest) {
|
|
2468
|
+
if (typeof manifest !== "object" || manifest === null) return null;
|
|
2469
|
+
const record = manifest;
|
|
2470
|
+
const deps = collectDependencyNames(record.dependencies, record.devDependencies);
|
|
2471
|
+
if (deps.has("@korajs/react")) return "react";
|
|
2472
|
+
if (deps.has("@korajs/vue")) return "vue";
|
|
2473
|
+
if (deps.has("@korajs/svelte")) return "svelte";
|
|
2474
|
+
return null;
|
|
2475
|
+
}
|
|
2476
|
+
function collectDependencyNames(...groups) {
|
|
2477
|
+
const names = /* @__PURE__ */ new Set();
|
|
2478
|
+
for (const group of groups) {
|
|
2479
|
+
if (typeof group !== "object" || group === null) continue;
|
|
2480
|
+
for (const name of Object.keys(group)) {
|
|
2481
|
+
names.add(name);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
return names;
|
|
2485
|
+
}
|
|
2486
|
+
var FRAMEWORK_BINDINGS = {
|
|
2487
|
+
react: `## React bindings
|
|
2488
|
+
|
|
2489
|
+
\`\`\`tsx
|
|
2490
|
+
import { KoraProvider, useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/react'
|
|
2491
|
+
|
|
2492
|
+
// Wrap the tree once near your app entry: <KoraProvider app={app}><App /></KoraProvider>
|
|
2493
|
+
|
|
2494
|
+
const todos = useCollection('todos')
|
|
2495
|
+
const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt'))
|
|
2496
|
+
const addTodo = useMutation((data) => todos.insert(data))
|
|
2497
|
+
addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
|
|
2498
|
+
await addTodo.mutateAsync({ title: 'x' }) // resolves with the result; throws on failure
|
|
2499
|
+
const status = useSyncStatus() // status.status, status.pendingOperations
|
|
2500
|
+
\`\`\`
|
|
2501
|
+
|
|
2502
|
+
Rules: always render \`mutation.error\` somewhere. Keep \`<StrictMode>\` in place; the hooks are StrictMode-safe. \`useQuery\` returns data synchronously from the local store, so do not add loading spinners for local reads.`,
|
|
2503
|
+
vue: `## Vue bindings
|
|
2504
|
+
|
|
2505
|
+
\`\`\`ts
|
|
2506
|
+
import { useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/vue'
|
|
2507
|
+
|
|
2508
|
+
const todos = useCollection('todos')
|
|
2509
|
+
const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt')) // readonly reactive ref
|
|
2510
|
+
const addTodo = useMutation((data) => todos.insert(data))
|
|
2511
|
+
addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
|
|
2512
|
+
const status = useSyncStatus() // status.status, status.pendingOperations
|
|
2513
|
+
\`\`\`
|
|
2514
|
+
|
|
2515
|
+
Rules: 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 comes from \`KoraProvider\`, wired in your app entry (for example \`src/main.ts\`).`,
|
|
2516
|
+
svelte: `## Svelte bindings
|
|
2517
|
+
|
|
2518
|
+
Kora's Svelte bindings from \`@korajs/svelte\` expose \`useCollection\`, \`useQuery\`, \`useMutation\`, and \`useSyncStatus\`, wired through the provider set up in your app entry.
|
|
2519
|
+
|
|
2520
|
+
\`\`\`ts
|
|
2521
|
+
import { useCollection, useMutation, useQuery, useSyncStatus } from '@korajs/svelte'
|
|
2522
|
+
|
|
2523
|
+
const todos = useCollection('todos')
|
|
2524
|
+
const rows = useQuery(todos.where({ completed: false }).orderBy('createdAt')) // reactive store
|
|
2525
|
+
const addTodo = useMutation((data) => todos.insert(data))
|
|
2526
|
+
addTodo.mutate({ title: 'x' }) // fire-and-forget; errors land in addTodo.error
|
|
2527
|
+
const status = useSyncStatus() // readable store; read $status.status in markup
|
|
2528
|
+
\`\`\`
|
|
2529
|
+
|
|
2530
|
+
Rules: queries are reactive stores that read synchronously from the local database, so avoid loading spinners for local reads. Mutations expose an \`error\` state that must be surfaced in the UI.`
|
|
2531
|
+
};
|
|
2532
|
+
function generateAgentsMd(framework) {
|
|
2533
|
+
return `# AGENTS.md
|
|
2534
|
+
|
|
2535
|
+
Guidance for AI coding agents working in this project. Humans: this is useful for you too.
|
|
2536
|
+
|
|
2537
|
+
## What this project is
|
|
2538
|
+
|
|
2539
|
+
This project uses **Kora.js**, an offline-first application framework. All application data lives in a local SQLite database (WASM + OPFS in the browser, native SQLite on desktop and server) and optionally syncs across devices through a Kora sync server. Offline is the normal state, not an error state. Full docs live at https://korajs.dev, with a machine-readable index at https://korajs.dev/llms.txt and the complete docs in one file at https://korajs.dev/llms-full.txt. Any documentation page is available as raw markdown by appending \`.md\` to its URL.
|
|
2540
|
+
|
|
2541
|
+
## Golden rules
|
|
2542
|
+
|
|
2543
|
+
1. **The schema is the source of truth.** Collections are defined with \`defineSchema\` and the \`t.*\` field builders (by convention in \`src/schema.ts\`). To add or change data shapes, edit the schema first; types flow from it automatically. Never hand-write types for records.
|
|
2544
|
+
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.
|
|
2545
|
+
3. **Await readiness before direct collection access.** Outside the UI bindings, \`await app.ready\` before calling \`app.<collection>\` methods. The framework bindings handle this for you inside components.
|
|
2546
|
+
4. **Offline must keep working.** Any feature you add must function with the network off. Never gate a read or write on connectivity. If you are checking \`navigator.onLine\` before a data operation, you are doing it wrong.
|
|
2547
|
+
5. **Surface mutation errors.** Fire-and-forget \`mutate\` calls fold errors into the mutation state. Always render the mutation's \`error\`, or handle the promise from the \`mutateAsync\` variant. Silent failure is the worst failure.
|
|
2548
|
+
6. **Do not add a state library for server or app data.** Kora's reactive queries are the store. Do not reach for react-query, SWR, Redux, Zustand, or similar for data that lives in a collection. Local UI state (form inputs, toggles) can use your framework's normal state tools.
|
|
2549
|
+
7. **Do not add loading spinners for local reads.** \`useQuery\` returns data synchronously from the local store, so there is no loading state to wait on for local data.
|
|
2550
|
+
|
|
2551
|
+
## Data API cheat sheet
|
|
2552
|
+
|
|
2553
|
+
\`\`\`ts
|
|
2554
|
+
await app.ready
|
|
2555
|
+
const rec = await app.todos.insert({ title: 'x' }) // defaults and .auto() fields applied
|
|
2556
|
+
await app.todos.update(rec.id, { completed: true }) // partial update, changed fields only
|
|
2557
|
+
await app.todos.delete(rec.id)
|
|
2558
|
+
const one = await app.todos.findById(rec.id)
|
|
2559
|
+
const unsubscribe = app.todos
|
|
2560
|
+
.where({ completed: false })
|
|
2561
|
+
.orderBy('createdAt', 'desc')
|
|
2562
|
+
.subscribe((rows) => {/* fires immediately, then on every change */})
|
|
2563
|
+
\`\`\`
|
|
2564
|
+
|
|
2565
|
+
Schema example (\`src/schema.ts\`):
|
|
2566
|
+
|
|
2567
|
+
\`\`\`ts
|
|
2568
|
+
import { defineSchema, t } from 'korajs'
|
|
2569
|
+
|
|
2570
|
+
export default defineSchema({
|
|
2571
|
+
version: 1,
|
|
2572
|
+
collections: {
|
|
2573
|
+
todos: {
|
|
2574
|
+
fields: {
|
|
2575
|
+
title: t.string(),
|
|
2576
|
+
completed: t.boolean().default(false),
|
|
2577
|
+
tags: t.array(t.string()).default([]),
|
|
2578
|
+
priority: t.enum(['low', 'medium', 'high']).default('medium'),
|
|
2579
|
+
createdAt: t.timestamp().auto(), // set automatically; never pass it on insert
|
|
2580
|
+
},
|
|
2581
|
+
indexes: ['completed', 'createdAt'],
|
|
2582
|
+
},
|
|
2583
|
+
},
|
|
2584
|
+
})
|
|
2585
|
+
\`\`\`
|
|
2586
|
+
|
|
2587
|
+
If you change collection shapes, increment \`version\` and run \`npx kora migrate\`.
|
|
2588
|
+
|
|
2589
|
+
## Conflict handling
|
|
2590
|
+
|
|
2591
|
+
Concurrent edits merge automatically: last-write-wins per field, add-wins for arrays, and character-level CRDT for \`t.richtext()\` fields. When a field needs domain-specific merging (counters, quantities), add a \`resolve\` function in the schema rather than writing sync logic by hand. Never write your own conflict or merge code.
|
|
2592
|
+
|
|
2593
|
+
## Sync and auth
|
|
2594
|
+
|
|
2595
|
+
Enable sync by adding one line to \`createApp\`: \`createApp({ schema, sync: { url } })\`. When the app is offline, writes queue locally and sync when connectivity returns. If the project uses \`@korajs/auth\`, pass its client as \`createApp({ schema, sync: { url, authClient } })\`. Local writes work without sign-in; sync requires the server to accept the connection.
|
|
2596
|
+
|
|
2597
|
+
${FRAMEWORK_BINDINGS[framework]}
|
|
2598
|
+
|
|
2599
|
+
## Commands
|
|
2600
|
+
|
|
2601
|
+
- \`npx kora dev\` runs the dev environment (app server, local sync server when configured, schema watcher).
|
|
2602
|
+
- \`npx kora doctor\` diagnoses a broken setup.
|
|
2603
|
+
- \`npx kora migrate\` applies a schema change to the local store.
|
|
2604
|
+
- In a running app, the DevTools overlay (Ctrl+Shift+K, Cmd+Shift+K on macOS) inspects operations, merges, and sync status.
|
|
2605
|
+
`;
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// src/commands/agents/agents-command.ts
|
|
2609
|
+
async function fileExists(path) {
|
|
2610
|
+
try {
|
|
2611
|
+
await (0, import_promises2.access)(path);
|
|
2612
|
+
return true;
|
|
2613
|
+
} catch {
|
|
2614
|
+
return false;
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
async function readManifest(root) {
|
|
2618
|
+
try {
|
|
2619
|
+
return JSON.parse(await (0, import_promises2.readFile)((0, import_node_path2.join)(root, "package.json"), "utf-8"));
|
|
2620
|
+
} catch {
|
|
2621
|
+
return null;
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
function resolveFramework(override, manifest) {
|
|
2625
|
+
if (override !== void 0 && isAgentsFramework(override)) return override;
|
|
2626
|
+
return detectFrameworkFromManifest(manifest) ?? "react";
|
|
2627
|
+
}
|
|
2628
|
+
var agentsCommand = (0, import_citty.defineCommand)({
|
|
2629
|
+
meta: {
|
|
2630
|
+
name: "agents-md",
|
|
2631
|
+
description: "Write an AGENTS.md with Kora rules for AI coding agents into this project"
|
|
2632
|
+
},
|
|
2633
|
+
args: {
|
|
2634
|
+
force: {
|
|
2635
|
+
type: "boolean",
|
|
2636
|
+
description: "Overwrite an existing AGENTS.md",
|
|
2637
|
+
default: false
|
|
2638
|
+
},
|
|
2639
|
+
framework: {
|
|
2640
|
+
type: "string",
|
|
2641
|
+
description: "Override framework detection (react, vue, or svelte)"
|
|
2642
|
+
}
|
|
2643
|
+
},
|
|
2644
|
+
async run({ args }) {
|
|
2645
|
+
const logger = createLogger();
|
|
2646
|
+
const projectRoot = await findProjectRoot() ?? process.cwd();
|
|
2647
|
+
const manifest = await readManifest(projectRoot);
|
|
2648
|
+
const override = typeof args.framework === "string" ? args.framework : void 0;
|
|
2649
|
+
if (override !== void 0 && !isAgentsFramework(override)) {
|
|
2650
|
+
logger.error(`Unknown framework "${override}". Use one of: react, vue, svelte.`);
|
|
2651
|
+
process.exitCode = 1;
|
|
2652
|
+
return;
|
|
2653
|
+
}
|
|
2654
|
+
const framework = resolveFramework(override, manifest);
|
|
2655
|
+
const target = (0, import_node_path2.join)(projectRoot, "AGENTS.md");
|
|
2656
|
+
const force = args.force === true;
|
|
2657
|
+
if (await fileExists(target) && !force) {
|
|
2658
|
+
logger.warn("AGENTS.md already exists. Re-run with --force to overwrite it.");
|
|
2659
|
+
process.exitCode = 1;
|
|
2660
|
+
return;
|
|
2661
|
+
}
|
|
2662
|
+
await (0, import_promises2.writeFile)(target, generateAgentsMd(framework), "utf-8");
|
|
2663
|
+
logger.banner();
|
|
2664
|
+
logger.success(`Wrote AGENTS.md (${framework} bindings) to ${target}`);
|
|
2665
|
+
logger.step("Commit it so coding agents pick up Kora conventions automatically.");
|
|
2666
|
+
logger.blank();
|
|
2667
|
+
}
|
|
2668
|
+
});
|
|
2669
|
+
|
|
2461
2670
|
// src/commands/backup/backup-command.ts
|
|
2671
|
+
var import_promises3 = require("fs/promises");
|
|
2672
|
+
var import_node_path3 = require("path");
|
|
2673
|
+
var import_citty2 = require("citty");
|
|
2462
2674
|
var DEFAULT_SYNC_PORT = 3001;
|
|
2463
|
-
var backupCommand = (0,
|
|
2675
|
+
var backupCommand = (0, import_citty2.defineCommand)({
|
|
2464
2676
|
meta: {
|
|
2465
2677
|
name: "backup",
|
|
2466
2678
|
description: "Backup and restore Kora sync server data"
|
|
2467
2679
|
},
|
|
2468
2680
|
subCommands: {
|
|
2469
|
-
create: (0,
|
|
2681
|
+
create: (0, import_citty2.defineCommand)({
|
|
2470
2682
|
meta: {
|
|
2471
2683
|
name: "create",
|
|
2472
2684
|
description: "Create a backup of the sync server"
|
|
@@ -2506,7 +2718,7 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2506
2718
|
);
|
|
2507
2719
|
}
|
|
2508
2720
|
const buffer = await response.arrayBuffer();
|
|
2509
|
-
await (0,
|
|
2721
|
+
await (0, import_promises3.writeFile)(outFile, new Uint8Array(buffer));
|
|
2510
2722
|
const size = (buffer.byteLength / 1024).toFixed(1);
|
|
2511
2723
|
logger.success(`Backup saved to ${outFile} (${size} KB)`);
|
|
2512
2724
|
} catch (error) {
|
|
@@ -2518,7 +2730,7 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2518
2730
|
}
|
|
2519
2731
|
}
|
|
2520
2732
|
}),
|
|
2521
|
-
restore: (0,
|
|
2733
|
+
restore: (0, import_citty2.defineCommand)({
|
|
2522
2734
|
meta: {
|
|
2523
2735
|
name: "restore",
|
|
2524
2736
|
description: "Restore a backup to the sync server"
|
|
@@ -2553,7 +2765,7 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2553
2765
|
logger.banner();
|
|
2554
2766
|
logger.info(`Restoring backup from ${filePath} to ${url}...`);
|
|
2555
2767
|
try {
|
|
2556
|
-
const data = await (0,
|
|
2768
|
+
const data = await (0, import_promises3.readFile)(filePath);
|
|
2557
2769
|
const restoreUrl = `${url.replace(/\/$/, "")}/__kora/backup/import?merge=${merge}`;
|
|
2558
2770
|
const response = await fetch(restoreUrl, {
|
|
2559
2771
|
method: "POST",
|
|
@@ -2581,7 +2793,7 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2581
2793
|
}
|
|
2582
2794
|
}
|
|
2583
2795
|
}),
|
|
2584
|
-
info: (0,
|
|
2796
|
+
info: (0, import_citty2.defineCommand)({
|
|
2585
2797
|
meta: {
|
|
2586
2798
|
name: "info",
|
|
2587
2799
|
description: "Show backup file information"
|
|
@@ -2597,7 +2809,7 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2597
2809
|
const logger = createLogger();
|
|
2598
2810
|
const filePath = typeof args.file === "string" ? args.file : "";
|
|
2599
2811
|
try {
|
|
2600
|
-
const data = await (0,
|
|
2812
|
+
const data = await (0, import_promises3.readFile)(filePath);
|
|
2601
2813
|
const { readBackupManifest } = await import("@korajs/store");
|
|
2602
2814
|
const manifest = readBackupManifest(
|
|
2603
2815
|
new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
|
|
@@ -2624,8 +2836,8 @@ var backupCommand = (0, import_citty.defineCommand)({
|
|
|
2624
2836
|
});
|
|
2625
2837
|
|
|
2626
2838
|
// src/commands/compact/compact-command.ts
|
|
2627
|
-
var
|
|
2628
|
-
var
|
|
2839
|
+
var import_node_path6 = require("path");
|
|
2840
|
+
var import_citty3 = require("citty");
|
|
2629
2841
|
|
|
2630
2842
|
// src/errors.ts
|
|
2631
2843
|
var import_core = require("@korajs/core");
|
|
@@ -2685,8 +2897,8 @@ init_fs_helpers();
|
|
|
2685
2897
|
|
|
2686
2898
|
// src/commands/dev/kora-config.ts
|
|
2687
2899
|
var import_node_child_process = require("child_process");
|
|
2688
|
-
var
|
|
2689
|
-
var
|
|
2900
|
+
var import_promises4 = require("fs/promises");
|
|
2901
|
+
var import_node_path4 = require("path");
|
|
2690
2902
|
var import_node_url = require("url");
|
|
2691
2903
|
init_fs_helpers();
|
|
2692
2904
|
var CONFIG_CANDIDATES = [
|
|
@@ -2700,7 +2912,7 @@ var CONFIG_CANDIDATES = [
|
|
|
2700
2912
|
async function loadKoraConfig(projectRoot) {
|
|
2701
2913
|
const configPath = await findKoraConfigFile(projectRoot);
|
|
2702
2914
|
if (!configPath) return null;
|
|
2703
|
-
const ext = (0,
|
|
2915
|
+
const ext = (0, import_node_path4.extname)(configPath);
|
|
2704
2916
|
if (ext === ".ts" || ext === ".mts" || ext === ".cts") {
|
|
2705
2917
|
const loaded2 = await loadTypeScriptConfig(configPath, projectRoot);
|
|
2706
2918
|
return toConfigObject(loaded2);
|
|
@@ -2710,9 +2922,9 @@ async function loadKoraConfig(projectRoot) {
|
|
|
2710
2922
|
}
|
|
2711
2923
|
async function findKoraConfigFile(projectRoot) {
|
|
2712
2924
|
for (const file of CONFIG_CANDIDATES) {
|
|
2713
|
-
const candidate = (0,
|
|
2925
|
+
const candidate = (0, import_node_path4.join)(projectRoot, file);
|
|
2714
2926
|
try {
|
|
2715
|
-
await (0,
|
|
2927
|
+
await (0, import_promises4.access)(candidate);
|
|
2716
2928
|
return candidate;
|
|
2717
2929
|
} catch {
|
|
2718
2930
|
}
|
|
@@ -2777,7 +2989,7 @@ function toConfigObject(mod) {
|
|
|
2777
2989
|
|
|
2778
2990
|
// src/commands/compact/compact-command.ts
|
|
2779
2991
|
init_schema_loader();
|
|
2780
|
-
var compactCommand = (0,
|
|
2992
|
+
var compactCommand = (0, import_citty3.defineCommand)({
|
|
2781
2993
|
meta: {
|
|
2782
2994
|
name: "compact",
|
|
2783
2995
|
description: "Compact the local Kora operation log after server ack"
|
|
@@ -2808,12 +3020,12 @@ var compactCommand = (0, import_citty2.defineCommand)({
|
|
|
2808
3020
|
if (!projectRoot) {
|
|
2809
3021
|
throw new InvalidProjectError(process.cwd());
|
|
2810
3022
|
}
|
|
2811
|
-
const dbPath = typeof args.db === "string" ? (0,
|
|
3023
|
+
const dbPath = typeof args.db === "string" ? (0, import_node_path6.resolve)(projectRoot, args.db) : void 0;
|
|
2812
3024
|
if (!dbPath) {
|
|
2813
3025
|
throw new Error("Missing --db <path> to the local SQLite database file.");
|
|
2814
3026
|
}
|
|
2815
3027
|
const config = await loadKoraConfig(projectRoot);
|
|
2816
|
-
const schemaPath = typeof args.schema === "string" ? (0,
|
|
3028
|
+
const schemaPath = typeof args.schema === "string" ? (0, import_node_path6.resolve)(projectRoot, args.schema) : typeof config?.schema === "string" ? (0, import_node_path6.resolve)(projectRoot, config.schema) : void 0;
|
|
2817
3029
|
if (!schemaPath) {
|
|
2818
3030
|
throw new Error("Could not resolve schema path. Pass --schema <path>.");
|
|
2819
3031
|
}
|
|
@@ -2850,9 +3062,9 @@ var compactCommand = (0, import_citty2.defineCommand)({
|
|
|
2850
3062
|
// src/commands/create/create-command.ts
|
|
2851
3063
|
var import_node_child_process4 = require("child_process");
|
|
2852
3064
|
var import_node_fs2 = require("fs");
|
|
2853
|
-
var
|
|
3065
|
+
var import_node_path10 = require("path");
|
|
2854
3066
|
var import_node_url4 = require("url");
|
|
2855
|
-
var
|
|
3067
|
+
var import_citty4 = require("citty");
|
|
2856
3068
|
|
|
2857
3069
|
// src/prompts/preferences.ts
|
|
2858
3070
|
var import_conf = __toESM(require("conf"), 1);
|
|
@@ -3099,8 +3311,8 @@ function getRunDevCommand(pm) {
|
|
|
3099
3311
|
}
|
|
3100
3312
|
|
|
3101
3313
|
// src/commands/create/environment-detection.ts
|
|
3102
|
-
var
|
|
3103
|
-
var
|
|
3314
|
+
var import_promises5 = require("fs/promises");
|
|
3315
|
+
var import_node_path7 = require("path");
|
|
3104
3316
|
function detectEditorFromEnvironment(env = process.env) {
|
|
3105
3317
|
const termProgram = String(env.TERM_PROGRAM ?? "").toLowerCase();
|
|
3106
3318
|
const editorValue = `${String(env.EDITOR ?? "")} ${String(env.VISUAL ?? "")}`.toLowerCase();
|
|
@@ -3126,18 +3338,18 @@ async function detectGitContext(startDir) {
|
|
|
3126
3338
|
};
|
|
3127
3339
|
}
|
|
3128
3340
|
async function detectMonorepoContext(startDir) {
|
|
3129
|
-
let current = (0,
|
|
3341
|
+
let current = (0, import_node_path7.resolve)(startDir);
|
|
3130
3342
|
for (; ; ) {
|
|
3131
|
-
if (await
|
|
3343
|
+
if (await fileExists2((0, import_node_path7.join)(current, "pnpm-workspace.yaml"))) {
|
|
3132
3344
|
return { isMonorepo: true, root: current, kind: "pnpm-workspace" };
|
|
3133
3345
|
}
|
|
3134
|
-
if (await
|
|
3346
|
+
if (await fileExists2((0, import_node_path7.join)(current, "turbo.json"))) {
|
|
3135
3347
|
return { isMonorepo: true, root: current, kind: "turborepo" };
|
|
3136
3348
|
}
|
|
3137
|
-
const packageJsonPath = (0,
|
|
3138
|
-
if (await
|
|
3349
|
+
const packageJsonPath = (0, import_node_path7.join)(current, "package.json");
|
|
3350
|
+
if (await fileExists2(packageJsonPath)) {
|
|
3139
3351
|
try {
|
|
3140
|
-
const packageJsonRaw = await (0,
|
|
3352
|
+
const packageJsonRaw = await (0, import_promises5.readFile)(packageJsonPath, "utf-8");
|
|
3141
3353
|
const parsed = JSON.parse(packageJsonRaw);
|
|
3142
3354
|
if (Array.isArray(parsed.workspaces) || isNpmWorkspaceObject(parsed.workspaces)) {
|
|
3143
3355
|
return { isMonorepo: true, root: current, kind: "npm-workspaces" };
|
|
@@ -3145,7 +3357,7 @@ async function detectMonorepoContext(startDir) {
|
|
|
3145
3357
|
} catch {
|
|
3146
3358
|
}
|
|
3147
3359
|
}
|
|
3148
|
-
const parent = (0,
|
|
3360
|
+
const parent = (0, import_node_path7.dirname)(current);
|
|
3149
3361
|
if (parent === current) {
|
|
3150
3362
|
return { isMonorepo: false, root: null, kind: "none" };
|
|
3151
3363
|
}
|
|
@@ -3157,9 +3369,9 @@ async function applyEditorWorkspacePreset(params) {
|
|
|
3157
3369
|
if (editor !== "vscode" && editor !== "cursor" && editor !== "windsurf") {
|
|
3158
3370
|
return { applied: false, filePath: null };
|
|
3159
3371
|
}
|
|
3160
|
-
const vscodeDir = (0,
|
|
3161
|
-
const extensionsPath = (0,
|
|
3162
|
-
await (0,
|
|
3372
|
+
const vscodeDir = (0, import_node_path7.join)(targetDir, ".vscode");
|
|
3373
|
+
const extensionsPath = (0, import_node_path7.join)(vscodeDir, "extensions.json");
|
|
3374
|
+
await (0, import_promises5.mkdir)(vscodeDir, { recursive: true });
|
|
3163
3375
|
const recommendations = ["korajs.kora-devtools"];
|
|
3164
3376
|
const existing = await readJsonObject(extensionsPath);
|
|
3165
3377
|
const existingRecommendations = Array.isArray(existing?.recommendations) ? existing.recommendations.filter((item) => typeof item === "string") : [];
|
|
@@ -3167,19 +3379,19 @@ async function applyEditorWorkspacePreset(params) {
|
|
|
3167
3379
|
const next = {
|
|
3168
3380
|
recommendations: mergedRecommendations
|
|
3169
3381
|
};
|
|
3170
|
-
await (0,
|
|
3382
|
+
await (0, import_promises5.writeFile)(extensionsPath, `${JSON.stringify(next, null, 2)}
|
|
3171
3383
|
`, "utf-8");
|
|
3172
3384
|
return { applied: true, filePath: extensionsPath };
|
|
3173
3385
|
}
|
|
3174
3386
|
function resolveMonorepoTargetDirectory(monorepoRoot, projectName) {
|
|
3175
|
-
return (0,
|
|
3387
|
+
return (0, import_node_path7.join)(monorepoRoot, "packages", projectName);
|
|
3176
3388
|
}
|
|
3177
3389
|
function dedupeStrings(values) {
|
|
3178
3390
|
return Array.from(new Set(values));
|
|
3179
3391
|
}
|
|
3180
3392
|
async function readJsonObject(path) {
|
|
3181
3393
|
try {
|
|
3182
|
-
const content = await (0,
|
|
3394
|
+
const content = await (0, import_promises5.readFile)(path, "utf-8");
|
|
3183
3395
|
const parsed = JSON.parse(content);
|
|
3184
3396
|
if (typeof parsed === "object" && parsed !== null) {
|
|
3185
3397
|
return parsed;
|
|
@@ -3194,24 +3406,24 @@ function isNpmWorkspaceObject(value) {
|
|
|
3194
3406
|
const record = value;
|
|
3195
3407
|
return Array.isArray(record.packages);
|
|
3196
3408
|
}
|
|
3197
|
-
async function
|
|
3409
|
+
async function fileExists2(path) {
|
|
3198
3410
|
try {
|
|
3199
|
-
await (0,
|
|
3411
|
+
await (0, import_promises5.access)(path);
|
|
3200
3412
|
return true;
|
|
3201
3413
|
} catch {
|
|
3202
3414
|
return false;
|
|
3203
3415
|
}
|
|
3204
3416
|
}
|
|
3205
3417
|
async function findNearestAncestorWithEntry(startDir, entryName) {
|
|
3206
|
-
let current = (0,
|
|
3418
|
+
let current = (0, import_node_path7.resolve)(startDir);
|
|
3207
3419
|
for (; ; ) {
|
|
3208
|
-
const candidate = (0,
|
|
3420
|
+
const candidate = (0, import_node_path7.join)(current, entryName);
|
|
3209
3421
|
try {
|
|
3210
|
-
await (0,
|
|
3422
|
+
await (0, import_promises5.stat)(candidate);
|
|
3211
3423
|
return current;
|
|
3212
3424
|
} catch {
|
|
3213
3425
|
}
|
|
3214
|
-
const parent = (0,
|
|
3426
|
+
const parent = (0, import_node_path7.dirname)(current);
|
|
3215
3427
|
if (parent === current) {
|
|
3216
3428
|
return null;
|
|
3217
3429
|
}
|
|
@@ -3490,8 +3702,8 @@ function validateProjectName(name) {
|
|
|
3490
3702
|
}
|
|
3491
3703
|
|
|
3492
3704
|
// src/commands/create/sync-provider-preset.ts
|
|
3493
|
-
var
|
|
3494
|
-
var
|
|
3705
|
+
var import_promises6 = require("fs/promises");
|
|
3706
|
+
var import_node_path8 = require("path");
|
|
3495
3707
|
async function applySyncProviderPreset(options) {
|
|
3496
3708
|
if (!isSyncTemplate(options.template)) {
|
|
3497
3709
|
return;
|
|
@@ -3501,10 +3713,10 @@ async function applySyncProviderPreset(options) {
|
|
|
3501
3713
|
}
|
|
3502
3714
|
const providerName = getProviderDisplayName(options.dbProvider);
|
|
3503
3715
|
const providerConnectionString = getProviderConnectionStringExample(options.dbProvider);
|
|
3504
|
-
const envPath = (0,
|
|
3505
|
-
const readmePath = (0,
|
|
3506
|
-
const existingReadme = await (0,
|
|
3507
|
-
const existingEnv = await (0,
|
|
3716
|
+
const envPath = (0, import_node_path8.join)(options.targetDir, ".env.example");
|
|
3717
|
+
const readmePath = (0, import_node_path8.join)(options.targetDir, "README.md");
|
|
3718
|
+
const existingReadme = await (0, import_promises6.readFile)(readmePath, "utf-8");
|
|
3719
|
+
const existingEnv = await (0, import_promises6.readFile)(envPath, "utf-8");
|
|
3508
3720
|
const trimmedReadme = existingReadme.trimEnd();
|
|
3509
3721
|
const trimmedEnv = existingEnv.trimEnd();
|
|
3510
3722
|
const envSuffix = [
|
|
@@ -3524,9 +3736,9 @@ async function applySyncProviderPreset(options) {
|
|
|
3524
3736
|
""
|
|
3525
3737
|
].join("\n");
|
|
3526
3738
|
const readmeTemplate = `${trimmedReadme}${readmeSuffix}`;
|
|
3527
|
-
await (0,
|
|
3739
|
+
await (0, import_promises6.writeFile)(envPath, `${trimmedEnv}${envSuffix}
|
|
3528
3740
|
`, "utf-8");
|
|
3529
|
-
await (0,
|
|
3741
|
+
await (0, import_promises6.writeFile)(readmePath, readmeTemplate, "utf-8");
|
|
3530
3742
|
}
|
|
3531
3743
|
function isSyncTemplate(template) {
|
|
3532
3744
|
return template === "react-sync" || template === "react-tailwind-sync" || template === "vue-sync" || template === "vue-tailwind-sync" || template === "svelte-sync" || template === "svelte-tailwind-sync" || template === "tauri-react";
|
|
@@ -3570,8 +3782,8 @@ function getProviderConnectionStringExample(provider) {
|
|
|
3570
3782
|
|
|
3571
3783
|
// src/templates/composer.ts
|
|
3572
3784
|
var import_node_fs = require("fs");
|
|
3573
|
-
var
|
|
3574
|
-
var
|
|
3785
|
+
var import_promises7 = require("fs/promises");
|
|
3786
|
+
var import_node_path9 = require("path");
|
|
3575
3787
|
var import_node_url3 = require("url");
|
|
3576
3788
|
var import_meta = {};
|
|
3577
3789
|
function substituteVariables(template, context) {
|
|
@@ -3581,16 +3793,16 @@ function substituteVariables(template, context) {
|
|
|
3581
3793
|
});
|
|
3582
3794
|
}
|
|
3583
3795
|
function getTemplatePath(templateName) {
|
|
3584
|
-
let dir = (0,
|
|
3796
|
+
let dir = (0, import_node_path9.dirname)((0, import_node_url3.fileURLToPath)(import_meta.url));
|
|
3585
3797
|
for (let i = 0; i < 7; i++) {
|
|
3586
|
-
const candidate = (0,
|
|
3798
|
+
const candidate = (0, import_node_path9.resolve)(dir, "templates", templateName);
|
|
3587
3799
|
if ((0, import_node_fs.existsSync)(candidate)) {
|
|
3588
3800
|
return candidate;
|
|
3589
3801
|
}
|
|
3590
|
-
dir = (0,
|
|
3802
|
+
dir = (0, import_node_path9.dirname)(dir);
|
|
3591
3803
|
}
|
|
3592
|
-
const currentDir = (0,
|
|
3593
|
-
return (0,
|
|
3804
|
+
const currentDir = (0, import_node_path9.dirname)((0, import_node_url3.fileURLToPath)(import_meta.url));
|
|
3805
|
+
return (0, import_node_path9.resolve)(currentDir, "..", "..", "..", "templates", templateName);
|
|
3594
3806
|
}
|
|
3595
3807
|
function createCompatibilityLayerPlan(templateName) {
|
|
3596
3808
|
const baseLayer = { category: "base", name: "base", sourceTemplate: "react-basic" };
|
|
@@ -3723,22 +3935,22 @@ async function composeTemplateLayers(plan, targetDir, context) {
|
|
|
3723
3935
|
}
|
|
3724
3936
|
}
|
|
3725
3937
|
async function copyDirectory(src, dest, vars) {
|
|
3726
|
-
await (0,
|
|
3727
|
-
const entries = await (0,
|
|
3938
|
+
await (0, import_promises7.mkdir)(dest, { recursive: true });
|
|
3939
|
+
const entries = await (0, import_promises7.readdir)(src);
|
|
3728
3940
|
for (const entry of entries) {
|
|
3729
|
-
const srcPath = (0,
|
|
3730
|
-
const srcStat = await (0,
|
|
3941
|
+
const srcPath = (0, import_node_path9.join)(src, entry);
|
|
3942
|
+
const srcStat = await (0, import_promises7.stat)(srcPath);
|
|
3731
3943
|
if (srcStat.isDirectory()) {
|
|
3732
|
-
await copyDirectory(srcPath, (0,
|
|
3944
|
+
await copyDirectory(srcPath, (0, import_node_path9.join)(dest, entry), vars);
|
|
3733
3945
|
continue;
|
|
3734
3946
|
}
|
|
3735
3947
|
if (entry.endsWith(".hbs")) {
|
|
3736
|
-
const content = await (0,
|
|
3948
|
+
const content = await (0, import_promises7.readFile)(srcPath, "utf-8");
|
|
3737
3949
|
const outputName = entry.slice(0, -4);
|
|
3738
|
-
await (0,
|
|
3950
|
+
await (0, import_promises7.writeFile)((0, import_node_path9.join)(dest, outputName), substituteVariables(content, vars), "utf-8");
|
|
3739
3951
|
continue;
|
|
3740
3952
|
}
|
|
3741
|
-
await (0,
|
|
3953
|
+
await (0, import_promises7.copyFile)(srcPath, (0, import_node_path9.join)(dest, entry));
|
|
3742
3954
|
}
|
|
3743
3955
|
}
|
|
3744
3956
|
|
|
@@ -3750,7 +3962,7 @@ async function scaffoldTemplate(templateName, targetDir, context) {
|
|
|
3750
3962
|
|
|
3751
3963
|
// src/commands/create/create-command.ts
|
|
3752
3964
|
var import_meta2 = {};
|
|
3753
|
-
var createCommand = (0,
|
|
3965
|
+
var createCommand = (0, import_citty4.defineCommand)({
|
|
3754
3966
|
meta: {
|
|
3755
3967
|
name: "create",
|
|
3756
3968
|
description: "Create a new Kora application"
|
|
@@ -3891,7 +4103,7 @@ var createCommand = (0, import_citty3.defineCommand)({
|
|
|
3891
4103
|
const editorDetection = detectEditorFromEnvironment();
|
|
3892
4104
|
const gitContext = await detectGitContext(process.cwd());
|
|
3893
4105
|
const monorepoContext = await detectMonorepoContext(process.cwd());
|
|
3894
|
-
let targetDir = (0,
|
|
4106
|
+
let targetDir = (0, import_node_path10.resolve)(process.cwd(), projectName);
|
|
3895
4107
|
if (!useDefaults && monorepoContext.isMonorepo && monorepoContext.root !== null) {
|
|
3896
4108
|
const useWorkspaceTarget = await prompts.confirm(
|
|
3897
4109
|
`Detected ${formatMonorepoKind(monorepoContext.kind)} at ${monorepoContext.root}. Create app under packages/${projectName}?`,
|
|
@@ -4061,9 +4273,9 @@ function relativeToTarget(targetDir, filePath) {
|
|
|
4061
4273
|
}
|
|
4062
4274
|
function resolveKoraVersion() {
|
|
4063
4275
|
try {
|
|
4064
|
-
let dir = (0,
|
|
4276
|
+
let dir = (0, import_node_path10.dirname)((0, import_node_url4.fileURLToPath)(import_meta2.url));
|
|
4065
4277
|
for (let i = 0; i < 5; i++) {
|
|
4066
|
-
const pkgPath = (0,
|
|
4278
|
+
const pkgPath = (0, import_node_path10.resolve)(dir, "package.json");
|
|
4067
4279
|
if ((0, import_node_fs2.existsSync)(pkgPath)) {
|
|
4068
4280
|
const pkg = JSON.parse((0, import_node_fs2.readFileSync)(pkgPath, "utf-8"));
|
|
4069
4281
|
if (pkg.name === "@korajs/cli") {
|
|
@@ -4072,7 +4284,7 @@ function resolveKoraVersion() {
|
|
|
4072
4284
|
return `^${parts[0]}.${parts[1]}.0`;
|
|
4073
4285
|
}
|
|
4074
4286
|
}
|
|
4075
|
-
dir = (0,
|
|
4287
|
+
dir = (0, import_node_path10.dirname)(dir);
|
|
4076
4288
|
}
|
|
4077
4289
|
return "latest";
|
|
4078
4290
|
} catch {
|
|
@@ -4082,8 +4294,8 @@ function resolveKoraVersion() {
|
|
|
4082
4294
|
|
|
4083
4295
|
// src/commands/deploy/deploy-command.ts
|
|
4084
4296
|
var import_node_fs4 = require("fs");
|
|
4085
|
-
var
|
|
4086
|
-
var
|
|
4297
|
+
var import_node_path21 = require("path");
|
|
4298
|
+
var import_citty5 = require("citty");
|
|
4087
4299
|
init_fs_helpers();
|
|
4088
4300
|
|
|
4089
4301
|
// src/commands/deploy/adapters/adapter.ts
|
|
@@ -4102,13 +4314,13 @@ function isDeployPlatform(value) {
|
|
|
4102
4314
|
|
|
4103
4315
|
// src/commands/deploy/adapters/aws-ecs-adapter.ts
|
|
4104
4316
|
var import_node_child_process6 = require("child_process");
|
|
4105
|
-
var
|
|
4317
|
+
var import_node_path13 = require("path");
|
|
4106
4318
|
|
|
4107
4319
|
// src/commands/deploy/builder/client-builder.ts
|
|
4108
4320
|
var import_node_child_process5 = require("child_process");
|
|
4109
4321
|
var import_node_fs3 = require("fs");
|
|
4110
|
-
var
|
|
4111
|
-
var
|
|
4322
|
+
var import_promises8 = require("fs/promises");
|
|
4323
|
+
var import_node_path11 = require("path");
|
|
4112
4324
|
init_fs_helpers();
|
|
4113
4325
|
async function buildClient(options) {
|
|
4114
4326
|
const viteEntryPoint = await resolveProjectBinaryEntryPoint(options.projectRoot, "vite", "vite");
|
|
@@ -4130,15 +4342,15 @@ async function buildClient(options) {
|
|
|
4130
4342
|
return { outDir: options.outDir };
|
|
4131
4343
|
}
|
|
4132
4344
|
async function patchSqliteWasmAssets(projectRoot, outDir) {
|
|
4133
|
-
const assetsDir = (0,
|
|
4345
|
+
const assetsDir = (0, import_node_path11.join)(outDir, "assets");
|
|
4134
4346
|
if (!(0, import_node_fs3.existsSync)(assetsDir)) return;
|
|
4135
|
-
const files = await (0,
|
|
4347
|
+
const files = await (0, import_promises8.readdir)(assetsDir);
|
|
4136
4348
|
const hashedWasm = files.find((f) => /^sqlite3-.+\.wasm$/.test(f));
|
|
4137
4349
|
if (hashedWasm && !files.includes("sqlite3.wasm")) {
|
|
4138
|
-
await (0,
|
|
4350
|
+
await (0, import_promises8.copyFile)((0, import_node_path11.join)(assetsDir, hashedWasm), (0, import_node_path11.join)(assetsDir, "sqlite3.wasm"));
|
|
4139
4351
|
}
|
|
4140
4352
|
if (!files.includes("sqlite3-opfs-async-proxy.js")) {
|
|
4141
|
-
const proxyFile = (0,
|
|
4353
|
+
const proxyFile = (0, import_node_path11.resolve)(
|
|
4142
4354
|
projectRoot,
|
|
4143
4355
|
"node_modules",
|
|
4144
4356
|
"@sqlite.org",
|
|
@@ -4148,7 +4360,7 @@ async function patchSqliteWasmAssets(projectRoot, outDir) {
|
|
|
4148
4360
|
"sqlite3-opfs-async-proxy.js"
|
|
4149
4361
|
);
|
|
4150
4362
|
if ((0, import_node_fs3.existsSync)(proxyFile)) {
|
|
4151
|
-
await (0,
|
|
4363
|
+
await (0, import_promises8.copyFile)(proxyFile, (0, import_node_path11.join)(assetsDir, "sqlite3-opfs-async-proxy.js"));
|
|
4152
4364
|
}
|
|
4153
4365
|
}
|
|
4154
4366
|
}
|
|
@@ -4173,9 +4385,9 @@ async function runProcess(command, args, cwd) {
|
|
|
4173
4385
|
}
|
|
4174
4386
|
|
|
4175
4387
|
// src/commands/deploy/builder/server-bundler.ts
|
|
4176
|
-
var import_promises8 = require("fs/promises");
|
|
4177
4388
|
var import_promises9 = require("fs/promises");
|
|
4178
|
-
var
|
|
4389
|
+
var import_promises10 = require("fs/promises");
|
|
4390
|
+
var import_node_path12 = require("path");
|
|
4179
4391
|
var import_esbuild = require("esbuild");
|
|
4180
4392
|
var DEFAULT_ENTRY_CANDIDATES = [
|
|
4181
4393
|
"server.ts",
|
|
@@ -4191,8 +4403,8 @@ async function bundleServer(options) {
|
|
|
4191
4403
|
`Could not find a server entry file in ${options.projectRoot}. Looked for: ${candidates.join(", ")}`
|
|
4192
4404
|
);
|
|
4193
4405
|
}
|
|
4194
|
-
await (0,
|
|
4195
|
-
const outputFilePath = (0,
|
|
4406
|
+
await (0, import_promises9.mkdir)(options.deployDirectory, { recursive: true });
|
|
4407
|
+
const outputFilePath = (0, import_node_path12.join)(options.deployDirectory, "server-bundled.js");
|
|
4196
4408
|
await (0, import_esbuild.build)({
|
|
4197
4409
|
entryPoints: [entryFilePath],
|
|
4198
4410
|
outfile: outputFilePath,
|
|
@@ -4214,9 +4426,9 @@ async function bundleServer(options) {
|
|
|
4214
4426
|
}
|
|
4215
4427
|
async function resolveServerEntry(projectRoot, candidates) {
|
|
4216
4428
|
for (const candidate of candidates) {
|
|
4217
|
-
const fullPath = (0,
|
|
4429
|
+
const fullPath = (0, import_node_path12.join)(projectRoot, candidate);
|
|
4218
4430
|
try {
|
|
4219
|
-
await (0,
|
|
4431
|
+
await (0, import_promises10.access)(fullPath);
|
|
4220
4432
|
return fullPath;
|
|
4221
4433
|
} catch {
|
|
4222
4434
|
}
|
|
@@ -4318,19 +4530,19 @@ var AwsEcsAdapter = class {
|
|
|
4318
4530
|
appName: config.appName,
|
|
4319
4531
|
region: config.region
|
|
4320
4532
|
};
|
|
4321
|
-
const deployDirectory = (0,
|
|
4533
|
+
const deployDirectory = (0, import_node_path13.join)(config.projectRoot, ".kora", "deploy");
|
|
4322
4534
|
await bundleServer({
|
|
4323
4535
|
projectRoot: config.projectRoot,
|
|
4324
4536
|
deployDirectory
|
|
4325
4537
|
});
|
|
4326
4538
|
const client = config.deployTarget === "sync-server" ? null : await buildClient({
|
|
4327
4539
|
projectRoot: config.projectRoot,
|
|
4328
|
-
outDir: (0,
|
|
4540
|
+
outDir: (0, import_node_path13.join)(deployDirectory, "dist"),
|
|
4329
4541
|
mode: "production"
|
|
4330
4542
|
});
|
|
4331
4543
|
return {
|
|
4332
4544
|
clientDirectory: client?.outDir ?? null,
|
|
4333
|
-
serverBundlePath: (0,
|
|
4545
|
+
serverBundlePath: (0, import_node_path13.join)(deployDirectory, "server-bundled.js"),
|
|
4334
4546
|
deployDirectory
|
|
4335
4547
|
};
|
|
4336
4548
|
}
|
|
@@ -4596,7 +4808,7 @@ function inferLogLevel(line) {
|
|
|
4596
4808
|
|
|
4597
4809
|
// src/commands/deploy/adapters/aws-lightsail-adapter.ts
|
|
4598
4810
|
var import_node_child_process7 = require("child_process");
|
|
4599
|
-
var
|
|
4811
|
+
var import_node_path14 = require("path");
|
|
4600
4812
|
var AwsLightsailAdapter = class {
|
|
4601
4813
|
name = "aws-lightsail";
|
|
4602
4814
|
logger = createLogger();
|
|
@@ -4669,19 +4881,19 @@ var AwsLightsailAdapter = class {
|
|
|
4669
4881
|
appName: config.appName,
|
|
4670
4882
|
region: config.region
|
|
4671
4883
|
};
|
|
4672
|
-
const deployDirectory = (0,
|
|
4884
|
+
const deployDirectory = (0, import_node_path14.join)(config.projectRoot, ".kora", "deploy");
|
|
4673
4885
|
await bundleServer({
|
|
4674
4886
|
projectRoot: config.projectRoot,
|
|
4675
4887
|
deployDirectory
|
|
4676
4888
|
});
|
|
4677
4889
|
const client = config.deployTarget === "sync-server" ? null : await buildClient({
|
|
4678
4890
|
projectRoot: config.projectRoot,
|
|
4679
|
-
outDir: (0,
|
|
4891
|
+
outDir: (0, import_node_path14.join)(deployDirectory, "dist"),
|
|
4680
4892
|
mode: "production"
|
|
4681
4893
|
});
|
|
4682
4894
|
return {
|
|
4683
4895
|
clientDirectory: client?.outDir ?? null,
|
|
4684
|
-
serverBundlePath: (0,
|
|
4896
|
+
serverBundlePath: (0, import_node_path14.join)(deployDirectory, "server-bundled.js"),
|
|
4685
4897
|
deployDirectory
|
|
4686
4898
|
};
|
|
4687
4899
|
}
|
|
@@ -4981,11 +5193,11 @@ function inferLogLevel2(line) {
|
|
|
4981
5193
|
|
|
4982
5194
|
// src/commands/deploy/adapters/fly-adapter.ts
|
|
4983
5195
|
var import_node_child_process8 = require("child_process");
|
|
4984
|
-
var
|
|
5196
|
+
var import_node_path16 = require("path");
|
|
4985
5197
|
|
|
4986
5198
|
// src/commands/deploy/artifacts/fly-toml-generator.ts
|
|
4987
|
-
var
|
|
4988
|
-
var
|
|
5199
|
+
var import_promises11 = require("fs/promises");
|
|
5200
|
+
var import_node_path15 = require("path");
|
|
4989
5201
|
var GENERATED_HEADER = "# Generated by kora deploy \u2014 do not edit manually";
|
|
4990
5202
|
function generateFlyToml(options) {
|
|
4991
5203
|
const internalPort = options.internalPort ?? 3e3;
|
|
@@ -5015,9 +5227,9 @@ function generateFlyToml(options) {
|
|
|
5015
5227
|
].join("\n");
|
|
5016
5228
|
}
|
|
5017
5229
|
async function writeFlyTomlArtifact(deployDirectory, options) {
|
|
5018
|
-
await (0,
|
|
5019
|
-
const filePath = (0,
|
|
5020
|
-
await (0,
|
|
5230
|
+
await (0, import_promises11.mkdir)(deployDirectory, { recursive: true });
|
|
5231
|
+
const filePath = (0, import_node_path15.join)(deployDirectory, "fly.toml");
|
|
5232
|
+
await (0, import_promises11.writeFile)(filePath, generateFlyToml(options), "utf-8");
|
|
5021
5233
|
return filePath;
|
|
5022
5234
|
}
|
|
5023
5235
|
|
|
@@ -5111,7 +5323,7 @@ var FlyAdapter = class {
|
|
|
5111
5323
|
appName: config.appName,
|
|
5112
5324
|
region: config.region
|
|
5113
5325
|
};
|
|
5114
|
-
const deployDirectory = (0,
|
|
5326
|
+
const deployDirectory = (0, import_node_path16.join)(config.projectRoot, ".kora", "deploy");
|
|
5115
5327
|
await writeFlyTomlArtifact(deployDirectory, {
|
|
5116
5328
|
appName: config.appName,
|
|
5117
5329
|
region: config.region ?? "iad"
|
|
@@ -5122,12 +5334,12 @@ var FlyAdapter = class {
|
|
|
5122
5334
|
});
|
|
5123
5335
|
const client = config.deployTarget === "sync-server" ? null : await buildClient({
|
|
5124
5336
|
projectRoot: config.projectRoot,
|
|
5125
|
-
outDir: (0,
|
|
5337
|
+
outDir: (0, import_node_path16.join)(deployDirectory, "dist"),
|
|
5126
5338
|
mode: "production"
|
|
5127
5339
|
});
|
|
5128
5340
|
return {
|
|
5129
5341
|
clientDirectory: client?.outDir ?? null,
|
|
5130
|
-
serverBundlePath: (0,
|
|
5342
|
+
serverBundlePath: (0, import_node_path16.join)(deployDirectory, "server-bundled.js"),
|
|
5131
5343
|
deployDirectory
|
|
5132
5344
|
};
|
|
5133
5345
|
}
|
|
@@ -5349,11 +5561,11 @@ ${stdout}`.toLowerCase();
|
|
|
5349
5561
|
|
|
5350
5562
|
// src/commands/deploy/adapters/railway-adapter.ts
|
|
5351
5563
|
var import_node_child_process9 = require("child_process");
|
|
5352
|
-
var
|
|
5564
|
+
var import_node_path18 = require("path");
|
|
5353
5565
|
|
|
5354
5566
|
// src/commands/deploy/artifacts/railway-json-generator.ts
|
|
5355
|
-
var
|
|
5356
|
-
var
|
|
5567
|
+
var import_promises12 = require("fs/promises");
|
|
5568
|
+
var import_node_path17 = require("path");
|
|
5357
5569
|
var GENERATED_HEADER2 = "Generated by kora deploy - do not edit manually.";
|
|
5358
5570
|
function generateRailwayJson(options) {
|
|
5359
5571
|
const file = {
|
|
@@ -5378,9 +5590,9 @@ function generateRailwayJson(options) {
|
|
|
5378
5590
|
`;
|
|
5379
5591
|
}
|
|
5380
5592
|
async function writeRailwayJsonArtifact(deployDirectory, options) {
|
|
5381
|
-
await (0,
|
|
5382
|
-
const filePath = (0,
|
|
5383
|
-
await (0,
|
|
5593
|
+
await (0, import_promises12.mkdir)(deployDirectory, { recursive: true });
|
|
5594
|
+
const filePath = (0, import_node_path17.join)(deployDirectory, "railway.json");
|
|
5595
|
+
await (0, import_promises12.writeFile)(filePath, generateRailwayJson(options), "utf-8");
|
|
5384
5596
|
return filePath;
|
|
5385
5597
|
}
|
|
5386
5598
|
|
|
@@ -5469,7 +5681,7 @@ var RailwayAdapter = class {
|
|
|
5469
5681
|
appName: config.appName,
|
|
5470
5682
|
region: config.region
|
|
5471
5683
|
};
|
|
5472
|
-
const deployDirectory = (0,
|
|
5684
|
+
const deployDirectory = (0, import_node_path18.join)(config.projectRoot, ".kora", "deploy");
|
|
5473
5685
|
await writeRailwayJsonArtifact(deployDirectory, {
|
|
5474
5686
|
appName: config.appName,
|
|
5475
5687
|
environment: config.environment
|
|
@@ -5480,12 +5692,12 @@ var RailwayAdapter = class {
|
|
|
5480
5692
|
});
|
|
5481
5693
|
const client = config.deployTarget === "sync-server" ? null : await buildClient({
|
|
5482
5694
|
projectRoot: config.projectRoot,
|
|
5483
|
-
outDir: (0,
|
|
5695
|
+
outDir: (0, import_node_path18.join)(deployDirectory, "dist"),
|
|
5484
5696
|
mode: "production"
|
|
5485
5697
|
});
|
|
5486
5698
|
return {
|
|
5487
5699
|
clientDirectory: client?.outDir ?? null,
|
|
5488
|
-
serverBundlePath: (0,
|
|
5700
|
+
serverBundlePath: (0, import_node_path18.join)(deployDirectory, "server-bundled.js"),
|
|
5489
5701
|
deployDirectory
|
|
5490
5702
|
};
|
|
5491
5703
|
}
|
|
@@ -5770,8 +5982,8 @@ function createDeployAdapter(platform) {
|
|
|
5770
5982
|
}
|
|
5771
5983
|
|
|
5772
5984
|
// src/commands/deploy/artifacts/dockerfile-generator.ts
|
|
5773
|
-
var
|
|
5774
|
-
var
|
|
5985
|
+
var import_promises13 = require("fs/promises");
|
|
5986
|
+
var import_node_path19 = require("path");
|
|
5775
5987
|
var GENERATED_HEADER3 = "# Generated by kora deploy \u2014 do not edit manually";
|
|
5776
5988
|
function generateDockerfile(options = {}) {
|
|
5777
5989
|
const nodeVersion = options.nodeVersion ?? "20-alpine";
|
|
@@ -5837,37 +6049,37 @@ function generateDockerIgnore() {
|
|
|
5837
6049
|
].join("\n");
|
|
5838
6050
|
}
|
|
5839
6051
|
async function writeDockerfileArtifact(deployDirectory, options = {}) {
|
|
5840
|
-
await (0,
|
|
5841
|
-
const dockerfilePath = (0,
|
|
5842
|
-
await (0,
|
|
6052
|
+
await (0, import_promises13.mkdir)(deployDirectory, { recursive: true });
|
|
6053
|
+
const dockerfilePath = (0, import_node_path19.join)(deployDirectory, "Dockerfile");
|
|
6054
|
+
await (0, import_promises13.writeFile)(dockerfilePath, generateDockerfile(options), "utf-8");
|
|
5843
6055
|
if (options.nativeDependencies && Object.keys(options.nativeDependencies).length > 0) {
|
|
5844
|
-
const pkgJsonPath = (0,
|
|
5845
|
-
await (0,
|
|
6056
|
+
const pkgJsonPath = (0, import_node_path19.join)(deployDirectory, "package.json");
|
|
6057
|
+
await (0, import_promises13.writeFile)(pkgJsonPath, generateDeployPackageJson(options.nativeDependencies), "utf-8");
|
|
5846
6058
|
}
|
|
5847
6059
|
return dockerfilePath;
|
|
5848
6060
|
}
|
|
5849
6061
|
async function writeDockerIgnoreArtifact(deployDirectory) {
|
|
5850
|
-
await (0,
|
|
5851
|
-
const dockerIgnorePath = (0,
|
|
5852
|
-
await (0,
|
|
6062
|
+
await (0, import_promises13.mkdir)(deployDirectory, { recursive: true });
|
|
6063
|
+
const dockerIgnorePath = (0, import_node_path19.join)(deployDirectory, ".dockerignore");
|
|
6064
|
+
await (0, import_promises13.writeFile)(dockerIgnorePath, generateDockerIgnore(), "utf-8");
|
|
5853
6065
|
return dockerIgnorePath;
|
|
5854
6066
|
}
|
|
5855
6067
|
|
|
5856
6068
|
// src/commands/deploy/state/deploy-state.ts
|
|
5857
|
-
var
|
|
5858
|
-
var
|
|
5859
|
-
var KORA_DEPLOY_DIRECTORY = (0,
|
|
6069
|
+
var import_promises14 = require("fs/promises");
|
|
6070
|
+
var import_node_path20 = require("path");
|
|
6071
|
+
var KORA_DEPLOY_DIRECTORY = (0, import_node_path20.join)(".kora", "deploy");
|
|
5860
6072
|
var DEPLOY_STATE_FILENAME = "deploy.json";
|
|
5861
6073
|
function resolveDeployDirectory(projectRoot) {
|
|
5862
|
-
return (0,
|
|
6074
|
+
return (0, import_node_path20.join)(projectRoot, KORA_DEPLOY_DIRECTORY);
|
|
5863
6075
|
}
|
|
5864
6076
|
function resolveDeployStatePath(projectRoot) {
|
|
5865
|
-
return (0,
|
|
6077
|
+
return (0, import_node_path20.join)(resolveDeployDirectory(projectRoot), DEPLOY_STATE_FILENAME);
|
|
5866
6078
|
}
|
|
5867
6079
|
async function readDeployState(projectRoot) {
|
|
5868
6080
|
const statePath = resolveDeployStatePath(projectRoot);
|
|
5869
6081
|
try {
|
|
5870
|
-
const source = await (0,
|
|
6082
|
+
const source = await (0, import_promises14.readFile)(statePath, "utf-8");
|
|
5871
6083
|
const parsed = JSON.parse(source);
|
|
5872
6084
|
return parseDeployState(parsed);
|
|
5873
6085
|
} catch (error) {
|
|
@@ -5914,13 +6126,13 @@ async function updateDeployState(projectRoot, patch, now = /* @__PURE__ */ new D
|
|
|
5914
6126
|
return nextState;
|
|
5915
6127
|
}
|
|
5916
6128
|
async function resetDeployState(projectRoot) {
|
|
5917
|
-
await (0,
|
|
6129
|
+
await (0, import_promises14.rm)(resolveDeployDirectory(projectRoot), { recursive: true, force: true });
|
|
5918
6130
|
}
|
|
5919
6131
|
async function persistDeployState(projectRoot, state) {
|
|
5920
6132
|
const deployDir = resolveDeployDirectory(projectRoot);
|
|
5921
6133
|
const statePath = resolveDeployStatePath(projectRoot);
|
|
5922
|
-
await (0,
|
|
5923
|
-
await (0,
|
|
6134
|
+
await (0, import_promises14.mkdir)(deployDir, { recursive: true });
|
|
6135
|
+
await (0, import_promises14.writeFile)(statePath, `${JSON.stringify(state, null, 2)}
|
|
5924
6136
|
`, "utf-8");
|
|
5925
6137
|
}
|
|
5926
6138
|
function parseDeployState(value) {
|
|
@@ -5970,7 +6182,7 @@ function readOptionalString(value, field) {
|
|
|
5970
6182
|
}
|
|
5971
6183
|
|
|
5972
6184
|
// src/commands/deploy/deploy-command.ts
|
|
5973
|
-
var deployCommand = (0,
|
|
6185
|
+
var deployCommand = (0, import_citty5.defineCommand)({
|
|
5974
6186
|
meta: {
|
|
5975
6187
|
name: "deploy",
|
|
5976
6188
|
description: "Deploy a Kora project to your selected platform"
|
|
@@ -6005,7 +6217,7 @@ var deployCommand = (0, import_citty4.defineCommand)({
|
|
|
6005
6217
|
}
|
|
6006
6218
|
},
|
|
6007
6219
|
subCommands: {
|
|
6008
|
-
status: (0,
|
|
6220
|
+
status: (0, import_citty5.defineCommand)({
|
|
6009
6221
|
meta: {
|
|
6010
6222
|
name: "status",
|
|
6011
6223
|
description: "Show current deployment status"
|
|
@@ -6036,7 +6248,7 @@ var deployCommand = (0, import_citty4.defineCommand)({
|
|
|
6036
6248
|
logger.step(`Sync URL: ${state.syncUrl ?? "n/a"}`);
|
|
6037
6249
|
}
|
|
6038
6250
|
}),
|
|
6039
|
-
rollback: (0,
|
|
6251
|
+
rollback: (0, import_citty5.defineCommand)({
|
|
6040
6252
|
meta: {
|
|
6041
6253
|
name: "rollback",
|
|
6042
6254
|
description: "Rollback the current deployment"
|
|
@@ -6067,7 +6279,7 @@ var deployCommand = (0, import_citty4.defineCommand)({
|
|
|
6067
6279
|
logger.success(`Rolled back ${state.platform} deployment to ${deploymentId}.`);
|
|
6068
6280
|
}
|
|
6069
6281
|
}),
|
|
6070
|
-
logs: (0,
|
|
6282
|
+
logs: (0, import_citty5.defineCommand)({
|
|
6071
6283
|
meta: {
|
|
6072
6284
|
name: "logs",
|
|
6073
6285
|
description: "Read deployment logs"
|
|
@@ -6254,7 +6466,7 @@ function resolveAppName(argValue, storedValue, projectRoot, confirm) {
|
|
|
6254
6466
|
"Missing app name in --confirm mode. Provide --app or run an interactive deploy first."
|
|
6255
6467
|
);
|
|
6256
6468
|
}
|
|
6257
|
-
return sanitizeAppName((0,
|
|
6469
|
+
return sanitizeAppName((0, import_node_path21.basename)(projectRoot));
|
|
6258
6470
|
}
|
|
6259
6471
|
function resolveRegion(argValue, storedValue, confirm) {
|
|
6260
6472
|
if (typeof argValue === "string" && argValue.length > 0) return argValue;
|
|
@@ -6289,17 +6501,17 @@ function configureAdapterContext(adapter, context) {
|
|
|
6289
6501
|
}
|
|
6290
6502
|
}
|
|
6291
6503
|
function detectDeployTarget(projectRoot) {
|
|
6292
|
-
return (0, import_node_fs4.existsSync)((0,
|
|
6504
|
+
return (0, import_node_fs4.existsSync)((0, import_node_path21.join)(projectRoot, "src-tauri")) ? "sync-server" : "full-stack";
|
|
6293
6505
|
}
|
|
6294
6506
|
function hasContextSetter(adapter) {
|
|
6295
6507
|
return typeof adapter.setContext === "function";
|
|
6296
6508
|
}
|
|
6297
6509
|
|
|
6298
6510
|
// src/commands/dev/dev-command.ts
|
|
6299
|
-
var
|
|
6300
|
-
var import_node_path22 = require("path");
|
|
6511
|
+
var import_promises15 = require("fs/promises");
|
|
6301
6512
|
var import_node_path23 = require("path");
|
|
6302
|
-
var
|
|
6513
|
+
var import_node_path24 = require("path");
|
|
6514
|
+
var import_citty6 = require("citty");
|
|
6303
6515
|
init_fs_helpers();
|
|
6304
6516
|
|
|
6305
6517
|
// src/commands/dev/process-manager.ts
|
|
@@ -6392,7 +6604,7 @@ function delay(ms) {
|
|
|
6392
6604
|
// src/commands/dev/schema-watcher.ts
|
|
6393
6605
|
var import_node_child_process11 = require("child_process");
|
|
6394
6606
|
var import_node_fs5 = require("fs");
|
|
6395
|
-
var
|
|
6607
|
+
var import_node_path22 = require("path");
|
|
6396
6608
|
init_fs_helpers();
|
|
6397
6609
|
var SchemaWatcher = class {
|
|
6398
6610
|
constructor(config) {
|
|
@@ -6421,7 +6633,7 @@ var SchemaWatcher = class {
|
|
|
6421
6633
|
this.watcher = null;
|
|
6422
6634
|
}
|
|
6423
6635
|
async regenerate() {
|
|
6424
|
-
const koraBinJs = (0,
|
|
6636
|
+
const koraBinJs = (0, import_node_path22.join)(
|
|
6425
6637
|
this.config.projectRoot,
|
|
6426
6638
|
"node_modules",
|
|
6427
6639
|
"@korajs",
|
|
@@ -6487,7 +6699,7 @@ function toError(error) {
|
|
|
6487
6699
|
}
|
|
6488
6700
|
|
|
6489
6701
|
// src/commands/dev/dev-command.ts
|
|
6490
|
-
var devCommand = (0,
|
|
6702
|
+
var devCommand = (0, import_citty6.defineCommand)({
|
|
6491
6703
|
meta: {
|
|
6492
6704
|
name: "dev",
|
|
6493
6705
|
description: "Start the Kora development environment"
|
|
@@ -6527,7 +6739,7 @@ var devCommand = (0, import_citty5.defineCommand)({
|
|
|
6527
6739
|
const watchDebounceMs = typeof config?.dev?.watch === "object" && typeof config.dev.watch.debounceMs === "number" ? config.dev.watch.debounceMs : 300;
|
|
6528
6740
|
const viteEntryPoint = await resolveProjectBinaryEntryPoint(projectRoot, "vite", "vite");
|
|
6529
6741
|
if (!viteEntryPoint) {
|
|
6530
|
-
throw new DevServerError("vite", (0,
|
|
6742
|
+
throw new DevServerError("vite", (0, import_node_path23.join)(projectRoot, "node_modules", ".bin", "vite"));
|
|
6531
6743
|
}
|
|
6532
6744
|
const syncServerFile = await findSyncServerFile(projectRoot);
|
|
6533
6745
|
let managedSyncStore = normalizeManagedSyncStore(config, projectRoot);
|
|
@@ -6542,8 +6754,8 @@ var devCommand = (0, import_citty5.defineCommand)({
|
|
|
6542
6754
|
}
|
|
6543
6755
|
}
|
|
6544
6756
|
if (shouldStartSync && syncServerFile === null && managedSyncStore) {
|
|
6545
|
-
const hasServerPackage = await
|
|
6546
|
-
(0,
|
|
6757
|
+
const hasServerPackage = await fileExists3(
|
|
6758
|
+
(0, import_node_path23.join)(projectRoot, "node_modules", "@korajs", "server", "package.json")
|
|
6547
6759
|
);
|
|
6548
6760
|
if (!hasServerPackage) {
|
|
6549
6761
|
logger.warn(
|
|
@@ -6560,8 +6772,8 @@ var devCommand = (0, import_citty5.defineCommand)({
|
|
|
6560
6772
|
}
|
|
6561
6773
|
let configuredSchemaPath = null;
|
|
6562
6774
|
if (typeof config?.schema === "string") {
|
|
6563
|
-
const candidate = (0,
|
|
6564
|
-
if (await
|
|
6775
|
+
const candidate = (0, import_node_path24.resolve)(projectRoot, config.schema);
|
|
6776
|
+
if (await fileExists3(candidate)) {
|
|
6565
6777
|
configuredSchemaPath = candidate;
|
|
6566
6778
|
} else {
|
|
6567
6779
|
logger.warn(
|
|
@@ -6678,19 +6890,19 @@ var devCommand = (0, import_citty5.defineCommand)({
|
|
|
6678
6890
|
}
|
|
6679
6891
|
});
|
|
6680
6892
|
async function findSyncServerFile(projectRoot) {
|
|
6681
|
-
const candidates = [(0,
|
|
6893
|
+
const candidates = [(0, import_node_path23.join)(projectRoot, "server.ts"), (0, import_node_path23.join)(projectRoot, "server.js")];
|
|
6682
6894
|
for (const candidate of candidates) {
|
|
6683
6895
|
try {
|
|
6684
|
-
await (0,
|
|
6896
|
+
await (0, import_promises15.access)(candidate);
|
|
6685
6897
|
return candidate;
|
|
6686
6898
|
} catch {
|
|
6687
6899
|
}
|
|
6688
6900
|
}
|
|
6689
6901
|
return null;
|
|
6690
6902
|
}
|
|
6691
|
-
async function
|
|
6903
|
+
async function fileExists3(path) {
|
|
6692
6904
|
try {
|
|
6693
|
-
await (0,
|
|
6905
|
+
await (0, import_promises15.access)(path);
|
|
6694
6906
|
return true;
|
|
6695
6907
|
} catch {
|
|
6696
6908
|
return false;
|
|
@@ -6702,7 +6914,7 @@ function normalizeManagedSyncStore(config, projectRoot) {
|
|
|
6702
6914
|
const store = sync.store;
|
|
6703
6915
|
if (store === void 0) return { type: "memory" };
|
|
6704
6916
|
if (store === "memory") return { type: "memory" };
|
|
6705
|
-
if (store === "sqlite") return { type: "sqlite", filename: (0,
|
|
6917
|
+
if (store === "sqlite") return { type: "sqlite", filename: (0, import_node_path23.join)(projectRoot, "kora-sync.db") };
|
|
6706
6918
|
if (store === "postgres") {
|
|
6707
6919
|
const connectionString = process.env.DATABASE_URL;
|
|
6708
6920
|
if (!connectionString) return null;
|
|
@@ -6711,7 +6923,7 @@ function normalizeManagedSyncStore(config, projectRoot) {
|
|
|
6711
6923
|
if (typeof store === "object" && store !== null) {
|
|
6712
6924
|
if (store.type === "memory") return { type: "memory" };
|
|
6713
6925
|
if (store.type === "sqlite") {
|
|
6714
|
-
const filename = typeof store.filename === "string" && store.filename.length > 0 ? (0,
|
|
6926
|
+
const filename = typeof store.filename === "string" && store.filename.length > 0 ? (0, import_node_path24.resolve)(projectRoot, store.filename) : (0, import_node_path23.join)(projectRoot, "kora-sync.db");
|
|
6715
6927
|
return { type: "sqlite", filename };
|
|
6716
6928
|
}
|
|
6717
6929
|
if (store.type === "postgres" && typeof store.connectionString === "string") {
|
|
@@ -6775,12 +6987,12 @@ await new Promise(() => {});
|
|
|
6775
6987
|
`;
|
|
6776
6988
|
|
|
6777
6989
|
// src/commands/doctor/doctor-command.ts
|
|
6778
|
-
var
|
|
6990
|
+
var import_citty7 = require("citty");
|
|
6779
6991
|
init_fs_helpers();
|
|
6780
6992
|
|
|
6781
6993
|
// src/commands/doctor/doctor-checks.ts
|
|
6782
|
-
var
|
|
6783
|
-
var
|
|
6994
|
+
var import_promises16 = require("fs/promises");
|
|
6995
|
+
var import_node_path25 = require("path");
|
|
6784
6996
|
init_fs_helpers();
|
|
6785
6997
|
init_schema_loader();
|
|
6786
6998
|
var STATUS_ENDPOINT = "/__kora/status";
|
|
@@ -6860,9 +7072,9 @@ async function runDoctorChecks(options) {
|
|
|
6860
7072
|
}
|
|
6861
7073
|
async function resolveSchemaPath(projectRoot, configSchema) {
|
|
6862
7074
|
if (typeof configSchema === "string") {
|
|
6863
|
-
const resolved = (0,
|
|
7075
|
+
const resolved = (0, import_node_path25.resolve)(projectRoot, configSchema);
|
|
6864
7076
|
try {
|
|
6865
|
-
await (0,
|
|
7077
|
+
await (0, import_promises16.access)(resolved);
|
|
6866
7078
|
return resolved;
|
|
6867
7079
|
} catch {
|
|
6868
7080
|
}
|
|
@@ -6871,12 +7083,12 @@ async function resolveSchemaPath(projectRoot, configSchema) {
|
|
|
6871
7083
|
}
|
|
6872
7084
|
async function checkWorkerFile(projectRoot) {
|
|
6873
7085
|
const candidates = [
|
|
6874
|
-
(0,
|
|
6875
|
-
(0,
|
|
7086
|
+
(0, import_node_path25.join)(projectRoot, "src", "kora-worker.ts"),
|
|
7087
|
+
(0, import_node_path25.join)(projectRoot, "src", "kora-worker.js")
|
|
6876
7088
|
];
|
|
6877
7089
|
for (const path of candidates) {
|
|
6878
7090
|
try {
|
|
6879
|
-
await (0,
|
|
7091
|
+
await (0, import_promises16.access)(path);
|
|
6880
7092
|
return {
|
|
6881
7093
|
id: "worker",
|
|
6882
7094
|
title: "SQLite WASM worker",
|
|
@@ -6896,7 +7108,7 @@ async function checkWorkerFile(projectRoot) {
|
|
|
6896
7108
|
}
|
|
6897
7109
|
async function checkDependencies(projectRoot) {
|
|
6898
7110
|
try {
|
|
6899
|
-
const raw = await (0,
|
|
7111
|
+
const raw = await (0, import_promises16.readFile)((0, import_node_path25.join)(projectRoot, "package.json"), "utf-8");
|
|
6900
7112
|
const pkg = JSON.parse(raw);
|
|
6901
7113
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
6902
7114
|
const hasKora = Boolean(deps.korajs || deps.kora);
|
|
@@ -6945,9 +7157,9 @@ async function resolveSyncHttpUrl(projectRoot, config) {
|
|
|
6945
7157
|
}
|
|
6946
7158
|
async function readEnvSyncUrl(projectRoot) {
|
|
6947
7159
|
for (const file of [".env", ".env.local"]) {
|
|
6948
|
-
const path = (0,
|
|
7160
|
+
const path = (0, import_node_path25.join)(projectRoot, file);
|
|
6949
7161
|
try {
|
|
6950
|
-
const content = await (0,
|
|
7162
|
+
const content = await (0, import_promises16.readFile)(path, "utf-8");
|
|
6951
7163
|
for (const line of content.split("\n")) {
|
|
6952
7164
|
const trimmed = line.trim();
|
|
6953
7165
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -7038,7 +7250,7 @@ function doctorHasFailures(results) {
|
|
|
7038
7250
|
}
|
|
7039
7251
|
|
|
7040
7252
|
// src/commands/doctor/doctor-command.ts
|
|
7041
|
-
var doctorCommand = (0,
|
|
7253
|
+
var doctorCommand = (0, import_citty7.defineCommand)({
|
|
7042
7254
|
meta: {
|
|
7043
7255
|
name: "doctor",
|
|
7044
7256
|
description: "Check Kora project setup (schema, worker, sync server, versions)"
|
|
@@ -7093,9 +7305,9 @@ var doctorCommand = (0, import_citty6.defineCommand)({
|
|
|
7093
7305
|
});
|
|
7094
7306
|
|
|
7095
7307
|
// src/commands/generate/generate-command.ts
|
|
7096
|
-
var
|
|
7097
|
-
var
|
|
7098
|
-
var
|
|
7308
|
+
var import_promises17 = require("fs/promises");
|
|
7309
|
+
var import_node_path26 = require("path");
|
|
7310
|
+
var import_citty8 = require("citty");
|
|
7099
7311
|
init_fs_helpers();
|
|
7100
7312
|
init_schema_loader();
|
|
7101
7313
|
|
|
@@ -7250,13 +7462,13 @@ function toPascalCase2(name) {
|
|
|
7250
7462
|
}
|
|
7251
7463
|
|
|
7252
7464
|
// src/commands/generate/generate-command.ts
|
|
7253
|
-
var generateCommand = (0,
|
|
7465
|
+
var generateCommand = (0, import_citty8.defineCommand)({
|
|
7254
7466
|
meta: {
|
|
7255
7467
|
name: "generate",
|
|
7256
7468
|
description: "Generate code from your Kora schema"
|
|
7257
7469
|
},
|
|
7258
7470
|
subCommands: {
|
|
7259
|
-
types: (0,
|
|
7471
|
+
types: (0, import_citty8.defineCommand)({
|
|
7260
7472
|
meta: {
|
|
7261
7473
|
name: "types",
|
|
7262
7474
|
description: "Generate TypeScript types from your schema"
|
|
@@ -7280,7 +7492,7 @@ var generateCommand = (0, import_citty7.defineCommand)({
|
|
|
7280
7492
|
}
|
|
7281
7493
|
let schemaPath;
|
|
7282
7494
|
if (args.schema && typeof args.schema === "string") {
|
|
7283
|
-
schemaPath = (0,
|
|
7495
|
+
schemaPath = (0, import_node_path26.resolve)(args.schema);
|
|
7284
7496
|
} else {
|
|
7285
7497
|
const found = await findSchemaFile(projectRoot);
|
|
7286
7498
|
if (!found) {
|
|
@@ -7303,13 +7515,13 @@ var generateCommand = (0, import_citty7.defineCommand)({
|
|
|
7303
7515
|
}
|
|
7304
7516
|
const output = generateTypes(schema);
|
|
7305
7517
|
const outputFile = typeof args.output === "string" ? args.output : "kora/generated/types.ts";
|
|
7306
|
-
const outputPath = (0,
|
|
7307
|
-
await (0,
|
|
7308
|
-
await (0,
|
|
7518
|
+
const outputPath = (0, import_node_path26.resolve)(projectRoot, outputFile);
|
|
7519
|
+
await (0, import_promises17.mkdir)((0, import_node_path26.dirname)(outputPath), { recursive: true });
|
|
7520
|
+
await (0, import_promises17.writeFile)(outputPath, output, "utf-8");
|
|
7309
7521
|
logger.success(`Generated types at ${outputPath}`);
|
|
7310
7522
|
}
|
|
7311
7523
|
}),
|
|
7312
|
-
hooks: (0,
|
|
7524
|
+
hooks: (0, import_citty8.defineCommand)({
|
|
7313
7525
|
meta: {
|
|
7314
7526
|
name: "hooks",
|
|
7315
7527
|
description: "Generate per-collection React hook stubs"
|
|
@@ -7338,7 +7550,7 @@ var generateCommand = (0, import_citty7.defineCommand)({
|
|
|
7338
7550
|
}
|
|
7339
7551
|
let schemaPath;
|
|
7340
7552
|
if (args.schema && typeof args.schema === "string") {
|
|
7341
|
-
schemaPath = (0,
|
|
7553
|
+
schemaPath = (0, import_node_path26.resolve)(projectRoot, args.schema);
|
|
7342
7554
|
} else {
|
|
7343
7555
|
const found = await findSchemaFile(projectRoot);
|
|
7344
7556
|
if (!found) {
|
|
@@ -7352,13 +7564,13 @@ var generateCommand = (0, import_citty7.defineCommand)({
|
|
|
7352
7564
|
schemaPath = found;
|
|
7353
7565
|
}
|
|
7354
7566
|
const schema = await loadSchemaDefinition(schemaPath, projectRoot);
|
|
7355
|
-
const outputDir = typeof args.output === "string" ? (0,
|
|
7567
|
+
const outputDir = typeof args.output === "string" ? (0, import_node_path26.resolve)(projectRoot, args.output) : (0, import_node_path26.resolve)(projectRoot, "kora/generated/hooks");
|
|
7356
7568
|
const files = generateCollectionHooks(schema);
|
|
7357
7569
|
for (const [name, content] of files) {
|
|
7358
7570
|
const adjusted = typeof args.types === "string" && args.types !== "../types" ? content.replace("from '../types'", `from '${args.types}'`) : content;
|
|
7359
|
-
const filePath = (0,
|
|
7360
|
-
await (0,
|
|
7361
|
-
await (0,
|
|
7571
|
+
const filePath = (0, import_node_path26.resolve)(outputDir, name);
|
|
7572
|
+
await (0, import_promises17.mkdir)((0, import_node_path26.dirname)(filePath), { recursive: true });
|
|
7573
|
+
await (0, import_promises17.writeFile)(filePath, adjusted, "utf-8");
|
|
7362
7574
|
}
|
|
7363
7575
|
logger.success(`Generated ${String(files.size)} hook file(s) at ${outputDir}`);
|
|
7364
7576
|
logger.step("Run `kora generate types` first if ../types is missing.");
|
|
@@ -7380,10 +7592,10 @@ function isSchemaDefinition2(value) {
|
|
|
7380
7592
|
}
|
|
7381
7593
|
|
|
7382
7594
|
// src/commands/logs/logs-command.ts
|
|
7383
|
-
var
|
|
7595
|
+
var import_citty9 = require("citty");
|
|
7384
7596
|
var DEFAULT_SYNC_PORT2 = 3001;
|
|
7385
7597
|
var EVENTS_ENDPOINT = "/__kora/events";
|
|
7386
|
-
var logsCommand = (0,
|
|
7598
|
+
var logsCommand = (0, import_citty9.defineCommand)({
|
|
7387
7599
|
meta: {
|
|
7388
7600
|
name: "logs",
|
|
7389
7601
|
description: "Stream real-time events from a Kora sync server"
|
|
@@ -7487,9 +7699,9 @@ var logsCommand = (0, import_citty8.defineCommand)({
|
|
|
7487
7699
|
});
|
|
7488
7700
|
|
|
7489
7701
|
// src/commands/migrate/migrate-command.ts
|
|
7490
|
-
var
|
|
7491
|
-
var
|
|
7492
|
-
var
|
|
7702
|
+
var import_promises18 = require("fs/promises");
|
|
7703
|
+
var import_node_path27 = require("path");
|
|
7704
|
+
var import_citty10 = require("citty");
|
|
7493
7705
|
init_fs_helpers();
|
|
7494
7706
|
|
|
7495
7707
|
// src/commands/migrate/migration-generator.ts
|
|
@@ -7833,6 +8045,14 @@ function mapFieldType(descriptor) {
|
|
|
7833
8045
|
return "INTEGER";
|
|
7834
8046
|
case "array":
|
|
7835
8047
|
return "TEXT";
|
|
8048
|
+
case "object":
|
|
8049
|
+
return "TEXT";
|
|
8050
|
+
case "json":
|
|
8051
|
+
return "TEXT";
|
|
8052
|
+
case "blob":
|
|
8053
|
+
return "TEXT";
|
|
8054
|
+
case "secret":
|
|
8055
|
+
return "TEXT";
|
|
7836
8056
|
case "richtext":
|
|
7837
8057
|
return "BLOB";
|
|
7838
8058
|
}
|
|
@@ -7848,7 +8068,7 @@ function quoteIdentifier(identifier) {
|
|
|
7848
8068
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier)) {
|
|
7849
8069
|
throw new Error(`Invalid SQL identifier: ${identifier}`);
|
|
7850
8070
|
}
|
|
7851
|
-
return identifier
|
|
8071
|
+
return `"${identifier}"`;
|
|
7852
8072
|
}
|
|
7853
8073
|
function formatChange(change) {
|
|
7854
8074
|
switch (change.type) {
|
|
@@ -8084,7 +8304,7 @@ function generateOperationTransformModule(fromVersion, toVersion) {
|
|
|
8084
8304
|
init_schema_loader();
|
|
8085
8305
|
var SNAPSHOT_PATH = "kora/schema.snapshot.json";
|
|
8086
8306
|
var MIGRATIONS_DIR = "kora/migrations";
|
|
8087
|
-
var migrateCommand = (0,
|
|
8307
|
+
var migrateCommand = (0, import_citty10.defineCommand)({
|
|
8088
8308
|
meta: {
|
|
8089
8309
|
name: "migrate",
|
|
8090
8310
|
description: "Detect schema changes and generate/apply migrations"
|
|
@@ -8126,12 +8346,12 @@ var migrateCommand = (0, import_citty9.defineCommand)({
|
|
|
8126
8346
|
throw new InvalidProjectError(process.cwd());
|
|
8127
8347
|
}
|
|
8128
8348
|
const config = await loadKoraConfig(projectRoot);
|
|
8129
|
-
const resolvedSchemaPath = typeof args.schema === "string" ? (0,
|
|
8349
|
+
const resolvedSchemaPath = typeof args.schema === "string" ? (0, import_node_path27.resolve)(projectRoot, args.schema) : typeof config?.schema === "string" ? (0, import_node_path27.resolve)(projectRoot, config.schema) : await findSchemaFile(projectRoot);
|
|
8130
8350
|
if (!resolvedSchemaPath) {
|
|
8131
8351
|
throw new SchemaNotFoundError(["src/schema.ts", "schema.ts", "src/schema.js", "schema.js"]);
|
|
8132
8352
|
}
|
|
8133
8353
|
const currentSchema = await loadSchemaDefinition(resolvedSchemaPath, projectRoot);
|
|
8134
|
-
const snapshotFile = (0,
|
|
8354
|
+
const snapshotFile = (0, import_node_path27.join)(projectRoot, SNAPSHOT_PATH);
|
|
8135
8355
|
const previousSchema = await readSchemaSnapshot(snapshotFile);
|
|
8136
8356
|
if (!previousSchema) {
|
|
8137
8357
|
if (args["dry-run"] === true) {
|
|
@@ -8144,7 +8364,7 @@ var migrateCommand = (0, import_citty9.defineCommand)({
|
|
|
8144
8364
|
return;
|
|
8145
8365
|
}
|
|
8146
8366
|
const diff = diffSchemas(previousSchema, currentSchema);
|
|
8147
|
-
const outputDir = typeof args["output-dir"] === "string" ? (0,
|
|
8367
|
+
const outputDir = typeof args["output-dir"] === "string" ? (0, import_node_path27.resolve)(projectRoot, args["output-dir"]) : (0, import_node_path27.resolve)(projectRoot, MIGRATIONS_DIR);
|
|
8148
8368
|
if (!diff.hasChanges) {
|
|
8149
8369
|
logger.success("No schema changes detected.");
|
|
8150
8370
|
if (args.apply === true) {
|
|
@@ -8196,7 +8416,7 @@ var migrateCommand = (0, import_citty9.defineCommand)({
|
|
|
8196
8416
|
logger.warn("Dry run enabled: no files written, no migrations applied.");
|
|
8197
8417
|
return;
|
|
8198
8418
|
}
|
|
8199
|
-
await (0,
|
|
8419
|
+
await (0, import_promises18.mkdir)(outputDir, { recursive: true });
|
|
8200
8420
|
const migrationPath = await writeMigrationFile(
|
|
8201
8421
|
outputDir,
|
|
8202
8422
|
diff.fromVersion,
|
|
@@ -8232,7 +8452,7 @@ var migrateCommand = (0, import_citty9.defineCommand)({
|
|
|
8232
8452
|
});
|
|
8233
8453
|
async function readSchemaSnapshot(path) {
|
|
8234
8454
|
try {
|
|
8235
|
-
const content = await (0,
|
|
8455
|
+
const content = await (0, import_promises18.readFile)(path, "utf-8");
|
|
8236
8456
|
return JSON.parse(content);
|
|
8237
8457
|
} catch {
|
|
8238
8458
|
return null;
|
|
@@ -8253,15 +8473,15 @@ function isInteractiveTerminal2() {
|
|
|
8253
8473
|
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
8254
8474
|
}
|
|
8255
8475
|
async function writeSchemaSnapshot(path, schema) {
|
|
8256
|
-
await (0,
|
|
8257
|
-
await (0,
|
|
8476
|
+
await (0, import_promises18.mkdir)((0, import_node_path27.dirname)(path), { recursive: true });
|
|
8477
|
+
await (0, import_promises18.writeFile)(path, `${JSON.stringify(schema, null, 2)}
|
|
8258
8478
|
`, "utf-8");
|
|
8259
8479
|
}
|
|
8260
8480
|
async function writeMigrationFile(outputDir, fromVersion, toVersion, generated) {
|
|
8261
|
-
const existing = await (0,
|
|
8481
|
+
const existing = await (0, import_promises18.readdir)(outputDir).catch(() => []);
|
|
8262
8482
|
const sequence = existing.filter((file) => /^\d{3}-/.test(file)).length + 1;
|
|
8263
8483
|
const filename = `${String(sequence).padStart(3, "0")}-v${fromVersion}-to-v${toVersion}.ts`;
|
|
8264
|
-
const path = (0,
|
|
8484
|
+
const path = (0, import_node_path27.join)(outputDir, filename);
|
|
8265
8485
|
const migrationId = filename.replace(/\.ts$/, "");
|
|
8266
8486
|
const fileContent = [
|
|
8267
8487
|
`export const up = ${JSON.stringify(generated.up, null, 2)} as const`,
|
|
@@ -8273,10 +8493,10 @@ async function writeMigrationFile(outputDir, fromVersion, toVersion, generated)
|
|
|
8273
8493
|
`export const containsBreakingChanges = ${generated.containsBreakingChanges}`,
|
|
8274
8494
|
""
|
|
8275
8495
|
].join("\n");
|
|
8276
|
-
await (0,
|
|
8277
|
-
const transformsPath = (0,
|
|
8278
|
-
await (0,
|
|
8279
|
-
await writeMigrationManifest((0,
|
|
8496
|
+
await (0, import_promises18.writeFile)(path, fileContent, "utf-8");
|
|
8497
|
+
const transformsPath = (0, import_node_path27.join)(outputDir, `${migrationId}.transforms.ts`);
|
|
8498
|
+
await (0, import_promises18.writeFile)(transformsPath, generateOperationTransformModule(fromVersion, toVersion), "utf-8");
|
|
8499
|
+
await writeMigrationManifest((0, import_node_path27.join)(outputDir, `${migrationId}.json`), {
|
|
8280
8500
|
id: migrationId,
|
|
8281
8501
|
fromVersion,
|
|
8282
8502
|
toVersion,
|
|
@@ -8288,22 +8508,22 @@ async function writeMigrationFile(outputDir, fromVersion, toVersion, generated)
|
|
|
8288
8508
|
return path;
|
|
8289
8509
|
}
|
|
8290
8510
|
async function writeMigrationManifest(path, manifest) {
|
|
8291
|
-
await (0,
|
|
8511
|
+
await (0, import_promises18.writeFile)(path, `${JSON.stringify(manifest, null, 2)}
|
|
8292
8512
|
`, "utf-8");
|
|
8293
8513
|
}
|
|
8294
8514
|
async function listMigrationManifests(outputDir) {
|
|
8295
|
-
const files = await (0,
|
|
8515
|
+
const files = await (0, import_promises18.readdir)(outputDir).catch(() => []);
|
|
8296
8516
|
const migrationFiles = files.filter((file) => /^\d{3}-.*\.ts$/.test(file)).sort((left, right) => left.localeCompare(right));
|
|
8297
8517
|
const manifests = [];
|
|
8298
8518
|
for (const file of migrationFiles) {
|
|
8299
8519
|
const id = file.replace(/\.ts$/, "");
|
|
8300
|
-
const manifestPath = (0,
|
|
8520
|
+
const manifestPath = (0, import_node_path27.join)(outputDir, `${id}.json`);
|
|
8301
8521
|
const jsonManifest = await readMigrationManifest(manifestPath);
|
|
8302
8522
|
if (jsonManifest) {
|
|
8303
8523
|
manifests.push({ ...jsonManifest, id });
|
|
8304
8524
|
continue;
|
|
8305
8525
|
}
|
|
8306
|
-
const migrationPath = (0,
|
|
8526
|
+
const migrationPath = (0, import_node_path27.join)(outputDir, file);
|
|
8307
8527
|
const sourceManifest = await readMigrationManifestFromSource(migrationPath, id);
|
|
8308
8528
|
manifests.push(sourceManifest);
|
|
8309
8529
|
}
|
|
@@ -8311,7 +8531,7 @@ async function listMigrationManifests(outputDir) {
|
|
|
8311
8531
|
}
|
|
8312
8532
|
async function readMigrationManifest(path) {
|
|
8313
8533
|
try {
|
|
8314
|
-
const content = await (0,
|
|
8534
|
+
const content = await (0, import_promises18.readFile)(path, "utf-8");
|
|
8315
8535
|
return JSON.parse(content);
|
|
8316
8536
|
} catch (error) {
|
|
8317
8537
|
const code = error.code;
|
|
@@ -8322,7 +8542,7 @@ async function readMigrationManifest(path) {
|
|
|
8322
8542
|
}
|
|
8323
8543
|
}
|
|
8324
8544
|
async function readMigrationManifestFromSource(path, id) {
|
|
8325
|
-
const content = await (0,
|
|
8545
|
+
const content = await (0, import_promises18.readFile)(path, "utf-8");
|
|
8326
8546
|
const versions = parseVersionsFromMigrationId(id);
|
|
8327
8547
|
return {
|
|
8328
8548
|
id,
|
|
@@ -8384,18 +8604,18 @@ function parseLiteralExport(source, exportName) {
|
|
|
8384
8604
|
}
|
|
8385
8605
|
function resolveSqliteApplyPath(dbArg, projectRoot, config) {
|
|
8386
8606
|
if (typeof dbArg === "string") {
|
|
8387
|
-
return (0,
|
|
8607
|
+
return (0, import_node_path27.resolve)(projectRoot, dbArg);
|
|
8388
8608
|
}
|
|
8389
8609
|
const sync = config?.dev?.sync;
|
|
8390
8610
|
if (typeof sync === "object" && sync !== null) {
|
|
8391
8611
|
if (sync.store === "sqlite") {
|
|
8392
|
-
return (0,
|
|
8612
|
+
return (0, import_node_path27.join)(projectRoot, "kora-sync.db");
|
|
8393
8613
|
}
|
|
8394
8614
|
if (typeof sync.store === "object" && sync.store !== null && sync.store.type === "sqlite") {
|
|
8395
8615
|
if (typeof sync.store.filename === "string" && sync.store.filename.length > 0) {
|
|
8396
|
-
return (0,
|
|
8616
|
+
return (0, import_node_path27.resolve)(projectRoot, sync.store.filename);
|
|
8397
8617
|
}
|
|
8398
|
-
return (0,
|
|
8618
|
+
return (0, import_node_path27.join)(projectRoot, "kora-sync.db");
|
|
8399
8619
|
}
|
|
8400
8620
|
}
|
|
8401
8621
|
return void 0;
|
|
@@ -8413,7 +8633,7 @@ function resolvePostgresConnectionString(config) {
|
|
|
8413
8633
|
}
|
|
8414
8634
|
|
|
8415
8635
|
// src/commands/status/status-command.ts
|
|
8416
|
-
var
|
|
8636
|
+
var import_citty11 = require("citty");
|
|
8417
8637
|
var DEFAULT_SYNC_PORT3 = 3001;
|
|
8418
8638
|
var STATUS_ENDPOINT2 = "/__kora/status";
|
|
8419
8639
|
async function fetchServerStatus(url, token) {
|
|
@@ -8440,7 +8660,7 @@ function formatUptime(ms) {
|
|
|
8440
8660
|
parts.push(`${seconds % 60}s`);
|
|
8441
8661
|
return parts.join(" ");
|
|
8442
8662
|
}
|
|
8443
|
-
var statusCommand = (0,
|
|
8663
|
+
var statusCommand = (0, import_citty11.defineCommand)({
|
|
8444
8664
|
meta: {
|
|
8445
8665
|
name: "status",
|
|
8446
8666
|
description: "Show Kora sync server status"
|
|
@@ -8546,9 +8766,9 @@ function printStatus(status, url, logger) {
|
|
|
8546
8766
|
|
|
8547
8767
|
// src/commands/studio/studio-command.ts
|
|
8548
8768
|
var import_node_fs8 = require("fs");
|
|
8549
|
-
var
|
|
8550
|
-
var
|
|
8551
|
-
var studioCommand = (0,
|
|
8769
|
+
var import_node_path30 = require("path");
|
|
8770
|
+
var import_citty12 = require("citty");
|
|
8771
|
+
var studioCommand = (0, import_citty12.defineCommand)({
|
|
8552
8772
|
meta: {
|
|
8553
8773
|
name: "studio",
|
|
8554
8774
|
description: "Kora Studio: visualize records, operations, and sync \u2014 or run the sync lab"
|
|
@@ -8597,7 +8817,7 @@ var studioCommand = (0, import_citty11.defineCommand)({
|
|
|
8597
8817
|
);
|
|
8598
8818
|
}
|
|
8599
8819
|
const { loadSchemaDefinition: loadSchemaDefinition2 } = await Promise.resolve().then(() => (init_schema_loader(), schema_loader_exports));
|
|
8600
|
-
const schema = await loadSchemaDefinition2((0,
|
|
8820
|
+
const schema = await loadSchemaDefinition2((0, import_node_path30.resolve)(process.cwd(), args.schema), process.cwd());
|
|
8601
8821
|
const { SpectatorManager: SpectatorManager2 } = await Promise.resolve().then(() => (init_spectator_manager(), spectator_manager_exports));
|
|
8602
8822
|
const spectator = new SpectatorManager2({
|
|
8603
8823
|
url: args.connect,
|
|
@@ -8624,7 +8844,7 @@ var studioCommand = (0, import_citty11.defineCommand)({
|
|
|
8624
8844
|
let schema = defaultLabSchema2();
|
|
8625
8845
|
if (typeof args.schema === "string") {
|
|
8626
8846
|
const { loadSchemaDefinition: loadSchemaDefinition2 } = await Promise.resolve().then(() => (init_schema_loader(), schema_loader_exports));
|
|
8627
|
-
schema = await loadSchemaDefinition2((0,
|
|
8847
|
+
schema = await loadSchemaDefinition2((0, import_node_path30.resolve)(process.cwd(), args.schema), process.cwd());
|
|
8628
8848
|
}
|
|
8629
8849
|
const initialDevices = args.devices !== void 0 ? Math.max(1, Number.parseInt(args.devices, 10) || 2) : 2;
|
|
8630
8850
|
const lab = new LabManager2(schema);
|
|
@@ -8649,7 +8869,7 @@ var studioCommand = (0, import_citty11.defineCommand)({
|
|
|
8649
8869
|
"Pass --db <path> to inspect a database, --lab for the sync laboratory, or --connect <wss url> for live spectator mode."
|
|
8650
8870
|
);
|
|
8651
8871
|
}
|
|
8652
|
-
const dbPath = (0,
|
|
8872
|
+
const dbPath = (0, import_node_path30.resolve)(process.cwd(), args.db);
|
|
8653
8873
|
if (!(0, import_node_fs8.existsSync)(dbPath)) {
|
|
8654
8874
|
throw new Error(`Database file not found: ${dbPath}`);
|
|
8655
8875
|
}
|
|
@@ -8668,12 +8888,13 @@ var studioCommand = (0, import_citty11.defineCommand)({
|
|
|
8668
8888
|
});
|
|
8669
8889
|
|
|
8670
8890
|
// src/bin.ts
|
|
8671
|
-
var main = (0,
|
|
8891
|
+
var main = (0, import_citty13.defineCommand)({
|
|
8672
8892
|
meta: {
|
|
8673
8893
|
name: "kora",
|
|
8674
|
-
description: "Kora.js
|
|
8894
|
+
description: "Kora.js, the offline-first application framework"
|
|
8675
8895
|
},
|
|
8676
8896
|
subCommands: {
|
|
8897
|
+
"agents-md": agentsCommand,
|
|
8677
8898
|
backup: backupCommand,
|
|
8678
8899
|
compact: compactCommand,
|
|
8679
8900
|
create: createCommand,
|
|
@@ -8687,5 +8908,5 @@ var main = (0, import_citty12.defineCommand)({
|
|
|
8687
8908
|
studio: studioCommand
|
|
8688
8909
|
}
|
|
8689
8910
|
});
|
|
8690
|
-
(0,
|
|
8911
|
+
(0, import_citty13.runMain)(main);
|
|
8691
8912
|
//# sourceMappingURL=bin.cjs.map
|