@bitcobblers/wod-wiki-engine 0.35.2128 → 0.36.2130
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/wod.cjs +758 -194
- package/dist/bin/wod.cjs.map +1 -1
- package/dist/bin/wod.d.cts +1 -1
- package/dist/bin/wod.d.ts +1 -1
- package/dist/bin/wod.mjs +5 -3
- package/dist/bin/wod.mjs.map +1 -1
- package/dist/chunk-6L5ZDZJ7.mjs +15 -0
- package/dist/chunk-6L5ZDZJ7.mjs.map +1 -0
- package/dist/{chunk-Y6WO6MXS.mjs → chunk-BMHE7DDG.mjs} +3 -9
- package/dist/chunk-BMHE7DDG.mjs.map +1 -0
- package/dist/chunk-EUQWEX6Z.mjs +253 -0
- package/dist/chunk-EUQWEX6Z.mjs.map +1 -0
- package/dist/{chunk-N4KFWY6Z.mjs → chunk-UKBQ36RW.mjs} +377 -193
- package/dist/chunk-UKBQ36RW.mjs.map +1 -0
- package/dist/{compiler-SXUCF7AU.mjs → compiler-NODHKWJJ.mjs} +4 -3
- package/dist/compiler-NODHKWJJ.mjs.map +1 -0
- package/dist/index.cjs +763 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -8
- package/dist/index.d.ts +27 -8
- package/dist/index.mjs +10 -8
- package/dist/index.mjs.map +1 -1
- package/dist/server/app.cjs +299 -0
- package/dist/server/app.cjs.map +1 -0
- package/dist/server/app.d.cts +24 -0
- package/dist/server/app.d.ts +24 -0
- package/dist/server/app.mjs +301 -0
- package/dist/server/app.mjs.map +1 -0
- package/dist/server-4P6AJAGT.mjs +128 -0
- package/dist/server-4P6AJAGT.mjs.map +1 -0
- package/dist/web/playground/ai-skills/parse.md +656 -0
- package/dist/web/playground/assets/main-Bhn9NHgQ.css +2 -0
- package/dist/web/playground/assets/main-CGSJY1vM.js +212 -0
- package/dist/web/playground/assets/rolldown-runtime-C0FnF6B9.js +1 -0
- package/dist/web/playground/assets/statementBuilderFlow-PTgOOzz5.js +2 -0
- package/dist/web/playground/assets/vendor-BlJqgFME.js +201 -0
- package/dist/web/playground/assets/vendor-codemirror-BtJgoBjf.js +40 -0
- package/dist/web/playground/fonts/Inter-Regular.woff2 +0 -0
- package/dist/web/playground/fonts/Inter-SemiBold.woff2 +0 -0
- package/dist/web/playground/images/hero/editing.png +0 -0
- package/dist/web/playground/images/hero/journal.png +0 -0
- package/dist/web/playground/images/hero/results.png +0 -0
- package/dist/web/playground/images/hero/timer.png +0 -0
- package/dist/web/playground/images/wod-wiki-logo-dark.png +0 -0
- package/dist/web/playground/images/wod-wiki-logo-light.png +0 -0
- package/dist/web/playground/index.html +60 -0
- package/dist/web/playground/seed/core/chunks/canvas.e6c77ad0.json +1 -0
- package/dist/web/playground/seed/core/chunks/template.e5e0e82d.json +1 -0
- package/dist/web/playground/seed/core/manifest.json +24 -0
- package/dist/web/playground/seed/core/report.html +43 -0
- package/dist/web/server/ai-skills/parse.md +656 -0
- package/dist/web/server/assets/main-Bhn9NHgQ.css +2 -0
- package/dist/web/server/assets/main-DhN2J5Ax.js +211 -0
- package/dist/web/server/assets/rolldown-runtime-C0FnF6B9.js +1 -0
- package/dist/web/server/assets/statementBuilderFlow-Dj0o2Wpk.js +2 -0
- package/dist/web/server/assets/vendor-BlJqgFME.js +201 -0
- package/dist/web/server/assets/vendor-codemirror-BtJgoBjf.js +40 -0
- package/dist/web/server/fonts/Inter-Regular.woff2 +0 -0
- package/dist/web/server/fonts/Inter-SemiBold.woff2 +0 -0
- package/dist/web/server/images/hero/editing.png +0 -0
- package/dist/web/server/images/hero/journal.png +0 -0
- package/dist/web/server/images/hero/results.png +0 -0
- package/dist/web/server/images/hero/timer.png +0 -0
- package/dist/web/server/images/wod-wiki-logo-dark.png +0 -0
- package/dist/web/server/images/wod-wiki-logo-light.png +0 -0
- package/dist/web/server/index.html +60 -0
- package/dist/web/server/seed/core/chunks/canvas.e6c77ad0.json +1 -0
- package/dist/web/server/seed/core/chunks/template.e5e0e82d.json +1 -0
- package/dist/web/server/seed/core/manifest.json +24 -0
- package/dist/web/server/seed/core/report.html +43 -0
- package/package.json +11 -5
- package/dist/chunk-N4KFWY6Z.mjs.map +0 -1
- package/dist/chunk-Y6WO6MXS.mjs.map +0 -1
- package/dist/compiler-SXUCF7AU.mjs.map +0 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
|
-
import { SEED_SCHEMA, SEED_REGISTERED_WIDGETS, seedNoteSourceId, catalogForChunkId, DASHBOARDS_CHUNK_ID, EFFORTS_CHUNK_ID, parseEffortFile,
|
|
2
|
+
import { SEED_SCHEMA, SEED_REGISTERED_WIDGETS, seedNoteSourceId, catalogForChunkId, DASHBOARDS_CHUNK_ID, EFFORTS_CHUNK_ID, parseEffortFile, seedMetaKey, emptySeedMeta, CANVAS_CHUNK_ID } from './chunk-BMHE7DDG.mjs';
|
|
3
|
+
import { openCliDb, nodeFs, sqliteIndexStore, sqliteEffortStore, sqliteBlockStore, sqliteNoteStore, sqliteEventStore, getNoteBundle, getSessionBundle, getEffortBySlug, listTagsByType, nodePath, loadSql, uuid5, CLI_UUID_NAMESPACE, stableNoteId, randomId } from './chunk-EUQWEX6Z.mjs';
|
|
4
|
+
import { __require } from './chunk-6L5ZDZJ7.mjs';
|
|
3
5
|
import { dialectRegistry, realtimeProcessorRegistry, summaryProcessorRegistry, getHints, createParser, toStoredOutputStatement, frozenNow, createCompiler, createMockClock, RuntimeStack, EventBus, ScriptRuntime, createAnalyticsEngineForBlock, StartSessionAction, NextEvent, bundledEfforts, parseScript } from '@bitcobblers/wod-wiki-lang';
|
|
4
6
|
import { MetricType, validateNoteBlocks, parseDocumentSections, blockContentId, reconcileNoteBlocks, mapNoteBlockChanges, KNOWN_SECTION_WIDGETS } from '@bitcobblers/wod-wiki-core';
|
|
5
7
|
import { WQL_TYPED_TAG_KEYS, toEventRows, toSummaryEventRows, parseQuery, QueryService, isPipelineQuery, isFindQuery } from '@bitcobblers/wod-wiki-wql';
|
|
@@ -360,7 +362,7 @@ function loadQueryData(options) {
|
|
|
360
362
|
} else if (obj.facts || obj.results || obj.notes || obj.blocks || obj.efforts || obj.tags || obj.logs) {
|
|
361
363
|
const corpus = payload;
|
|
362
364
|
if (corpus.facts) data.facts = corpus.facts;
|
|
363
|
-
if (corpus.results) data.results = corpus.results;
|
|
365
|
+
if (Array.isArray(corpus.results)) data.results = corpus.results;
|
|
364
366
|
if (corpus.notes) data.notes = corpus.notes;
|
|
365
367
|
if (corpus.blocks) data.blocks = corpus.blocks;
|
|
366
368
|
if (corpus.efforts) data.efforts = corpus.efforts;
|
|
@@ -1580,192 +1582,249 @@ ${escapeCsvField2(data.parsed.metric)},${data.scalar},${escapeCsvField2(data.uni
|
|
|
1580
1582
|
}
|
|
1581
1583
|
return lines.join("\n");
|
|
1582
1584
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
var nodeCrypto = () => nodeRequire()("node:crypto");
|
|
1585
|
+
|
|
1586
|
+
// src/cli/config.ts
|
|
1586
1587
|
function nodeRequire() {
|
|
1587
1588
|
const g = globalThis;
|
|
1588
1589
|
if (typeof g.process?.versions?.node === "undefined" && typeof g.Bun === "undefined") {
|
|
1589
|
-
throw new Error("
|
|
1590
|
+
throw new Error("database configuration is only supported in Node / Bun environments");
|
|
1590
1591
|
}
|
|
1591
1592
|
const req = g.require ?? (typeof __require === "function" ? __require : void 0);
|
|
1592
|
-
if (!req) throw new Error("
|
|
1593
|
+
if (!req) throw new Error("database configuration requires a CJS require shim (missing tsup banner?)");
|
|
1593
1594
|
return req;
|
|
1594
1595
|
}
|
|
1595
|
-
var
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1596
|
+
var nodePath2 = () => nodeRequire()("node:path");
|
|
1597
|
+
var nodeFs2 = () => nodeRequire()("node:fs");
|
|
1598
|
+
function parseEnvFile(content) {
|
|
1599
|
+
return nodeRequire()("node:util").parseEnv(content);
|
|
1600
|
+
}
|
|
1601
|
+
function loadCliEnvironment(envFile) {
|
|
1602
|
+
const fs = nodeFs2();
|
|
1603
|
+
const path = nodePath2();
|
|
1604
|
+
let file;
|
|
1605
|
+
if (envFile !== void 0) {
|
|
1606
|
+
file = path.resolve(process.cwd(), envFile);
|
|
1607
|
+
if (!fs.existsSync(file)) throw new Error(`[wod] --env-file: file not found: ${envFile}`);
|
|
1608
|
+
} else {
|
|
1609
|
+
let dir = process.cwd();
|
|
1610
|
+
for (; ; ) {
|
|
1611
|
+
const candidate = path.join(dir, ".env");
|
|
1612
|
+
if (fs.existsSync(candidate)) {
|
|
1613
|
+
file = candidate;
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
const parent = path.dirname(dir);
|
|
1617
|
+
if (parent === dir) break;
|
|
1618
|
+
dir = parent;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return file !== void 0 ? parseEnvFile(fs.readFileSync(file, "utf-8")) : {};
|
|
1622
|
+
}
|
|
1623
|
+
var SQLITE_URL_SCHEMES = /^(libsql|https?|wss?|file):\/\//;
|
|
1624
|
+
var PG_URL_SCHEMES = /^postgres(ql)?:\/\//;
|
|
1625
|
+
var TURSO_URL_SCHEMES = /^(libsql|https?|wss?):\/\//;
|
|
1626
|
+
var PG_FLAG_KEYS = [
|
|
1627
|
+
"postgresHost",
|
|
1628
|
+
"postgresPort",
|
|
1629
|
+
"postgresUser",
|
|
1630
|
+
"postgresPassword",
|
|
1631
|
+
"postgresDatabase",
|
|
1632
|
+
"postgresSsl"
|
|
1633
|
+
];
|
|
1634
|
+
var PG_ENV_KEYS = [
|
|
1635
|
+
"POSTGRES_HOST",
|
|
1636
|
+
"POSTGRES_PORT",
|
|
1637
|
+
"POSTGRES_USER",
|
|
1638
|
+
"POSTGRES_PASSWORD",
|
|
1639
|
+
"POSTGRES_DATABASE",
|
|
1640
|
+
"POSTGRES_SSL"
|
|
1641
|
+
];
|
|
1642
|
+
var isBackend = (v) => v === "sqlite" || v === "postgres" || v === "turso";
|
|
1643
|
+
function setEnv(v) {
|
|
1644
|
+
return v !== void 0 && v.trim() !== "" ? v : void 0;
|
|
1645
|
+
}
|
|
1646
|
+
function fail(message) {
|
|
1647
|
+
throw new Error(`[wod] ${message}`);
|
|
1648
|
+
}
|
|
1649
|
+
function parsePort(v, source) {
|
|
1650
|
+
if (!/^\d+$/.test(v)) fail(`${source} must be an integer 1..65535, got ${JSON.stringify(v)}`);
|
|
1651
|
+
const port = Number(v);
|
|
1652
|
+
if (port < 1 || port > 65535) fail(`${source} must be an integer 1..65535, got ${v}`);
|
|
1653
|
+
return port;
|
|
1654
|
+
}
|
|
1655
|
+
function sslMode(v, source) {
|
|
1656
|
+
if (v === void 0 || v === "") return "prefer";
|
|
1657
|
+
if (typeof v === "boolean") return v ? "require" : "disable";
|
|
1658
|
+
const s = v.trim().toLowerCase();
|
|
1659
|
+
if (["true", "1", "yes", "require"].includes(s)) return "require";
|
|
1660
|
+
if (["false", "0", "no", "disable", "disabled"].includes(s)) return "disable";
|
|
1661
|
+
if (s === "prefer" || s === "verify-ca" || s === "verify-full") return s;
|
|
1662
|
+
fail(`${source} must be disable|prefer|require|verify-ca|verify-full, got ${JSON.stringify(v)}`);
|
|
1663
|
+
}
|
|
1664
|
+
function safeUrlLabel(raw) {
|
|
1618
1665
|
try {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
await db.close();
|
|
1624
|
-
throw error;
|
|
1666
|
+
const u = new URL(raw);
|
|
1667
|
+
return `${u.protocol}//${u.host}${u.pathname}`;
|
|
1668
|
+
} catch {
|
|
1669
|
+
return "<unparsable-url>";
|
|
1625
1670
|
}
|
|
1626
1671
|
}
|
|
1627
|
-
function
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
bytes[8] = bytes[8] & 63 | 128;
|
|
1631
|
-
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0"));
|
|
1632
|
-
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
|
|
1633
|
-
}
|
|
1634
|
-
function uuid5(namespace, name) {
|
|
1635
|
-
return formatV5Digest(nodeCrypto().createHash("sha1").update(namespace).update(name).digest());
|
|
1636
|
-
}
|
|
1637
|
-
var CLI_UUID_NAMESPACE = "c0ffee00-8b1a-4e2c-9d3f-5a6b7c8d9e0f";
|
|
1638
|
-
function stableNoteId(sourceLabel, content) {
|
|
1639
|
-
if (sourceLabel && sourceLabel !== "-") {
|
|
1640
|
-
return uuid5(CLI_UUID_NAMESPACE, `wod-cli:${nodePath().resolve(process.cwd(), sourceLabel)}`);
|
|
1672
|
+
function postgresFromUrl(url, source) {
|
|
1673
|
+
if (!PG_URL_SCHEMES.test(url)) {
|
|
1674
|
+
fail(`${source} must start with postgres:// or postgresql://`);
|
|
1641
1675
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
}
|
|
1650
|
-
async function rowsByIndex(sql, db, store, index, only) {
|
|
1651
|
-
return sql.listRows(db, sql.storeDefinition(store), { only }, void 0, index);
|
|
1652
|
-
}
|
|
1653
|
-
function sqliteEventStore(db) {
|
|
1654
|
-
const all = async () => await allRows(await loadSql(), db, "events");
|
|
1676
|
+
let u;
|
|
1677
|
+
try {
|
|
1678
|
+
u = new URL(url);
|
|
1679
|
+
} catch {
|
|
1680
|
+
fail(`${source} is not a parseable URL`);
|
|
1681
|
+
}
|
|
1682
|
+
const database = decodeURIComponent(u.pathname.replace(/^\/+|\/+$/g, ""));
|
|
1683
|
+
if (database === "") fail(`${source} has no database name`);
|
|
1655
1684
|
return {
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
for (const row of appended) await sql.putRow(tx, eventsDef, row);
|
|
1666
|
-
});
|
|
1667
|
-
},
|
|
1668
|
-
finalizeSummaries: async (resultId, finals) => {
|
|
1669
|
-
const sql = await loadSql();
|
|
1670
|
-
await db.transaction(async (tx) => {
|
|
1671
|
-
const eventsDef = sql.storeDefinition("events");
|
|
1672
|
-
const existing = (await sql.listRows(tx, eventsDef)).filter(
|
|
1673
|
-
(r) => r.resultId === resultId && r.grain === "summary" && r.origin !== "user"
|
|
1674
|
-
);
|
|
1675
|
-
for (const row of existing) await sql.deleteRows(tx, eventsDef, row.id);
|
|
1676
|
-
for (const row of finals) await sql.putRow(tx, eventsDef, row);
|
|
1677
|
-
});
|
|
1678
|
-
},
|
|
1679
|
-
deleteEvents: async (ids) => {
|
|
1680
|
-
const sql = await loadSql();
|
|
1681
|
-
await db.transaction(async (tx) => {
|
|
1682
|
-
const eventsDef = sql.storeDefinition("events");
|
|
1683
|
-
for (const id of ids) await sql.deleteRows(tx, eventsDef, id);
|
|
1684
|
-
});
|
|
1685
|
-
}
|
|
1685
|
+
kind: "postgres",
|
|
1686
|
+
label: safeUrlLabel(url),
|
|
1687
|
+
url,
|
|
1688
|
+
host: u.hostname,
|
|
1689
|
+
port: u.port !== "" ? parsePort(u.port, `${source} port`) : 5432,
|
|
1690
|
+
database,
|
|
1691
|
+
user: u.username !== "" ? decodeURIComponent(u.username) : void 0,
|
|
1692
|
+
password: u.password !== "" ? decodeURIComponent(u.password) : void 0,
|
|
1693
|
+
ssl: sslMode(u.searchParams.get("sslmode") ?? u.searchParams.get("ssl") ?? void 0, `${source} ssl parameter`)
|
|
1686
1694
|
};
|
|
1687
1695
|
}
|
|
1688
|
-
function
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1696
|
+
function resolvePostgres(options, e, databaseUrl) {
|
|
1697
|
+
const flagProps = PG_FLAG_KEYS.some((k) => options[k] !== void 0);
|
|
1698
|
+
const envProps = PG_ENV_KEYS.some((k) => setEnv(e[k]) !== void 0);
|
|
1699
|
+
if (flagProps || envProps && databaseUrl === void 0) {
|
|
1700
|
+
const host = options.postgresHost ?? setEnv(e.POSTGRES_HOST) ?? "127.0.0.1";
|
|
1701
|
+
const port = parsePort(options.postgresPort ?? setEnv(e.POSTGRES_PORT) ?? "5432", "--postgres-port/POSTGRES_PORT");
|
|
1702
|
+
const database = options.postgresDatabase ?? setEnv(e.POSTGRES_DATABASE);
|
|
1703
|
+
if (database === void 0) {
|
|
1704
|
+
fail("--postgres-database (or POSTGRES_DATABASE) is required for per-property PostgreSQL configuration");
|
|
1705
|
+
}
|
|
1706
|
+
const user = options.postgresUser ?? setEnv(e.POSTGRES_USER);
|
|
1707
|
+
const password = options.postgresPassword ?? setEnv(e.POSTGRES_PASSWORD);
|
|
1708
|
+
const ssl = sslMode(options.postgresSsl ?? setEnv(e.POSTGRES_SSL), "--postgres-ssl/POSTGRES_SSL");
|
|
1709
|
+
try {
|
|
1710
|
+
const u = new URL(`postgresql://${host}`);
|
|
1711
|
+
u.port = String(port);
|
|
1712
|
+
u.pathname = `/${database}`;
|
|
1713
|
+
if (user !== void 0) u.username = user;
|
|
1714
|
+
if (password !== void 0) u.password = password;
|
|
1715
|
+
u.searchParams.set("sslmode", ssl);
|
|
1716
|
+
return {
|
|
1717
|
+
kind: "postgres",
|
|
1718
|
+
label: `postgresql://${u.host}${u.pathname}`,
|
|
1719
|
+
url: u.toString(),
|
|
1720
|
+
host,
|
|
1721
|
+
port,
|
|
1722
|
+
database,
|
|
1723
|
+
user,
|
|
1724
|
+
password,
|
|
1725
|
+
ssl
|
|
1726
|
+
};
|
|
1727
|
+
} catch {
|
|
1728
|
+
fail("invalid PostgreSQL host/database in per-property configuration");
|
|
1718
1729
|
}
|
|
1719
|
-
}
|
|
1730
|
+
}
|
|
1731
|
+
if (databaseUrl !== void 0) return postgresFromUrl(databaseUrl, "DB_DRIVER=postgres DATABASE_URL");
|
|
1732
|
+
fail("DB_DRIVER=postgres requires DATABASE_URL starting with postgres:// or postgresql:// \u2014 or per-property --postgres-host/--postgres-database flags");
|
|
1720
1733
|
}
|
|
1721
|
-
function
|
|
1734
|
+
function resolveTurso(options, e, databaseUrl) {
|
|
1735
|
+
const url = options.tursoUrl ?? setEnv(e.TURSO_DATABASE_URL) ?? databaseUrl;
|
|
1736
|
+
if (url === void 0) {
|
|
1737
|
+
fail("DB_DRIVER=turso requires --turso-url / TURSO_DATABASE_URL or DATABASE_URL (libsql:// or https://)");
|
|
1738
|
+
}
|
|
1739
|
+
if (PG_URL_SCHEMES.test(url)) fail("DB_DRIVER=turso cannot use a postgres:// URL");
|
|
1740
|
+
if (!TURSO_URL_SCHEMES.test(url)) fail("DB_DRIVER=turso requires a libsql://, https://, http:// or wss:// URL");
|
|
1722
1741
|
return {
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
}
|
|
1742
|
+
kind: "turso",
|
|
1743
|
+
label: safeUrlLabel(url),
|
|
1744
|
+
url,
|
|
1745
|
+
authToken: options.tursoAuthToken ?? setEnv(e.TURSO_AUTH_TOKEN) ?? setEnv(e.LIBSQL_AUTH_TOKEN)
|
|
1728
1746
|
};
|
|
1729
1747
|
}
|
|
1730
|
-
function
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1748
|
+
function resolveSqlite(options, e, databaseUrl) {
|
|
1749
|
+
if (options.db !== void 0) {
|
|
1750
|
+
const path2 = nodePath2().resolve(process.cwd(), options.db);
|
|
1751
|
+
return { kind: "sqlite", label: path2, path: path2 };
|
|
1752
|
+
}
|
|
1753
|
+
if (databaseUrl !== void 0) {
|
|
1754
|
+
if (PG_URL_SCHEMES.test(databaseUrl)) fail("DB_DRIVER=sqlite cannot use a postgres:// DATABASE_URL");
|
|
1755
|
+
if (databaseUrl.startsWith("file:")) {
|
|
1756
|
+
const path2 = nodePath2().resolve(process.cwd(), decodeURIComponent(databaseUrl.slice("file:".length).split("?")[0]));
|
|
1757
|
+
return { kind: "sqlite", label: path2, path: path2 };
|
|
1758
|
+
}
|
|
1759
|
+
if (!SQLITE_URL_SCHEMES.test(databaseUrl)) {
|
|
1760
|
+
fail("DB_DRIVER=sqlite requires a libsql://, https://, http://, wss:// or file:// DATABASE_URL");
|
|
1761
|
+
}
|
|
1762
|
+
return { kind: "turso", label: safeUrlLabel(databaseUrl), url: databaseUrl, authToken: setEnv(e.LIBSQL_AUTH_TOKEN) };
|
|
1763
|
+
}
|
|
1764
|
+
const path = nodePath2().resolve(process.cwd(), setEnv(e.WOD_WIKI_DB) ?? setEnv(e.SQLITE_PATH) ?? "./wodwiki.db");
|
|
1765
|
+
return { kind: "sqlite", label: path, path };
|
|
1766
|
+
}
|
|
1767
|
+
function envBackend(e) {
|
|
1768
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
1769
|
+
if (setEnv(e.WOD_WIKI_DB) !== void 0 || setEnv(e.SQLITE_PATH) !== void 0) kinds.add("sqlite");
|
|
1770
|
+
const dbUrl = setEnv(e.DATABASE_URL);
|
|
1771
|
+
if (PG_ENV_KEYS.some((k) => setEnv(e[k]) !== void 0) || dbUrl !== void 0 && PG_URL_SCHEMES.test(dbUrl)) {
|
|
1772
|
+
kinds.add("postgres");
|
|
1773
|
+
} else if (dbUrl !== void 0 && SQLITE_URL_SCHEMES.test(dbUrl)) {
|
|
1774
|
+
kinds.add("sqlite");
|
|
1775
|
+
}
|
|
1776
|
+
if (setEnv(e.TURSO_DATABASE_URL) !== void 0) kinds.add("turso");
|
|
1777
|
+
if (kinds.size > 1) {
|
|
1778
|
+
fail(`ambiguous database configuration: ${[...kinds].join(" + ")} env vars are both set \u2014 set DB_DRIVER (or pass explicit flags) to choose`);
|
|
1779
|
+
}
|
|
1780
|
+
return kinds.values().next().value ?? "sqlite";
|
|
1781
|
+
}
|
|
1782
|
+
function resolveDatabaseConfig(options = {}, env) {
|
|
1783
|
+
const e = env ?? { ...loadCliEnvironment(options.envFile), ...process.env };
|
|
1784
|
+
const driverFlag = options.dbDriver;
|
|
1785
|
+
if (driverFlag !== void 0 && !isBackend(driverFlag)) {
|
|
1786
|
+
fail(`--db-driver must be sqlite|postgres|turso, got ${JSON.stringify(driverFlag)}`);
|
|
1787
|
+
}
|
|
1788
|
+
const pinned = [];
|
|
1789
|
+
if (options.db !== void 0) pinned.push(["--db", "sqlite"]);
|
|
1790
|
+
if (driverFlag !== void 0) pinned.push([`--db-driver ${driverFlag}`, driverFlag]);
|
|
1791
|
+
if (options.tursoUrl !== void 0) pinned.push(["--turso-url", "turso"]);
|
|
1792
|
+
if (options.tursoAuthToken !== void 0) pinned.push(["--turso-auth-token", "turso"]);
|
|
1793
|
+
if (PG_FLAG_KEYS.some((k) => options[k] !== void 0)) pinned.push(["--postgres-*", "postgres"]);
|
|
1794
|
+
const kinds = new Set(pinned.map(([, kind]) => kind));
|
|
1795
|
+
if (kinds.size > 1) {
|
|
1796
|
+
fail(`conflicting database selectors: ${pinned.map(([flag, kind]) => `${flag} (${kind})`).join(", ")}`);
|
|
1797
|
+
}
|
|
1798
|
+
if (options.databaseUrl !== void 0) {
|
|
1799
|
+
if (options.db !== void 0) fail("conflicting database selectors: --db and --database-url are both set");
|
|
1800
|
+
if (options.tursoUrl !== void 0) fail("conflicting database selectors: --turso-url and --database-url are both set");
|
|
1801
|
+
if (PG_FLAG_KEYS.some((k) => options[k] !== void 0)) {
|
|
1802
|
+
fail("conflicting database selectors: --database-url and --postgres-* flags are both set");
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
let backend;
|
|
1806
|
+
if (pinned.length > 0) {
|
|
1807
|
+
backend = pinned[0][1];
|
|
1808
|
+
} else {
|
|
1809
|
+
const envDriver = setEnv(e.DB_DRIVER);
|
|
1810
|
+
if (envDriver !== void 0) {
|
|
1811
|
+
if (!isBackend(envDriver)) {
|
|
1812
|
+
fail(`Unsupported DB_DRIVER: ${envDriver} (expected sqlite|turso|postgres)`);
|
|
1738
1813
|
}
|
|
1739
|
-
|
|
1814
|
+
backend = envDriver;
|
|
1815
|
+
} else {
|
|
1816
|
+
backend = envBackend(e);
|
|
1740
1817
|
}
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
return { note };
|
|
1752
|
-
}
|
|
1753
|
-
async function getSessionBundle(db, resultId) {
|
|
1754
|
-
const sql = await loadSql();
|
|
1755
|
-
const session = await sql.getRow(db, sql.storeDefinition("sessions"), resultId);
|
|
1756
|
-
if (!session) return void 0;
|
|
1757
|
-
const events = await sql.listRows(db, sql.storeDefinition("events"), { only: resultId }, void 0, "by-result-grain");
|
|
1758
|
-
return { session, events };
|
|
1759
|
-
}
|
|
1760
|
-
async function getEffortBySlug(db, slug) {
|
|
1761
|
-
const sql = await loadSql();
|
|
1762
|
-
const efforts = await allRows(sql, db, "efforts");
|
|
1763
|
-
return efforts.find((e) => e.slug === slug);
|
|
1764
|
-
}
|
|
1765
|
-
async function listTagsByType(db, type) {
|
|
1766
|
-
const sql = await loadSql();
|
|
1767
|
-
const tags = await allRows(sql, db, "tags");
|
|
1768
|
-
return tags.filter((t) => t.type === type);
|
|
1818
|
+
}
|
|
1819
|
+
const databaseUrl = options.databaseUrl ?? setEnv(e.DATABASE_URL);
|
|
1820
|
+
switch (backend) {
|
|
1821
|
+
case "postgres":
|
|
1822
|
+
return resolvePostgres(options, e, databaseUrl);
|
|
1823
|
+
case "turso":
|
|
1824
|
+
return resolveTurso(options, e, databaseUrl);
|
|
1825
|
+
case "sqlite":
|
|
1826
|
+
return resolveSqlite(options, e, databaseUrl);
|
|
1827
|
+
}
|
|
1769
1828
|
}
|
|
1770
1829
|
var registeredWidgets = KNOWN_SECTION_WIDGETS;
|
|
1771
1830
|
var saveStores = ["notes", "block_revisions", "block_index", "block_efforts", "tags", "note_tags", "sessions"];
|
|
@@ -2103,16 +2162,53 @@ ${source}
|
|
|
2103
2162
|
${fence}
|
|
2104
2163
|
`;
|
|
2105
2164
|
}
|
|
2165
|
+
var VALUE_FLAGS = [
|
|
2166
|
+
["--db", "db"],
|
|
2167
|
+
["--db-driver", "dbDriver"],
|
|
2168
|
+
["--database-url", "databaseUrl"],
|
|
2169
|
+
["--postgres-host", "postgresHost"],
|
|
2170
|
+
["--postgres-port", "postgresPort"],
|
|
2171
|
+
["--postgres-user", "postgresUser"],
|
|
2172
|
+
["--postgres-password", "postgresPassword"],
|
|
2173
|
+
["--postgres-database", "postgresDatabase"],
|
|
2174
|
+
["--postgres-ssl", "postgresSsl"],
|
|
2175
|
+
["--turso-url", "tursoUrl"],
|
|
2176
|
+
["--turso-auth-token", "tursoAuthToken"],
|
|
2177
|
+
["--env-file", "envFile"],
|
|
2178
|
+
["--host", "host"],
|
|
2179
|
+
["--port", "port"],
|
|
2180
|
+
["--dist", "dist"]
|
|
2181
|
+
];
|
|
2182
|
+
function readValueFlag(args, i, flag) {
|
|
2183
|
+
const inline = args[i].startsWith(`${flag}=`);
|
|
2184
|
+
if (inline) {
|
|
2185
|
+
const value2 = args[i].slice(flag.length + 1);
|
|
2186
|
+
if (!value2) throw new Error(`Missing value for ${flag}`);
|
|
2187
|
+
return { value: value2, next: i + 1 };
|
|
2188
|
+
}
|
|
2189
|
+
const value = args[i + 1];
|
|
2190
|
+
if (value === void 0 || value === "" || value.startsWith("--")) throw new Error(`Missing value for ${flag}`);
|
|
2191
|
+
return { value, next: i + 2 };
|
|
2192
|
+
}
|
|
2106
2193
|
function parseCliArgs(args) {
|
|
2107
2194
|
const result = {
|
|
2108
2195
|
format: "json",
|
|
2109
2196
|
packs: [],
|
|
2110
2197
|
sources: []
|
|
2111
2198
|
};
|
|
2199
|
+
const valueArgs = result;
|
|
2112
2200
|
let i = 0;
|
|
2113
2201
|
while (i < args.length) {
|
|
2114
2202
|
const arg = args[i];
|
|
2115
2203
|
if (arg === "--at" || arg.startsWith("--at=")) throw new Error("Unknown option --at; whole Note exports have no as-of version");
|
|
2204
|
+
const valueFlag = VALUE_FLAGS.find(([flag]) => arg === flag || arg.startsWith(`${flag}=`));
|
|
2205
|
+
if (valueFlag) {
|
|
2206
|
+
const [flag, key] = valueFlag;
|
|
2207
|
+
const { value, next } = readValueFlag(args, i, flag);
|
|
2208
|
+
valueArgs[key] = value;
|
|
2209
|
+
i = next;
|
|
2210
|
+
continue;
|
|
2211
|
+
}
|
|
2116
2212
|
if (arg === "--help" || arg === "-h") {
|
|
2117
2213
|
result.help = true;
|
|
2118
2214
|
i++;
|
|
@@ -2159,12 +2255,6 @@ function parseCliArgs(args) {
|
|
|
2159
2255
|
} else if (arg === "--unit") {
|
|
2160
2256
|
result.unit = args[++i];
|
|
2161
2257
|
i++;
|
|
2162
|
-
} else if (arg === "--db") {
|
|
2163
|
-
result.db = args[++i];
|
|
2164
|
-
i++;
|
|
2165
|
-
} else if (arg.startsWith("--db=")) {
|
|
2166
|
-
result.db = arg.slice("--db=".length);
|
|
2167
|
-
i++;
|
|
2168
2258
|
} else if (arg === "--debug") {
|
|
2169
2259
|
result.debug = "";
|
|
2170
2260
|
i++;
|
|
@@ -2200,7 +2290,7 @@ function parseCliArgs(args) {
|
|
|
2200
2290
|
result.dir = arg.slice("--dir=".length);
|
|
2201
2291
|
i++;
|
|
2202
2292
|
} else if (!result.subcommand) {
|
|
2203
|
-
if (arg === "parse" || arg === "run" || arg === "query" || arg === "download" || arg === "import" || arg === "build" || arg === "seed" || arg === "reset" || arg === "help" || arg === "version") {
|
|
2293
|
+
if (arg === "parse" || arg === "run" || arg === "query" || arg === "download" || arg === "import" || arg === "build" || arg === "seed" || arg === "reset" || arg === "init" || arg === "server" || arg === "serve" || arg === "playground" || arg === "help" || arg === "version") {
|
|
2204
2294
|
result.subcommand = arg;
|
|
2205
2295
|
} else {
|
|
2206
2296
|
result.target = arg;
|
|
@@ -2216,6 +2306,11 @@ function parseCliArgs(args) {
|
|
|
2216
2306
|
i++;
|
|
2217
2307
|
}
|
|
2218
2308
|
}
|
|
2309
|
+
for (const [flag, value] of [["--port", result.port], ["--postgres-port", result.postgresPort]]) {
|
|
2310
|
+
if (value !== void 0 && (!/^\d+$/.test(value) || Number(value) < 1 || Number(value) > 65535)) {
|
|
2311
|
+
throw new Error(`Invalid value for ${flag}: "${value}" is not a TCP port (1-65535)`);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2219
2314
|
return result;
|
|
2220
2315
|
}
|
|
2221
2316
|
function readBunStdinText() {
|
|
@@ -2261,6 +2356,11 @@ USAGE:
|
|
|
2261
2356
|
wod build [dir] [options]
|
|
2262
2357
|
wod seed [options]
|
|
2263
2358
|
wod reset [options]
|
|
2359
|
+
wod init Initialize the configured database (idempotent)
|
|
2360
|
+
wod server [options]
|
|
2361
|
+
Serve the app (HTTP API + packaged frontend; alias: serve)
|
|
2362
|
+
wod playground [options]
|
|
2363
|
+
Serve the local playground (browser IndexedDB build)
|
|
2264
2364
|
|
|
2265
2365
|
SUBCOMMANDS:
|
|
2266
2366
|
parse <file | -> Parse Whiteboard Script, create a note in the database
|
|
@@ -2314,9 +2414,47 @@ INPUT SOURCING (for 'query'; without these, the database is queried):
|
|
|
2314
2414
|
--stdin-log Read kind: 'execution-log' JSON payload from stdin
|
|
2315
2415
|
--stdin-facts Read raw kind: 'fact-set' JSON payload from stdin
|
|
2316
2416
|
|
|
2317
|
-
DATABASE (parse / run / query / download / import / seed / reset):
|
|
2318
|
-
|
|
2319
|
-
|
|
2417
|
+
DATABASE (init / parse / run / query / download / import / seed / reset / server):
|
|
2418
|
+
Pick one backend; explicit flags win over the process environment, the
|
|
2419
|
+
process environment wins over .env files. Run 'wod init' once first: it
|
|
2420
|
+
creates the SQLite file + schema, creates the PostgreSQL database when
|
|
2421
|
+
your role is authorized to (otherwise use an existing/provisioned one),
|
|
2422
|
+
or installs the schema in your provisioned Turso database \u2014 idempotently,
|
|
2423
|
+
preserving existing notes. 'wod server' refuses an uninitialized database.
|
|
2424
|
+
--db <path> Local SQLite database file (default: $WOD_WIKI_DB
|
|
2425
|
+
or ./wodwiki.db). Passing --db always selects SQLite,
|
|
2426
|
+
even when the environment names a remote backend.
|
|
2427
|
+
Created on demand by parse/run/seed.
|
|
2428
|
+
--db-driver <name> Backend driver: sqlite (default), postgres, or
|
|
2429
|
+
turso ($DB_DRIVER)
|
|
2430
|
+
--database-url <url> Database connection URL ($DATABASE_URL); accepts
|
|
2431
|
+
PostgreSQL, local SQLite, and remote libSQL URLs.
|
|
2432
|
+
--postgres-host <host> PostgreSQL host ($POSTGRES_HOST)
|
|
2433
|
+
--postgres-port <port> PostgreSQL port ($POSTGRES_PORT)
|
|
2434
|
+
--postgres-user <user> PostgreSQL user ($POSTGRES_USER)
|
|
2435
|
+
--postgres-password <pw> PostgreSQL password ($POSTGRES_PASSWORD)
|
|
2436
|
+
--postgres-database <db> PostgreSQL database name ($POSTGRES_DATABASE)
|
|
2437
|
+
--postgres-ssl <mode> PostgreSQL SSL mode, e.g. disable/prefer/require
|
|
2438
|
+
($POSTGRES_SSL)
|
|
2439
|
+
--turso-url <url> Turso/libSQL database URL (libsql://\u2026). The
|
|
2440
|
+
hosted database must already exist (provisioned on
|
|
2441
|
+
Turso); only its schema is installed.
|
|
2442
|
+
--turso-auth-token <token> Turso authentication token (never printed)
|
|
2443
|
+
--env-file <path> Load variables from this file; a missing file is
|
|
2444
|
+
an error. Without it: ./.env when present, otherwise
|
|
2445
|
+
the workspace-root .env. Credentials are never logged.
|
|
2446
|
+
|
|
2447
|
+
HOSTING (for 'server' / 'playground'; requires the Bun runtime):
|
|
2448
|
+
server HTTP API over the configured database plus the frontend
|
|
2449
|
+
packaged inside the engine module. Requires an
|
|
2450
|
+
initialized database. ('serve' is an accepted alias.)
|
|
2451
|
+
playground Serves the playground app backed by browser IndexedDB;
|
|
2452
|
+
the configured database is not touched.
|
|
2453
|
+
--host <host> Bind address (default 127.0.0.1, $HOST)
|
|
2454
|
+
--port <port> TCP port (default 3000, $PORT)
|
|
2455
|
+
--dist <dir> Serve this prebuilt frontend directory instead of the
|
|
2456
|
+
packaged one ($PLAYGROUND_DIST); must already contain
|
|
2457
|
+
index.html.
|
|
2320
2458
|
|
|
2321
2459
|
SEED SOURCING (for 'seed'):
|
|
2322
2460
|
--source <dir> Extra compiled seed directory (manifest.json + chunks);
|
|
@@ -2336,6 +2474,15 @@ OPTIONS:
|
|
|
2336
2474
|
-h, --help Show help message
|
|
2337
2475
|
-v, --version Show version number
|
|
2338
2476
|
|
|
2477
|
+
ENVIRONMENT (flags > process env > .env):
|
|
2478
|
+
WOD_WIKI_DB, SQLITE_PATH SQLite file path
|
|
2479
|
+
DB_DRIVER sqlite | postgres | turso
|
|
2480
|
+
DATABASE_URL PostgreSQL connection URL
|
|
2481
|
+
POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER,
|
|
2482
|
+
POSTGRES_PASSWORD, POSTGRES_DATABASE, POSTGRES_SSL
|
|
2483
|
+
TURSO_DATABASE_URL, TURSO_AUTH_TOKEN, LIBSQL_AUTH_TOKEN
|
|
2484
|
+
HOST, PORT, PLAYGROUND_DIST server / playground defaults
|
|
2485
|
+
|
|
2339
2486
|
EXIT CODES:
|
|
2340
2487
|
0 - OK / Success
|
|
2341
2488
|
1 - General / Runtime error
|
|
@@ -2355,6 +2502,10 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2355
2502
|
const writeOut = io.stdout ?? ((t) => process.stdout.write(t + "\n"));
|
|
2356
2503
|
const writeErr = io.stderr ?? ((t) => process.stderr.write(t + "\n"));
|
|
2357
2504
|
const getStdin = io.readStdinFn ?? readStdin;
|
|
2505
|
+
let envLoaded;
|
|
2506
|
+
const cliEnv = () => envLoaded ??= { ...loadCliEnvironment(parsed.envFile), ...process.env };
|
|
2507
|
+
let dbResolved;
|
|
2508
|
+
const cliDb = () => dbResolved ??= resolveDatabaseConfig(parsed, cliEnv());
|
|
2358
2509
|
let parsed;
|
|
2359
2510
|
try {
|
|
2360
2511
|
parsed = parseCliArgs(argv);
|
|
@@ -2421,7 +2572,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2421
2572
|
const ir = runParse(source, { sport: parsed.sport, sourceLabel: `cli:wod parse ${parsed.target}` });
|
|
2422
2573
|
const identity = extractNoteIdentity(source);
|
|
2423
2574
|
const tags = extractTypedTags(source);
|
|
2424
|
-
const db = await openCliDb(
|
|
2575
|
+
const db = await openCliDb(cliDb());
|
|
2425
2576
|
try {
|
|
2426
2577
|
const persisted = await persistNote(db, {
|
|
2427
2578
|
source: noteSource,
|
|
@@ -2460,7 +2611,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2460
2611
|
source = fs.readFileSync(parsed.target, "utf-8");
|
|
2461
2612
|
}
|
|
2462
2613
|
const identity = extractNoteIdentity(source);
|
|
2463
|
-
const db = await openCliDb(
|
|
2614
|
+
const db = await openCliDb(cliDb());
|
|
2464
2615
|
let ir;
|
|
2465
2616
|
try {
|
|
2466
2617
|
const started = await startRun(db, {
|
|
@@ -2511,14 +2662,14 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2511
2662
|
}
|
|
2512
2663
|
let ir;
|
|
2513
2664
|
if (useDb) {
|
|
2514
|
-
const
|
|
2515
|
-
if (!nodeFs().existsSync(
|
|
2665
|
+
const config = cliDb();
|
|
2666
|
+
if (config.kind === "sqlite" && !nodeFs().existsSync(config.path)) {
|
|
2516
2667
|
writeErr(
|
|
2517
|
-
`[wod query] No input dataset and no database at ${
|
|
2668
|
+
`[wod query] No input dataset and no database at ${config.path}. Specify --corpus <file>, --stdin-log, --stdin-facts, or run \`wod seed\` first.`
|
|
2518
2669
|
);
|
|
2519
2670
|
return 1;
|
|
2520
2671
|
}
|
|
2521
|
-
const db = await openCliDb(
|
|
2672
|
+
const db = await openCliDb(config, config.kind === "sqlite" ? void 0 : { initialize: false });
|
|
2522
2673
|
try {
|
|
2523
2674
|
ir = await runQueryCli(parsed.target, {
|
|
2524
2675
|
preferredUnit: parsed.unit,
|
|
@@ -2564,7 +2715,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2564
2715
|
return 1;
|
|
2565
2716
|
}
|
|
2566
2717
|
const targetId = id;
|
|
2567
|
-
const db = await openCliDb(
|
|
2718
|
+
const db = await openCliDb(cliDb());
|
|
2568
2719
|
try {
|
|
2569
2720
|
if (kind === "note") {
|
|
2570
2721
|
const bundle = await getNoteBundle(db.db, targetId);
|
|
@@ -2641,7 +2792,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2641
2792
|
const source = fs.readFileSync(file, "utf-8");
|
|
2642
2793
|
const identity = extractNoteIdentity(source);
|
|
2643
2794
|
const tags = extractTypedTags(source);
|
|
2644
|
-
const db2 = await openCliDb(
|
|
2795
|
+
const db2 = await openCliDb(cliDb());
|
|
2645
2796
|
try {
|
|
2646
2797
|
const persisted = await persistNote(db2, {
|
|
2647
2798
|
source,
|
|
@@ -2664,7 +2815,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2664
2815
|
writeErr(`[wod import] Unparseable effort file (need frontmatter id/slug/label + numeric baseAttributes.met): ${file}`);
|
|
2665
2816
|
return 1;
|
|
2666
2817
|
}
|
|
2667
|
-
const db2 = await openCliDb(
|
|
2818
|
+
const db2 = await openCliDb(cliDb());
|
|
2668
2819
|
try {
|
|
2669
2820
|
await persistEffort(db2, { ...effort, registrySource: "user" });
|
|
2670
2821
|
writeOut(`[wod import] effort ${effort.slug} \u2014 ${effort.label} \u2192 ${db2.path}`);
|
|
@@ -2679,7 +2830,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2679
2830
|
writeErr(`[wod import] No equipment labels found in ${file}`);
|
|
2680
2831
|
return 1;
|
|
2681
2832
|
}
|
|
2682
|
-
const db2 = await openCliDb(
|
|
2833
|
+
const db2 = await openCliDb(cliDb());
|
|
2683
2834
|
try {
|
|
2684
2835
|
const added = await persistTypedTags(db2, labels, "equipment");
|
|
2685
2836
|
writeOut(`[wod import] equipment \u2014 ${labels.length} labels (${added} new) \u2192 ${db2.path}`);
|
|
@@ -2689,7 +2840,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2689
2840
|
return 0;
|
|
2690
2841
|
}
|
|
2691
2842
|
const { session, events } = csvToSessionRows(fs.readFileSync(file, "utf-8"));
|
|
2692
|
-
const db = await openCliDb(
|
|
2843
|
+
const db = await openCliDb(cliDb());
|
|
2693
2844
|
try {
|
|
2694
2845
|
const result = await persistSessionBundle(db, session, events);
|
|
2695
2846
|
writeOut(
|
|
@@ -2707,7 +2858,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2707
2858
|
writeErr(`[wod build] No markdown/ corpus under ${root} \u2014 run from the content repo root (or pass its directory).`);
|
|
2708
2859
|
return 1;
|
|
2709
2860
|
}
|
|
2710
|
-
const { generateSeed } = await import('./compiler-
|
|
2861
|
+
const { generateSeed } = await import('./compiler-NODHKWJJ.mjs');
|
|
2711
2862
|
try {
|
|
2712
2863
|
const result = generateSeed({
|
|
2713
2864
|
corpusRoot: root,
|
|
@@ -2736,7 +2887,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2736
2887
|
);
|
|
2737
2888
|
return 1;
|
|
2738
2889
|
}
|
|
2739
|
-
const db = await openCliDb(
|
|
2890
|
+
const db = await openCliDb(cliDb());
|
|
2740
2891
|
try {
|
|
2741
2892
|
for (const dir of dirs) {
|
|
2742
2893
|
const summary = await importSeedDir(db, dir, "");
|
|
@@ -2750,7 +2901,14 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2750
2901
|
return 0;
|
|
2751
2902
|
}
|
|
2752
2903
|
if (parsed.subcommand === "reset") {
|
|
2753
|
-
const
|
|
2904
|
+
const config = cliDb();
|
|
2905
|
+
if (config.kind !== "sqlite") {
|
|
2906
|
+
writeErr(
|
|
2907
|
+
`[wod reset] refusing to reset the configured ${config.kind} database \u2014 reset only removes a local SQLite file. Clear remote databases through their provider.`
|
|
2908
|
+
);
|
|
2909
|
+
return 1;
|
|
2910
|
+
}
|
|
2911
|
+
const target = config.path;
|
|
2754
2912
|
if (nodeFs().existsSync(target)) {
|
|
2755
2913
|
nodeFs().unlinkSync(target);
|
|
2756
2914
|
writeOut(`[wod reset] removed ${target}`);
|
|
@@ -2759,6 +2917,32 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2759
2917
|
}
|
|
2760
2918
|
return 0;
|
|
2761
2919
|
}
|
|
2920
|
+
if (parsed.subcommand === "init") {
|
|
2921
|
+
const db = await openCliDb(cliDb(), { create: true });
|
|
2922
|
+
try {
|
|
2923
|
+
writeOut(`[wod init] database ready at ${db.path}`);
|
|
2924
|
+
} finally {
|
|
2925
|
+
await db.close();
|
|
2926
|
+
}
|
|
2927
|
+
return 0;
|
|
2928
|
+
}
|
|
2929
|
+
if (parsed.subcommand === "server" || parsed.subcommand === "serve" || parsed.subcommand === "playground") {
|
|
2930
|
+
if (!("Bun" in globalThis)) {
|
|
2931
|
+
writeErr(
|
|
2932
|
+
`[wod ${parsed.subcommand}] Error: hosting requires the Bun runtime (https://bun.sh) \u2014 run \`bun wod server\` / \`bun wod playground\`.`
|
|
2933
|
+
);
|
|
2934
|
+
return 1;
|
|
2935
|
+
}
|
|
2936
|
+
const mode = parsed.subcommand === "playground" ? "playground" : "server";
|
|
2937
|
+
const { runCliServer } = await import('./server-4P6AJAGT.mjs');
|
|
2938
|
+
const options = { env: cliEnv() };
|
|
2939
|
+
if (mode === "server") options.database = cliDb();
|
|
2940
|
+
if (parsed.host !== void 0) options.host = parsed.host;
|
|
2941
|
+
if (parsed.port !== void 0) options.port = parsed.port;
|
|
2942
|
+
if (parsed.dist !== void 0) options.dist = parsed.dist;
|
|
2943
|
+
await runCliServer(mode, options, writeOut);
|
|
2944
|
+
return 0;
|
|
2945
|
+
}
|
|
2762
2946
|
writeErr(`[wod] Unknown subcommand "${parsed.subcommand}"`);
|
|
2763
2947
|
return 1;
|
|
2764
2948
|
} catch (error) {
|
|
@@ -2776,5 +2960,5 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
2776
2960
|
}
|
|
2777
2961
|
|
|
2778
2962
|
export { NOTE_ID_FRONTMATTER_KEY, PackLoadError, ParseSyntaxError, SESSION_CSV_HEADER, WqlSyntaxError, applySeedChunk, assertSeedManifest, assertSeedRows, buildStatementTree, buildWorkoutResults, cliMain, composeNoteMarkdown, createIRFile, csvToEquipmentLabels, csvToSessionRows, defineLanguagePack, effortToMarkdown, equipmentToCsv, extractNoteIdentity, extractTypedTags, formatExecutionOutput, formatParseOutput, formatQueryOutput, getRegisteredLanguagePacks, inMemoryEventStore, injectIdentityFrontmatter, isIRFile, listLanguagePacks, loadLanguagePack, loadQueryData, markdownToEffort, parseCliArgs, parseCsvLine, readFrontmatterMeta, readStdin, registerLanguagePack, runExecution, runParse, runQueryCli, seedNoteId, sessionToCsv, splitCsvRecords, statementToNode, unregisterLanguagePack };
|
|
2779
|
-
//# sourceMappingURL=chunk-
|
|
2780
|
-
//# sourceMappingURL=chunk-
|
|
2963
|
+
//# sourceMappingURL=chunk-UKBQ36RW.mjs.map
|
|
2964
|
+
//# sourceMappingURL=chunk-UKBQ36RW.mjs.map
|