@bitcobblers/wod-wiki-tools 0.37.2137 → 0.37.2140
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 +224 -231
- package/dist/bin/wod.cjs.map +1 -1
- package/dist/bin/wod.mjs +4 -4
- package/dist/{chunk-NATJMTAW.mjs → chunk-IEW74LUO.mjs} +109 -187
- package/dist/chunk-IEW74LUO.mjs.map +1 -0
- package/dist/{chunk-CYKNTEGY.mjs → chunk-IWT7U3WX.mjs} +8 -3
- package/dist/chunk-IWT7U3WX.mjs.map +1 -0
- package/dist/{chunk-MA6BBTWC.mjs → chunk-RWNL6APX.mjs} +3 -3
- package/dist/{chunk-MA6BBTWC.mjs.map → chunk-RWNL6APX.mjs.map} +1 -1
- package/dist/{chunk-GBBJBDLS.mjs → chunk-UNJ6OZVO.mjs} +116 -42
- package/dist/chunk-UNJ6OZVO.mjs.map +1 -0
- package/dist/{chunk-SQAI6B4P.mjs → chunk-YO256WSO.mjs} +3 -3
- package/dist/chunk-YO256WSO.mjs.map +1 -0
- package/dist/compiler-E6HYL477.mjs +9 -0
- package/dist/{compiler-B77PITYH.mjs.map → compiler-E6HYL477.mjs.map} +1 -1
- package/dist/index.cjs +224 -231
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/{scaffoldCatalog-LQOUCJ4X.mjs → scaffoldCatalog-TLYSPOQK.mjs} +3 -3
- package/dist/{scaffoldCatalog-LQOUCJ4X.mjs.map → scaffoldCatalog-TLYSPOQK.mjs.map} +1 -1
- package/dist/{server-JXECWS4A.mjs → server-2DVBA35J.mjs} +4 -4
- package/dist/{server-JXECWS4A.mjs.map → server-2DVBA35J.mjs.map} +1 -1
- package/dist/web/playground/assets/main-BUcjhK2w.css +2 -0
- package/dist/web/playground/assets/main-CT3-Winw.js +194 -0
- package/dist/web/playground/assets/{statementBuilderFlow-BL8OKlcb.js → statementBuilderFlow-CtxxN_h0.js} +2 -2
- package/dist/web/playground/assets/{vendor-CTANVdPW.js → vendor-DaJxNU_W.js} +19 -19
- package/dist/web/playground/assets/{vendor-codemirror-BlXDdJID.js → vendor-codemirror-BtDM22HA.js} +8 -8
- package/dist/web/playground/index.html +4 -4
- package/dist/web/playground/seed/core/chunks/canvas.3c75c4cb.json +1 -0
- package/dist/web/playground/seed/core/chunks/efforts.1422c1a6.json +1 -0
- package/dist/web/playground/seed/core/chunks/equipment.c4fb1d64.json +1 -0
- package/dist/web/playground/seed/core/chunks/{template.e5e0e82d.json → template.0120276c.json} +1 -1
- package/dist/web/playground/seed/core/manifest.json +24 -10
- package/dist/web/playground/seed/core/report.html +15 -13
- package/dist/web/server/assets/main-BUcjhK2w.css +2 -0
- package/dist/web/server/assets/main-C5jPewkG.js +193 -0
- package/dist/web/server/assets/{statementBuilderFlow-xqsK_3T8.js → statementBuilderFlow-Df5Scxwh.js} +2 -2
- package/dist/web/server/assets/{vendor-CTANVdPW.js → vendor-DaJxNU_W.js} +19 -19
- package/dist/web/server/assets/{vendor-codemirror-BlXDdJID.js → vendor-codemirror-BtDM22HA.js} +8 -8
- package/dist/web/server/index.html +4 -4
- package/dist/web/server/seed/core/chunks/canvas.3c75c4cb.json +1 -0
- package/dist/web/server/seed/core/chunks/efforts.1422c1a6.json +1 -0
- package/dist/web/server/seed/core/chunks/equipment.c4fb1d64.json +1 -0
- package/dist/web/server/seed/core/chunks/{template.e5e0e82d.json → template.0120276c.json} +1 -1
- package/dist/web/server/seed/core/manifest.json +24 -10
- package/dist/web/server/seed/core/report.html +15 -13
- package/package.json +6 -6
- package/dist/chunk-CYKNTEGY.mjs.map +0 -1
- package/dist/chunk-GBBJBDLS.mjs.map +0 -1
- package/dist/chunk-NATJMTAW.mjs.map +0 -1
- package/dist/chunk-SQAI6B4P.mjs.map +0 -1
- package/dist/compiler-B77PITYH.mjs +0 -9
- package/dist/web/playground/assets/main-CFDrblxn.css +0 -2
- package/dist/web/playground/assets/main-OGIV1avF.js +0 -188
- package/dist/web/playground/seed/core/chunks/canvas.a2e32d8c.json +0 -1
- package/dist/web/server/assets/main-BdUrlkaF.js +0 -187
- package/dist/web/server/assets/main-CFDrblxn.css +0 -2
- package/dist/web/server/seed/core/chunks/canvas.a2e32d8c.json +0 -1
package/dist/bin/wod.cjs
CHANGED
|
@@ -267,6 +267,11 @@ async function getEffortBySlug(db, slug) {
|
|
|
267
267
|
const efforts = await allRows(sql, db, "efforts");
|
|
268
268
|
return efforts.find((e) => e.slug === slug);
|
|
269
269
|
}
|
|
270
|
+
async function getEquipmentBySlug(db, slug) {
|
|
271
|
+
const sql = await loadSql();
|
|
272
|
+
const equipment = await allRows(sql, db, "equipment");
|
|
273
|
+
return equipment.find((e) => e.slug === slug);
|
|
274
|
+
}
|
|
270
275
|
async function listTagsByType(db, type) {
|
|
271
276
|
const sql = await loadSql();
|
|
272
277
|
const tags = await allRows(sql, db, "tags");
|
|
@@ -297,6 +302,7 @@ function seedNoteSourceId(path, content, chunkId) {
|
|
|
297
302
|
if (chunkId === CANVAS_CHUNK_ID2) return `guides:${canvasRouteSlug(content) ?? under}`;
|
|
298
303
|
if (chunkId === DASHBOARDS_CHUNK_ID) return "dashboards";
|
|
299
304
|
if (chunkId === EFFORTS_CHUNK_ID) return "efforts";
|
|
305
|
+
if (chunkId === EQUIPMENT_CHUNK_ID) return "equipment";
|
|
300
306
|
if (chunkId === TEMPLATE_CHUNK_ID) return "playground";
|
|
301
307
|
if (chunkId.startsWith("collection.")) {
|
|
302
308
|
const catalog = catalogForChunkId(chunkId);
|
|
@@ -305,40 +311,19 @@ function seedNoteSourceId(path, content, chunkId) {
|
|
|
305
311
|
if (chunkId.startsWith("feed.")) return `feed:feeds/${under}`;
|
|
306
312
|
return void 0;
|
|
307
313
|
}
|
|
308
|
-
var SEED_SCHEMA2, SEED_REGISTERED_WIDGETS, EFFORTS_CHUNK_ID, CANVAS_CHUNK_ID2, DASHBOARDS_CHUNK_ID, TEMPLATE_CHUNK_ID;
|
|
314
|
+
var SEED_SCHEMA2, SEED_REGISTERED_WIDGETS, EFFORTS_CHUNK_ID, EQUIPMENT_CHUNK_ID, CANVAS_CHUNK_ID2, DASHBOARDS_CHUNK_ID, TEMPLATE_CHUNK_ID;
|
|
309
315
|
var init_contract = __esm({
|
|
310
316
|
"src/seedbuild/contract.ts"() {
|
|
311
|
-
SEED_SCHEMA2 =
|
|
317
|
+
SEED_SCHEMA2 = 9;
|
|
312
318
|
SEED_REGISTERED_WIDGETS = wodWikiCore.KNOWN_SECTION_WIDGETS;
|
|
313
319
|
EFFORTS_CHUNK_ID = "efforts";
|
|
320
|
+
EQUIPMENT_CHUNK_ID = "equipment";
|
|
314
321
|
CANVAS_CHUNK_ID2 = "canvas";
|
|
315
322
|
DASHBOARDS_CHUNK_ID = "dashboards";
|
|
316
323
|
TEMPLATE_CHUNK_ID = "template";
|
|
317
324
|
}
|
|
318
325
|
});
|
|
319
326
|
|
|
320
|
-
// src/seedbuild/effort-slugs.ts
|
|
321
|
-
function extractEffortSlugs2(statements) {
|
|
322
|
-
const slugs = /* @__PURE__ */ new Set();
|
|
323
|
-
for (const statement of statements) {
|
|
324
|
-
if (statement.exerciseId) {
|
|
325
|
-
slugs.add(statement.exerciseId);
|
|
326
|
-
} else {
|
|
327
|
-
const effortMetric = statement.metrics?.getMetric?.("effort");
|
|
328
|
-
const effort = effortMetric && typeof effortMetric.value === "string" ? effortMetric.value : void 0;
|
|
329
|
-
if (effort) {
|
|
330
|
-
const slug = effort.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
331
|
-
if (slug) slugs.add(slug);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return Array.from(slugs);
|
|
336
|
-
}
|
|
337
|
-
var init_effort_slugs = __esm({
|
|
338
|
-
"src/seedbuild/effort-slugs.ts"() {
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
|
|
342
327
|
// src/seedbuild/filename.ts
|
|
343
328
|
function fileToDisplayName(filename) {
|
|
344
329
|
const base = filename.replace(/\.md$/, "");
|
|
@@ -384,149 +369,6 @@ var init_filename = __esm({
|
|
|
384
369
|
};
|
|
385
370
|
}
|
|
386
371
|
});
|
|
387
|
-
|
|
388
|
-
// src/seedbuild/frontmatter.ts
|
|
389
|
-
function unquote(value) {
|
|
390
|
-
return value.replace(
|
|
391
|
-
/^(['"])(.*)\1$/,
|
|
392
|
-
(_match, quote, inner) => quote === '"' ? inner.replace(/\\(["\\])/g, "$1") : inner
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
function parseFrontmatter(raw) {
|
|
396
|
-
const match = raw.match(FRONTMATTER_RE);
|
|
397
|
-
if (!match) return { meta: {}, body: raw };
|
|
398
|
-
return { meta: parseMetaLines(match[1].split(/\r?\n/)), body: raw.slice(match[0].length) };
|
|
399
|
-
}
|
|
400
|
-
function parseMetaLines(lines) {
|
|
401
|
-
const meta = {};
|
|
402
|
-
for (let i = 0; i < lines.length; i++) {
|
|
403
|
-
const keyMatch = lines[i].match(/^([A-Za-z][\w.-]*)\s*:(.*)$/);
|
|
404
|
-
if (!keyMatch) continue;
|
|
405
|
-
const key = keyMatch[1];
|
|
406
|
-
const rawVal = keyMatch[2].trim();
|
|
407
|
-
if (rawVal === "") {
|
|
408
|
-
const items = [];
|
|
409
|
-
while (i + 1 < lines.length) {
|
|
410
|
-
const itemMatch = lines[i + 1].match(/^\s+-\s+(.+)$/);
|
|
411
|
-
if (!itemMatch) break;
|
|
412
|
-
items.push(itemMatch[1].trim());
|
|
413
|
-
i++;
|
|
414
|
-
}
|
|
415
|
-
meta[key] = items.length > 0 ? items : "";
|
|
416
|
-
} else {
|
|
417
|
-
const wasQuoted = /^(['"])(.*)\1$/.test(rawVal);
|
|
418
|
-
const value = unquote(rawVal);
|
|
419
|
-
const num = Number(value);
|
|
420
|
-
meta[key] = !wasQuoted && value !== "" && !isNaN(num) ? num : value;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return meta;
|
|
424
|
-
}
|
|
425
|
-
function getScalar(meta, key) {
|
|
426
|
-
const value = meta[key];
|
|
427
|
-
return typeof value === "string" || typeof value === "number" ? value : void 0;
|
|
428
|
-
}
|
|
429
|
-
function getList(meta, key) {
|
|
430
|
-
const value = meta[key];
|
|
431
|
-
return Array.isArray(value) ? value : [];
|
|
432
|
-
}
|
|
433
|
-
var FRONTMATTER_RE;
|
|
434
|
-
var init_frontmatter = __esm({
|
|
435
|
-
"src/seedbuild/frontmatter.ts"() {
|
|
436
|
-
FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
function parseDiscipline(val) {
|
|
440
|
-
if (!val) return void 0;
|
|
441
|
-
const normalized = unquoteYaml(val.trim()).toLowerCase();
|
|
442
|
-
if (wodWikiLang.isEffortDiscipline(normalized)) return normalized;
|
|
443
|
-
console.warn(`[effort-file] unknown discipline '${val}' \u2014 treating as unset`);
|
|
444
|
-
return void 0;
|
|
445
|
-
}
|
|
446
|
-
function unquoteYaml(val) {
|
|
447
|
-
if (val.startsWith('"') && val.endsWith('"')) {
|
|
448
|
-
return val.slice(1, -1).replace(/\\(["\\])/g, "$1");
|
|
449
|
-
}
|
|
450
|
-
if (val.startsWith("'") && val.endsWith("'")) {
|
|
451
|
-
return val.slice(1, -1).replace(/\\'/g, "'");
|
|
452
|
-
}
|
|
453
|
-
return val;
|
|
454
|
-
}
|
|
455
|
-
function coerceNestedScalar(raw) {
|
|
456
|
-
if (raw === "true") return true;
|
|
457
|
-
if (raw === "false") return false;
|
|
458
|
-
if (raw !== "" && !Number.isNaN(Number(raw))) return Number(raw);
|
|
459
|
-
return raw;
|
|
460
|
-
}
|
|
461
|
-
function readNestedSection(lines, key) {
|
|
462
|
-
const start = lines.findIndex((l) => new RegExp(`^${key}:\\s*$`).test(l));
|
|
463
|
-
if (start === -1) return void 0;
|
|
464
|
-
const result = {};
|
|
465
|
-
let subKey = null;
|
|
466
|
-
for (let i = start + 1; i < lines.length; i++) {
|
|
467
|
-
const line = lines[i];
|
|
468
|
-
if (/^\S/.test(line)) break;
|
|
469
|
-
const trimmed = line.trim();
|
|
470
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
471
|
-
const indent = line.length - line.trimStart().length;
|
|
472
|
-
const m = trimmed.match(/^([\w.-]+):\s*(.*)$/);
|
|
473
|
-
if (!m) continue;
|
|
474
|
-
const [, k, rawVal] = m;
|
|
475
|
-
if (indent === 2) {
|
|
476
|
-
if (rawVal === "") {
|
|
477
|
-
subKey = k;
|
|
478
|
-
result[k] = {};
|
|
479
|
-
} else {
|
|
480
|
-
subKey = null;
|
|
481
|
-
result[k] = coerceNestedScalar(rawVal);
|
|
482
|
-
}
|
|
483
|
-
} else if (indent >= 4 && subKey !== null) {
|
|
484
|
-
result[subKey][k] = coerceNestedScalar(rawVal);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return Object.keys(result).length > 0 ? result : void 0;
|
|
488
|
-
}
|
|
489
|
-
function parseEffortFile(raw) {
|
|
490
|
-
const blockMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
491
|
-
if (!blockMatch) return null;
|
|
492
|
-
const { meta, body } = parseFrontmatter(raw);
|
|
493
|
-
const innerLines = blockMatch[1].split(/\r?\n/);
|
|
494
|
-
const id = getScalar(meta, "id");
|
|
495
|
-
const slug = getScalar(meta, "slug");
|
|
496
|
-
const label = getScalar(meta, "label");
|
|
497
|
-
const aliases = getList(meta, "aliases");
|
|
498
|
-
const baseAttrs = readNestedSection(innerLines, "baseAttributes");
|
|
499
|
-
const hints = readNestedSection(innerLines, "hints");
|
|
500
|
-
const derivation = readNestedSection(innerLines, "derivation");
|
|
501
|
-
const metRaw = baseAttrs?.met;
|
|
502
|
-
const met = typeof metRaw === "number" ? metRaw : Number(metRaw);
|
|
503
|
-
if (!id || !slug || !label || metRaw === void 0 || Number.isNaN(met)) return null;
|
|
504
|
-
const discipline = parseDiscipline(
|
|
505
|
-
typeof baseAttrs?.discipline === "string" ? baseAttrs.discipline : void 0
|
|
506
|
-
);
|
|
507
|
-
const intensityTier = baseAttrs?.intensityTier;
|
|
508
|
-
const trimmedBody = body.trim();
|
|
509
|
-
return {
|
|
510
|
-
id: String(id),
|
|
511
|
-
slug: String(slug),
|
|
512
|
-
label: String(label),
|
|
513
|
-
aliases,
|
|
514
|
-
baseAttributes: {
|
|
515
|
-
met,
|
|
516
|
-
...discipline ? { discipline } : {},
|
|
517
|
-
...intensityTier ? { intensityTier } : {}
|
|
518
|
-
},
|
|
519
|
-
registrySource: "bundled",
|
|
520
|
-
...trimmedBody ? { body: trimmedBody } : {},
|
|
521
|
-
...hints ? { hints } : {},
|
|
522
|
-
...derivation ? { derivation } : {}
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
var init_effort_file = __esm({
|
|
526
|
-
"src/seedbuild/effort-file.ts"() {
|
|
527
|
-
init_frontmatter();
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
372
|
function resolveGitVersion(repoRoot) {
|
|
531
373
|
try {
|
|
532
374
|
const run = (args) => child_process.execSync(`git ${args}`, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
@@ -614,6 +456,54 @@ var init_report = __esm({
|
|
|
614
456
|
"src/seedbuild/report.ts"() {
|
|
615
457
|
}
|
|
616
458
|
});
|
|
459
|
+
|
|
460
|
+
// src/seedbuild/frontmatter.ts
|
|
461
|
+
function unquote(value) {
|
|
462
|
+
return value.replace(
|
|
463
|
+
/^(['"])(.*)\1$/,
|
|
464
|
+
(_match, quote, inner) => quote === '"' ? inner.replace(/\\(["\\])/g, "$1") : inner
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
function parseFrontmatter(raw) {
|
|
468
|
+
const match = raw.match(FRONTMATTER_RE);
|
|
469
|
+
if (!match) return { meta: {}, body: raw };
|
|
470
|
+
return { meta: parseMetaLines(match[1].split(/\r?\n/)), body: raw.slice(match[0].length) };
|
|
471
|
+
}
|
|
472
|
+
function parseMetaLines(lines) {
|
|
473
|
+
const meta = {};
|
|
474
|
+
for (let i = 0; i < lines.length; i++) {
|
|
475
|
+
const keyMatch = lines[i].match(/^([A-Za-z][\w.-]*)\s*:(.*)$/);
|
|
476
|
+
if (!keyMatch) continue;
|
|
477
|
+
const key = keyMatch[1];
|
|
478
|
+
const rawVal = keyMatch[2].trim();
|
|
479
|
+
if (rawVal === "") {
|
|
480
|
+
const items = [];
|
|
481
|
+
while (i + 1 < lines.length) {
|
|
482
|
+
const itemMatch = lines[i + 1].match(/^\s+-\s+(.+)$/);
|
|
483
|
+
if (!itemMatch) break;
|
|
484
|
+
items.push(itemMatch[1].trim());
|
|
485
|
+
i++;
|
|
486
|
+
}
|
|
487
|
+
meta[key] = items.length > 0 ? items : "";
|
|
488
|
+
} else {
|
|
489
|
+
const wasQuoted = /^(['"])(.*)\1$/.test(rawVal);
|
|
490
|
+
const value = unquote(rawVal);
|
|
491
|
+
const num = Number(value);
|
|
492
|
+
meta[key] = !wasQuoted && value !== "" && !isNaN(num) ? num : value;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return meta;
|
|
496
|
+
}
|
|
497
|
+
function getScalar(meta, key) {
|
|
498
|
+
const value = meta[key];
|
|
499
|
+
return typeof value === "string" || typeof value === "number" ? value : void 0;
|
|
500
|
+
}
|
|
501
|
+
var FRONTMATTER_RE;
|
|
502
|
+
var init_frontmatter = __esm({
|
|
503
|
+
"src/seedbuild/frontmatter.ts"() {
|
|
504
|
+
FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
505
|
+
}
|
|
506
|
+
});
|
|
617
507
|
function object(value) {
|
|
618
508
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
619
509
|
}
|
|
@@ -644,6 +534,7 @@ var init_validation = __esm({
|
|
|
644
534
|
var compiler_exports = {};
|
|
645
535
|
__export(compiler_exports, {
|
|
646
536
|
buildBlockEffortRows: () => buildBlockEffortRows,
|
|
537
|
+
buildBlockEquipmentRows: () => buildBlockEquipmentRows,
|
|
647
538
|
buildBlockIndexRows: () => buildBlockIndexRows,
|
|
648
539
|
chunkIdFor: () => chunkIdFor,
|
|
649
540
|
collectCorpusMarkdown: () => collectCorpusMarkdown,
|
|
@@ -652,7 +543,7 @@ __export(compiler_exports, {
|
|
|
652
543
|
feedDateToCreatedAt: () => feedDateToCreatedAt,
|
|
653
544
|
frontmatterDateToCreatedAt: () => frontmatterDateToCreatedAt,
|
|
654
545
|
generateSeed: () => generateSeed,
|
|
655
|
-
|
|
546
|
+
loadCorpusReferenceCatalog: () => loadCorpusReferenceCatalog,
|
|
656
547
|
partitionIntoChunks: () => partitionIntoChunks,
|
|
657
548
|
scaffoldDiscoveredEfforts: () => scaffoldDiscoveredEfforts,
|
|
658
549
|
validateDashboardNote: () => validateDashboardNote,
|
|
@@ -678,6 +569,7 @@ function chunkIdFor(relPath) {
|
|
|
678
569
|
case "canvas":
|
|
679
570
|
case "dashboards":
|
|
680
571
|
case "efforts":
|
|
572
|
+
case "equipment":
|
|
681
573
|
return corpus;
|
|
682
574
|
case "collections":
|
|
683
575
|
return parts.length === 3 ? `collection._root` : `collection.${slug}`;
|
|
@@ -696,7 +588,7 @@ function partitionIntoChunks(paths) {
|
|
|
696
588
|
const id = chunkIdFor(p);
|
|
697
589
|
if (id === null) {
|
|
698
590
|
throw new Error(
|
|
699
|
-
`[generate-seed] Parity failure: '${p}' is not part of any known corpus (canvas | dashboards | efforts | collections | feeds). Extend chunkIdFor() if this is a new corpus.`
|
|
591
|
+
`[generate-seed] Parity failure: '${p}' is not part of any known corpus (canvas | dashboards | efforts | equipment | collections | feeds). Extend chunkIdFor() if this is a new corpus.`
|
|
700
592
|
);
|
|
701
593
|
}
|
|
702
594
|
const list = byId.get(id);
|
|
@@ -778,7 +670,7 @@ function compileSeedRow(path, content, metadata = {}) {
|
|
|
778
670
|
const section = sections.find((section2) => section2.from === block.from && section2.to === block.to);
|
|
779
671
|
return { id: `${noteId}:${block.id}`, noteId, blockId: block.id, blockVersion: 1, sourceRevision: 1, from: block.from, to: block.to, position, dataType: block.kind, ...block.kind === "wod" ? { blockContentId: wodWikiCore.blockContentId(section?.scriptBlock?.content ?? content.slice(block.from, block.to)) } : {}, rawContent: content.slice(block.from, block.to), noteTitle: metadata.noteTitle ?? fileToDisplayName(path.split("/").at(-1) ?? path), createdAt: metadata.createdAt ?? 0, isStatic: true, sourceId: metadata.sourceId, sourcePath: path, routeId: metadata.routeId };
|
|
780
672
|
});
|
|
781
|
-
return { path, content, blocks, blockIndex, blockEfforts: [] };
|
|
673
|
+
return { path, content, blocks, blockIndex, blockEfforts: [], blockEquipment: [] };
|
|
782
674
|
}
|
|
783
675
|
function buildBlockIndexRows(markdownDir, corpusRoot) {
|
|
784
676
|
const rows = [];
|
|
@@ -828,41 +720,37 @@ function formatDiscoveredLabel(raw) {
|
|
|
828
720
|
const clean = raw.replace(/[-_]+/g, " ").trim();
|
|
829
721
|
return clean.split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
|
|
830
722
|
}
|
|
831
|
-
function
|
|
832
|
-
const
|
|
833
|
-
const
|
|
723
|
+
function loadCorpusReferenceCatalog(markdownDir) {
|
|
724
|
+
const efforts = [];
|
|
725
|
+
const equipment = [];
|
|
834
726
|
const effortsDir = path.join(markdownDir, "efforts");
|
|
835
727
|
for (const file of listMarkdownFiles(effortsDir)) {
|
|
836
|
-
const
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
for (const alias of parsed.aliases) {
|
|
844
|
-
aliasToCanonical.set(alias.toLowerCase(), parsed.slug);
|
|
845
|
-
aliasToCanonical.set(alias.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""), parsed.slug);
|
|
846
|
-
}
|
|
728
|
+
const parsed = wodWikiLang.parseEffortFile(fs.readFileSync(path.join(effortsDir, file), "utf8"));
|
|
729
|
+
if (parsed) efforts.push(parsed);
|
|
730
|
+
}
|
|
731
|
+
const equipmentDir = path.join(markdownDir, "equipment");
|
|
732
|
+
for (const file of listMarkdownFiles(equipmentDir)) {
|
|
733
|
+
const parsed = wodWikiLang.parseEquipmentFile(fs.readFileSync(path.join(equipmentDir, file), "utf8"));
|
|
734
|
+
if (parsed) equipment.push(parsed);
|
|
847
735
|
}
|
|
848
|
-
return {
|
|
736
|
+
return { efforts, equipment };
|
|
849
737
|
}
|
|
850
738
|
function discoverUncatalogedEfforts(markdownDir, corpusRoot) {
|
|
851
|
-
const
|
|
739
|
+
const catalog = loadCorpusReferenceCatalog(markdownDir);
|
|
740
|
+
const index = wodWikiLang.createReferenceIndex(catalog);
|
|
852
741
|
const blocks = buildBlockIndexRows(markdownDir, corpusRoot);
|
|
853
742
|
const discovered = /* @__PURE__ */ new Map();
|
|
854
743
|
for (const block of blocks) {
|
|
855
744
|
if (block.dataType !== "wod" || !block.rawContent) continue;
|
|
856
745
|
const section = wodWikiCore.parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((section2) => section2.scriptBlock);
|
|
857
|
-
const script = wodWikiLang.parseScript(section?.scriptBlock?.content ?? block.rawContent);
|
|
746
|
+
const script = wodWikiLang.parseScript(section?.scriptBlock?.content ?? block.rawContent, { references: index });
|
|
858
747
|
for (const statement of script.statements) {
|
|
859
748
|
const effortMetric = statement.metrics?.getMetric?.("effort");
|
|
860
749
|
const effortLabel = (effortMetric && typeof effortMetric.value === "string" ? effortMetric.value : void 0) ?? statement.exerciseId;
|
|
861
750
|
if (!effortLabel) continue;
|
|
862
|
-
const slugified =
|
|
751
|
+
const slugified = wodWikiLang.slugifyRefLabel(effortLabel);
|
|
863
752
|
if (!slugified || NON_EFFORT_SLUGS[slugified]) continue;
|
|
864
|
-
|
|
865
|
-
if (canonical && slugs.has(canonical)) continue;
|
|
753
|
+
if (index.resolveEffort(slugified) || index.resolveEffort(effortLabel)) continue;
|
|
866
754
|
const existing = discovered.get(slugified);
|
|
867
755
|
if (existing) {
|
|
868
756
|
existing.rawLabels.add(effortLabel);
|
|
@@ -912,17 +800,16 @@ ${aliases.join("\n")}` : "aliases: []",
|
|
|
912
800
|
}
|
|
913
801
|
function buildBlockEffortRows(markdownDir, corpusRoot, blocks = buildBlockIndexRows(markdownDir, corpusRoot)) {
|
|
914
802
|
const efforts = [];
|
|
915
|
-
const
|
|
803
|
+
const index = wodWikiLang.createReferenceIndex(loadCorpusReferenceCatalog(markdownDir));
|
|
916
804
|
for (const block of blocks) {
|
|
917
805
|
if (block.dataType !== "wod" || !block.rawContent) continue;
|
|
918
806
|
const section = wodWikiCore.parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((section2) => section2.scriptBlock);
|
|
919
|
-
const script = wodWikiLang.parseScript(section?.scriptBlock?.content ?? block.rawContent);
|
|
920
|
-
const effortSlugs = extractEffortSlugs2(script.statements);
|
|
807
|
+
const script = wodWikiLang.parseScript(section?.scriptBlock?.content ?? block.rawContent, { references: index });
|
|
921
808
|
const linked = /* @__PURE__ */ new Set();
|
|
922
|
-
for (const rawSlug of
|
|
923
|
-
const
|
|
924
|
-
const canonicalSlug =
|
|
925
|
-
if (!canonicalSlug || NON_EFFORT_SLUGS[canonicalSlug] || NON_EFFORT_SLUGS[
|
|
809
|
+
for (const rawSlug of wodWikiLang.extractStatementRefs(script.statements).efforts) {
|
|
810
|
+
const canonical = index.resolveEffort(rawSlug);
|
|
811
|
+
const canonicalSlug = canonical?.slug;
|
|
812
|
+
if (!canonicalSlug || NON_EFFORT_SLUGS[canonicalSlug] || NON_EFFORT_SLUGS[rawSlug]) {
|
|
926
813
|
continue;
|
|
927
814
|
}
|
|
928
815
|
if (linked.has(canonicalSlug)) continue;
|
|
@@ -941,6 +828,32 @@ function buildBlockEffortRows(markdownDir, corpusRoot, blocks = buildBlockIndexR
|
|
|
941
828
|
}
|
|
942
829
|
return efforts;
|
|
943
830
|
}
|
|
831
|
+
function buildBlockEquipmentRows(markdownDir, corpusRoot, blocks = buildBlockIndexRows(markdownDir, corpusRoot)) {
|
|
832
|
+
const links = [];
|
|
833
|
+
const index = wodWikiLang.createReferenceIndex(loadCorpusReferenceCatalog(markdownDir));
|
|
834
|
+
for (const block of blocks) {
|
|
835
|
+
if (block.dataType !== "wod" || !block.rawContent) continue;
|
|
836
|
+
const section = wodWikiCore.parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((s) => s.scriptBlock);
|
|
837
|
+
const script = wodWikiLang.parseScript(section?.scriptBlock?.content ?? block.rawContent, { references: index });
|
|
838
|
+
const linked = /* @__PURE__ */ new Set();
|
|
839
|
+
for (const rawSlug of wodWikiLang.extractStatementRefs(script.statements).equipment) {
|
|
840
|
+
const canonicalSlug = index.resolveEquipment(rawSlug)?.slug;
|
|
841
|
+
if (!canonicalSlug || linked.has(canonicalSlug)) continue;
|
|
842
|
+
linked.add(canonicalSlug);
|
|
843
|
+
links.push({
|
|
844
|
+
id: `${block.id}:${canonicalSlug}`,
|
|
845
|
+
noteId: block.noteId,
|
|
846
|
+
blockId: block.blockId,
|
|
847
|
+
blockContentId: block.blockContentId,
|
|
848
|
+
equipmentSlug: canonicalSlug,
|
|
849
|
+
isStatic: block.isStatic,
|
|
850
|
+
sourcePath: block.sourcePath,
|
|
851
|
+
createdAt: block.createdAt
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return links;
|
|
856
|
+
}
|
|
944
857
|
function sha256Hex(data) {
|
|
945
858
|
return crypto.createHash("sha256").update(data).digest("hex");
|
|
946
859
|
}
|
|
@@ -992,9 +905,11 @@ ${shown}${more}`);
|
|
|
992
905
|
const manifestChunks = [];
|
|
993
906
|
const tBlockEfforts = Date.now();
|
|
994
907
|
const effortRows = buildBlockEffortRows(markdownDir, corpusRoot, blockRows);
|
|
908
|
+
const equipmentRows = buildBlockEquipmentRows(markdownDir, corpusRoot, blockRows);
|
|
995
909
|
passMs.blockEfforts = Date.now() - tBlockEfforts;
|
|
996
910
|
const blocksByPath = /* @__PURE__ */ new Map();
|
|
997
911
|
const effortsByPath = /* @__PURE__ */ new Map();
|
|
912
|
+
const equipmentByPath = /* @__PURE__ */ new Map();
|
|
998
913
|
for (const row of blockRows) {
|
|
999
914
|
const rows = blocksByPath.get(row.sourcePath) ?? [];
|
|
1000
915
|
rows.push(row);
|
|
@@ -1005,6 +920,11 @@ ${shown}${more}`);
|
|
|
1005
920
|
rows.push(row);
|
|
1006
921
|
effortsByPath.set(row.sourcePath, rows);
|
|
1007
922
|
}
|
|
923
|
+
for (const row of equipmentRows) {
|
|
924
|
+
const rows = equipmentByPath.get(row.sourcePath) ?? [];
|
|
925
|
+
rows.push(row);
|
|
926
|
+
equipmentByPath.set(row.sourcePath, rows);
|
|
927
|
+
}
|
|
1008
928
|
let totalFiles = 0;
|
|
1009
929
|
const tWrite = Date.now();
|
|
1010
930
|
for (const { id, files } of groups) {
|
|
@@ -1015,6 +935,7 @@ ${shown}${more}`);
|
|
|
1015
935
|
const compiled = compileSeedRow(p, content);
|
|
1016
936
|
compiled.blockIndex = blocksByPath.get(p) ?? compiled.blockIndex;
|
|
1017
937
|
compiled.blockEfforts = effortsByPath.get(p) ?? [];
|
|
938
|
+
compiled.blockEquipment = equipmentByPath.get(p) ?? [];
|
|
1018
939
|
return compiled;
|
|
1019
940
|
});
|
|
1020
941
|
const bytes = Buffer.from(JSON.stringify(rows), "utf8");
|
|
@@ -1050,9 +971,7 @@ var NON_EFFORT_SLUGS;
|
|
|
1050
971
|
var init_compiler = __esm({
|
|
1051
972
|
"src/seedbuild/compiler.ts"() {
|
|
1052
973
|
init_contract();
|
|
1053
|
-
init_effort_slugs();
|
|
1054
974
|
init_filename();
|
|
1055
|
-
init_effort_file();
|
|
1056
975
|
init_git_version();
|
|
1057
976
|
init_report();
|
|
1058
977
|
init_frontmatter();
|
|
@@ -1110,7 +1029,7 @@ var init_compiler = __esm({
|
|
|
1110
1029
|
var VERSION;
|
|
1111
1030
|
var init_version = __esm({
|
|
1112
1031
|
"src/version.ts"() {
|
|
1113
|
-
VERSION = "0.37.
|
|
1032
|
+
VERSION = "0.37.2140";
|
|
1114
1033
|
}
|
|
1115
1034
|
});
|
|
1116
1035
|
|
|
@@ -2408,23 +2327,7 @@ function resolveDatabaseConfig(options = {}, env) {
|
|
|
2408
2327
|
// src/cli/persist.ts
|
|
2409
2328
|
init_db();
|
|
2410
2329
|
var registeredWidgets = wodWikiCore.KNOWN_SECTION_WIDGETS;
|
|
2411
|
-
var saveStores = ["notes", "block_revisions", "block_index", "block_efforts", "tags", "note_tags", "sessions"];
|
|
2412
|
-
function extractEffortSlugs(statements) {
|
|
2413
|
-
const slugs = /* @__PURE__ */ new Set();
|
|
2414
|
-
for (const statement of statements) {
|
|
2415
|
-
if (statement.exerciseId) {
|
|
2416
|
-
slugs.add(statement.exerciseId);
|
|
2417
|
-
} else {
|
|
2418
|
-
const effortMetric = statement.metrics?.getMetric?.("effort");
|
|
2419
|
-
const effort = effortMetric && "effort" in effortMetric ? effortMetric.effort : void 0;
|
|
2420
|
-
if (typeof effort === "string") {
|
|
2421
|
-
const slug = effort.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
2422
|
-
if (slug) slugs.add(slug);
|
|
2423
|
-
}
|
|
2424
|
-
}
|
|
2425
|
-
}
|
|
2426
|
-
return [...slugs];
|
|
2427
|
-
}
|
|
2330
|
+
var saveStores = ["notes", "block_revisions", "block_index", "block_efforts", "block_equipment", "efforts", "equipment", "tags", "note_tags", "sessions"];
|
|
2428
2331
|
function titleFromLabel(sourceLabel) {
|
|
2429
2332
|
if (!sourceLabel || sourceLabel === "-") return "stdin";
|
|
2430
2333
|
const stem = sourceLabel.split("/").pop() ?? sourceLabel;
|
|
@@ -2496,9 +2399,19 @@ async function saveSource(db, options, startTime) {
|
|
|
2496
2399
|
};
|
|
2497
2400
|
const priorRows = await tx.readonly("block_index").getAllFromIndex("by-note", noteId);
|
|
2498
2401
|
const priorEfforts = await tx.readonly("block_efforts").getAllFromIndex("by-note", noteId);
|
|
2402
|
+
const priorEquipment = await tx.readonly("block_equipment").getAllFromIndex("by-note", noteId);
|
|
2403
|
+
const storedEfforts = await tx.readonly("efforts").getAll();
|
|
2404
|
+
const effortsBySlug = /* @__PURE__ */ new Map();
|
|
2405
|
+
for (const effort of wodWikiLang.bundledEfforts) effortsBySlug.set(effort.slug, effort);
|
|
2406
|
+
for (const effort of storedEfforts) effortsBySlug.set(effort.slug, effort);
|
|
2407
|
+
const referenceIndex = wodWikiLang.createReferenceIndex({
|
|
2408
|
+
efforts: [...effortsBySlug.values()],
|
|
2409
|
+
equipment: await tx.readonly("equipment").getAll()
|
|
2410
|
+
});
|
|
2499
2411
|
const priorById = new Map(priorRows.map((row) => [row.id, row]));
|
|
2500
2412
|
const nextRows = [];
|
|
2501
2413
|
const nextEfforts = [];
|
|
2414
|
+
const nextEquipment = [];
|
|
2502
2415
|
for (const [position, block] of Object.values(blocks).sort((a, b) => a.from - b.from).entries()) {
|
|
2503
2416
|
const id = `${noteId}:${block.id}`;
|
|
2504
2417
|
const prior = priorById.get(id);
|
|
@@ -2524,7 +2437,20 @@ async function saveSource(db, options, startTime) {
|
|
|
2524
2437
|
...note.sourceId ? { sourceId: note.sourceId } : {}
|
|
2525
2438
|
});
|
|
2526
2439
|
if (block.kind === "wod") {
|
|
2527
|
-
|
|
2440
|
+
const statements = wodWikiLang.parseScript(body, { sport: block.sport, dialect: block.dialect, references: referenceIndex }).statements;
|
|
2441
|
+
const refs = wodWikiLang.extractStatementRefs(statements);
|
|
2442
|
+
const effortSlugs = new Set(refs.efforts);
|
|
2443
|
+
if (effortSlugs.size === 0) {
|
|
2444
|
+
for (const s of statements) {
|
|
2445
|
+
const m = s.metrics?.getMetric?.(wodWikiCore.MetricType.Effort);
|
|
2446
|
+
const val = typeof m?.value === "string" ? m.value : m && "effort" in m ? String(m.effort) : "";
|
|
2447
|
+
const slug = val.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
2448
|
+
if (slug && !["rest", "amrap", "emom", "tabata", "for-time"].includes(slug)) {
|
|
2449
|
+
effortSlugs.add(slug);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
for (const effortSlug of effortSlugs) {
|
|
2528
2454
|
const effortId = `${noteId}:${block.id}:${effortSlug}`;
|
|
2529
2455
|
const previous = priorEfforts.find((row) => row.id === effortId);
|
|
2530
2456
|
nextEfforts.push({
|
|
@@ -2537,12 +2463,26 @@ async function saveSource(db, options, startTime) {
|
|
|
2537
2463
|
createdAt: previous?.createdAt ?? now
|
|
2538
2464
|
});
|
|
2539
2465
|
}
|
|
2466
|
+
for (const equipmentSlug of refs.equipment) {
|
|
2467
|
+
const equipmentId = `${noteId}:${block.id}:${equipmentSlug}`;
|
|
2468
|
+
const previous = priorEquipment.find((row) => row.id === equipmentId);
|
|
2469
|
+
nextEquipment.push({
|
|
2470
|
+
...previous,
|
|
2471
|
+
id: equipmentId,
|
|
2472
|
+
noteId,
|
|
2473
|
+
blockId: block.id,
|
|
2474
|
+
blockContentId: fingerprint,
|
|
2475
|
+
equipmentSlug,
|
|
2476
|
+
createdAt: previous?.createdAt ?? now
|
|
2477
|
+
});
|
|
2478
|
+
}
|
|
2540
2479
|
}
|
|
2541
2480
|
}
|
|
2542
2481
|
if (!wodWikiStorage.rowsEqual(existing, note)) await tx.readwrite("notes").put(note);
|
|
2543
2482
|
if (revisions.length) await tx.readwrite("block_revisions").putMany(revisions);
|
|
2544
2483
|
await diffProjection(tx, "block_index", priorRows, nextRows);
|
|
2545
2484
|
await diffProjection(tx, "block_efforts", priorEfforts, nextEfforts);
|
|
2485
|
+
await diffProjection(tx, "block_equipment", priorEquipment, nextEquipment);
|
|
2546
2486
|
const tags = await saveTags(tx, noteId, options.tags, now);
|
|
2547
2487
|
let session;
|
|
2548
2488
|
let revision;
|
|
@@ -2578,6 +2518,7 @@ async function diffProjection(tx, store, previous, next) {
|
|
|
2578
2518
|
if (!wodWikiStorage.rowsEqual(old.get(row.id), row)) {
|
|
2579
2519
|
if (store === "block_index" && "blockVersion" in row) await tx.readwrite("block_index").put(row);
|
|
2580
2520
|
if (store === "block_efforts" && "effortSlug" in row) await tx.readwrite("block_efforts").put(row);
|
|
2521
|
+
if (store === "block_equipment" && "equipmentSlug" in row) await tx.readwrite("block_equipment").put(row);
|
|
2581
2522
|
}
|
|
2582
2523
|
}
|
|
2583
2524
|
}
|
|
@@ -2669,6 +2610,12 @@ async function persistEffort(db, effort) {
|
|
|
2669
2610
|
await sql.putRow(tx, sql.storeDefinition("efforts"), effort);
|
|
2670
2611
|
});
|
|
2671
2612
|
}
|
|
2613
|
+
async function persistEquipment(db, equipment) {
|
|
2614
|
+
const sql = await loadSql();
|
|
2615
|
+
await db.db.transaction(async (tx) => {
|
|
2616
|
+
await sql.putRow(tx, sql.storeDefinition("equipment"), equipment);
|
|
2617
|
+
});
|
|
2618
|
+
}
|
|
2672
2619
|
async function persistTypedTags(db, labels, type) {
|
|
2673
2620
|
return db.storage.transaction(["tags"], "readwrite", async (tx) => {
|
|
2674
2621
|
let added = 0;
|
|
@@ -2694,17 +2641,18 @@ async function importSeedDir(db, dir, sourceId) {
|
|
|
2694
2641
|
const source = sourceId || path.basename(dir);
|
|
2695
2642
|
const manifest = wodWikiEngine.assertSeedManifest(JSON.parse(fs.readFileSync(path.resolve(dir, "manifest.json"), "utf-8")));
|
|
2696
2643
|
const key = wodWikiEngine.seedMetaKey(source);
|
|
2697
|
-
|
|
2698
|
-
|
|
2644
|
+
const stored = await db.storage.readonly("meta").get(key);
|
|
2645
|
+
let expected = stored?.schema === wodWikiEngine.SEED_SCHEMA ? stored : void 0;
|
|
2699
2646
|
let meta = expected ?? wodWikiEngine.emptySeedMeta(key);
|
|
2700
2647
|
if (manifest.version < meta.seedVersion) throw new Error("Seed manifest is older than stored checkpoint");
|
|
2701
|
-
const summary = { sourceId: source, version: manifest.version, notes: 0, efforts: 0, blocks: 0, blockEfforts: 0, deleted: 0, skippedUserOwned: 0 };
|
|
2648
|
+
const summary = { sourceId: source, version: manifest.version, notes: 0, efforts: 0, equipment: 0, blocks: 0, blockEfforts: 0, deleted: 0, skippedUserOwned: 0 };
|
|
2702
2649
|
const metadataChanged = manifest.version !== meta.seedVersion || manifest.builtAt !== meta.builtAt;
|
|
2703
2650
|
const plan = manifest.chunks.filter((c) => metadataChanged || meta.chunks[c.id]?.sha256 !== c.sha256);
|
|
2704
2651
|
plan.sort((a, b) => Number(b.id === wodWikiEngine.CANVAS_CHUNK_ID) - Number(a.id === wodWikiEngine.CANVAS_CHUNK_ID));
|
|
2705
2652
|
const accumulate = (result) => {
|
|
2706
2653
|
summary.notes += result.totalNotes;
|
|
2707
2654
|
summary.efforts += result.totalEfforts;
|
|
2655
|
+
summary.equipment += result.totalEquipment;
|
|
2708
2656
|
summary.blocks += result.totalBlocks;
|
|
2709
2657
|
summary.deleted += result.deleted;
|
|
2710
2658
|
summary.skippedUserOwned += result.skippedUserOwned;
|
|
@@ -2780,6 +2728,7 @@ async function publishCatalogSeed(db, options) {
|
|
|
2780
2728
|
}
|
|
2781
2729
|
const allIndexRows = await db.storage.readonly("block_index").getAll();
|
|
2782
2730
|
const allEffortRows = await db.storage.readonly("block_efforts").getAll();
|
|
2731
|
+
const allEquipmentRows = await db.storage.readonly("block_equipment").getAll();
|
|
2783
2732
|
const indexByNote = /* @__PURE__ */ new Map();
|
|
2784
2733
|
for (const row of allIndexRows) {
|
|
2785
2734
|
const list = indexByNote.get(row.noteId) ?? [];
|
|
@@ -2792,6 +2741,12 @@ async function publishCatalogSeed(db, options) {
|
|
|
2792
2741
|
list.push(row);
|
|
2793
2742
|
effortsByNote.set(row.noteId, list);
|
|
2794
2743
|
}
|
|
2744
|
+
const equipmentByNote = /* @__PURE__ */ new Map();
|
|
2745
|
+
for (const row of allEquipmentRows) {
|
|
2746
|
+
const list = equipmentByNote.get(row.noteId) ?? [];
|
|
2747
|
+
list.push(row);
|
|
2748
|
+
equipmentByNote.set(row.noteId, list);
|
|
2749
|
+
}
|
|
2795
2750
|
const outDir = path.resolve(process.cwd(), options.outDir);
|
|
2796
2751
|
const chunksDir = path.join(outDir, "chunks");
|
|
2797
2752
|
fs.mkdirSync(chunksDir, { recursive: true });
|
|
@@ -2806,6 +2761,7 @@ async function publishCatalogSeed(db, options) {
|
|
|
2806
2761
|
const notePath = note.sourcePath ?? `markdown/collections/${catalogName}/${stem}.md`;
|
|
2807
2762
|
const noteBlockIndex = indexByNote.get(note.id) ?? [];
|
|
2808
2763
|
const noteBlockEfforts = effortsByNote.get(note.id) ?? [];
|
|
2764
|
+
const noteBlockEquipment = equipmentByNote.get(note.id) ?? [];
|
|
2809
2765
|
const blockIndex = noteBlockIndex.length > 0 ? noteBlockIndex.map((b) => ({
|
|
2810
2766
|
...b,
|
|
2811
2767
|
isStatic: true,
|
|
@@ -2825,12 +2781,18 @@ async function publishCatalogSeed(db, options) {
|
|
|
2825
2781
|
isStatic: true,
|
|
2826
2782
|
sourcePath: e.sourcePath ?? notePath
|
|
2827
2783
|
}));
|
|
2784
|
+
const blockEquipment = noteBlockEquipment.map((e) => ({
|
|
2785
|
+
...e,
|
|
2786
|
+
isStatic: true,
|
|
2787
|
+
sourcePath: e.sourcePath ?? notePath
|
|
2788
|
+
}));
|
|
2828
2789
|
chunkRows.push({
|
|
2829
2790
|
path: notePath,
|
|
2830
2791
|
content: note.rawContent,
|
|
2831
2792
|
blocks: note.blocks,
|
|
2832
2793
|
blockIndex,
|
|
2833
|
-
blockEfforts
|
|
2794
|
+
blockEfforts,
|
|
2795
|
+
blockEquipment
|
|
2834
2796
|
});
|
|
2835
2797
|
}
|
|
2836
2798
|
const chunkId = `collection.${catalogName}`;
|
|
@@ -3800,7 +3762,9 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
3800
3762
|
writeErr(`[wod ${verb}] Effort not found in ${db.path}: ${id}`);
|
|
3801
3763
|
return 1;
|
|
3802
3764
|
}
|
|
3803
|
-
const
|
|
3765
|
+
const ownerNoteId = typeof effort.ownerNoteId === "string" ? effort.ownerNoteId : `effort/${effort.slug}`;
|
|
3766
|
+
const owner = await db.storage.readonly("notes").get(ownerNoteId);
|
|
3767
|
+
const markdown = owner?.rawContent ?? wodWikiEngine.effortToMarkdown(effort);
|
|
3804
3768
|
const target = parsed.output && parsed.output !== "-" ? parsed.output : `${id}.md`;
|
|
3805
3769
|
if (parsed.output === "-") {
|
|
3806
3770
|
writeOut(markdown);
|
|
@@ -3809,15 +3773,29 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
3809
3773
|
}
|
|
3810
3774
|
writeOut(`[wod ${verb}] effort ${id} \u2192 ${target}`);
|
|
3811
3775
|
} else {
|
|
3812
|
-
const
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3776
|
+
const equipment = id ? await getEquipmentBySlug(db.db, targetId) : void 0;
|
|
3777
|
+
if (equipment) {
|
|
3778
|
+
const ownerNoteId = typeof equipment.ownerNoteId === "string" ? equipment.ownerNoteId : `equipment/${equipment.slug}`;
|
|
3779
|
+
const owner = await db.storage.readonly("notes").get(ownerNoteId);
|
|
3780
|
+
const markdown = owner?.rawContent ?? wodWikiEngine.equipmentToMarkdown(equipment);
|
|
3781
|
+
const target = parsed.output && parsed.output !== "-" ? parsed.output : `${id}.md`;
|
|
3782
|
+
if (parsed.output === "-") {
|
|
3783
|
+
writeOut(markdown);
|
|
3784
|
+
} else {
|
|
3785
|
+
nodeFs().writeFileSync(target, markdown, "utf-8");
|
|
3786
|
+
}
|
|
3787
|
+
writeOut(`[wod ${verb}] equipment ${id} \u2192 ${target}`);
|
|
3817
3788
|
} else {
|
|
3818
|
-
|
|
3789
|
+
const labels = (await listTagsByType(db.db, "equipment")).map((t) => t.label).sort();
|
|
3790
|
+
const csv = wodWikiEngine.equipmentToCsv(labels);
|
|
3791
|
+
const target = parsed.output && parsed.output !== "-" ? parsed.output : "equipment.csv";
|
|
3792
|
+
if (parsed.output === "-") {
|
|
3793
|
+
writeOut(csv);
|
|
3794
|
+
} else {
|
|
3795
|
+
nodeFs().writeFileSync(target, csv, "utf-8");
|
|
3796
|
+
}
|
|
3797
|
+
writeOut(`[wod ${verb}] equipment \u2192 ${target} (${labels.length} labels)`);
|
|
3819
3798
|
}
|
|
3820
|
-
writeOut(`[wod ${verb}] equipment \u2192 ${target} (${labels.length} labels)`);
|
|
3821
3799
|
}
|
|
3822
3800
|
} finally {
|
|
3823
3801
|
await db.close();
|
|
@@ -3859,7 +3837,7 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
3859
3837
|
return 0;
|
|
3860
3838
|
}
|
|
3861
3839
|
if (kind === "effort") {
|
|
3862
|
-
const effort =
|
|
3840
|
+
const effort = wodWikiLang.parseEffortFile(fs.readFileSync(file, "utf-8"));
|
|
3863
3841
|
if (!effort) {
|
|
3864
3842
|
writeErr(`[wod import] Unparseable effort file (need frontmatter id/slug/label + numeric baseAttributes.met): ${file}`);
|
|
3865
3843
|
return 1;
|
|
@@ -3873,6 +3851,21 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
3873
3851
|
}
|
|
3874
3852
|
return 0;
|
|
3875
3853
|
}
|
|
3854
|
+
if (kind === "equipment" && /\.md$/i.test(file)) {
|
|
3855
|
+
const equipment = wodWikiLang.parseEquipmentFile(fs.readFileSync(file, "utf-8"));
|
|
3856
|
+
if (!equipment) {
|
|
3857
|
+
writeErr(`[wod import] Unparseable equipment file (need frontmatter type: equipment + id/slug/label): ${file}`);
|
|
3858
|
+
return 1;
|
|
3859
|
+
}
|
|
3860
|
+
const db2 = await openCliDb(cliDb());
|
|
3861
|
+
try {
|
|
3862
|
+
await persistEquipment(db2, { ...equipment, registrySource: "user" });
|
|
3863
|
+
writeOut(`[wod import] equipment ${equipment.slug} \u2014 ${equipment.label} \u2192 ${db2.path}`);
|
|
3864
|
+
} finally {
|
|
3865
|
+
await db2.close();
|
|
3866
|
+
}
|
|
3867
|
+
return 0;
|
|
3868
|
+
}
|
|
3876
3869
|
if (kind === "equipment") {
|
|
3877
3870
|
const labels = wodWikiEngine.csvToEquipmentLabels(fs.readFileSync(file, "utf-8"));
|
|
3878
3871
|
if (labels.length === 0) {
|