@bitcobblers/wod-wiki-core 0.36.2136 → 0.37.2139
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/index.cjs +194 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -9
- package/dist/index.d.ts +123 -9
- package/dist/index.mjs +192 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,7 @@ var MetricType = /* @__PURE__ */ ((MetricType2) => {
|
|
|
36
36
|
MetricType2["Total"] = "total";
|
|
37
37
|
MetricType2["Rep"] = "rep";
|
|
38
38
|
MetricType2["Effort"] = "effort";
|
|
39
|
+
MetricType2["Equipment"] = "equipment";
|
|
39
40
|
MetricType2["Distance"] = "distance";
|
|
40
41
|
MetricType2["Rounds"] = "rounds";
|
|
41
42
|
MetricType2["CurrentRound"] = "current-round";
|
|
@@ -530,6 +531,29 @@ function convertViaCatalog(value, from, to) {
|
|
|
530
531
|
return value * fromDef.factor / toDef.factor;
|
|
531
532
|
}
|
|
532
533
|
|
|
534
|
+
// src/models/ReferenceMetadata.ts
|
|
535
|
+
var REFERENCE_METADATA_KEY = "references";
|
|
536
|
+
var REFERENCE_MATCH_KINDS = ["explicit", "split", "whole", "default", "none"];
|
|
537
|
+
function isValidReferenceRef(value) {
|
|
538
|
+
if (!value || typeof value !== "object") return false;
|
|
539
|
+
const candidate = value;
|
|
540
|
+
return (candidate.kind === "effort" || candidate.kind === "equipment") && typeof candidate.slug === "string" && !!candidate.slug && typeof candidate.label === "string";
|
|
541
|
+
}
|
|
542
|
+
function isValidReferenceDiagnostic(value) {
|
|
543
|
+
if (!value || typeof value !== "object") return false;
|
|
544
|
+
return typeof value.reason === "string";
|
|
545
|
+
}
|
|
546
|
+
function getReferenceMetadata(metadata) {
|
|
547
|
+
const value = metadata?.[REFERENCE_METADATA_KEY];
|
|
548
|
+
if (!value || typeof value !== "object") return void 0;
|
|
549
|
+
const candidate = value;
|
|
550
|
+
if (typeof candidate.matched !== "string" || !REFERENCE_MATCH_KINDS.includes(candidate.matched)) return void 0;
|
|
551
|
+
if (typeof candidate.source !== "string") return void 0;
|
|
552
|
+
if (candidate.refs !== void 0 && (!Array.isArray(candidate.refs) || !candidate.refs.every(isValidReferenceRef))) return void 0;
|
|
553
|
+
if (candidate.diagnostics !== void 0 && (!Array.isArray(candidate.diagnostics) || !candidate.diagnostics.every(isValidReferenceDiagnostic))) return void 0;
|
|
554
|
+
return value;
|
|
555
|
+
}
|
|
556
|
+
|
|
533
557
|
// src/models/CodeMetadata.ts
|
|
534
558
|
var CodeMetadata = class {
|
|
535
559
|
constructor(line, startOffset, endOffset, length, columnStart = 0, columnEnd = 0, raw = "") {
|
|
@@ -988,13 +1012,14 @@ function matchDialectFence(trimmedLine) {
|
|
|
988
1012
|
}
|
|
989
1013
|
function frontmatterSubtype(properties) {
|
|
990
1014
|
const type = properties.type?.toLowerCase();
|
|
991
|
-
if (type === "youtube" || type === "strava" || type === "amazon" || type === "file" || type === "effort") return type;
|
|
1015
|
+
if (type === "youtube" || type === "strava" || type === "amazon" || type === "file" || type === "effort" || type === "equipment") return type;
|
|
992
1016
|
const url = properties.url || properties.link || "";
|
|
993
1017
|
const host = url.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "").split(/[/?#:]/, 1)[0].toLowerCase();
|
|
994
1018
|
if (host === "youtu.be" || host === "youtube.com" || host.endsWith(".youtube.com")) return "youtube";
|
|
995
1019
|
if (host === "strava.com" || host.endsWith(".strava.com")) return "strava";
|
|
996
1020
|
if (host === "amzn.to" || host === "amazon.com" || host.endsWith(".amazon.com")) return "amazon";
|
|
997
1021
|
if (["baseAttributes", "discipline", "effortType", "targetRPE", "equipment", "aliases", "derivation"].some((key) => key in properties)) return "effort";
|
|
1022
|
+
if (["slug", "label", "registrySource", "ownerNoteId", "sourcePath"].some((key) => key in properties)) return "equipment";
|
|
998
1023
|
return "default";
|
|
999
1024
|
}
|
|
1000
1025
|
function markdownSubtype(text) {
|
|
@@ -1211,14 +1236,173 @@ function extractBlockContent(content, startLine, endLine) {
|
|
|
1211
1236
|
return parseDocumentSections(content).find((section) => section.startLine === startLine && section.endLine === endLine && section.scriptBlock)?.scriptBlock?.content ?? "";
|
|
1212
1237
|
}
|
|
1213
1238
|
|
|
1239
|
+
// src/sections/frontmatter.ts
|
|
1240
|
+
var KEY_RE = /^[A-Za-z][\w.-]*$/;
|
|
1241
|
+
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
1242
|
+
function escapeRe(s) {
|
|
1243
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1244
|
+
}
|
|
1245
|
+
function isBlankOrComment(line) {
|
|
1246
|
+
const t = line.trim();
|
|
1247
|
+
return t === "" || t.startsWith("#");
|
|
1248
|
+
}
|
|
1249
|
+
function isList(value) {
|
|
1250
|
+
return Array.isArray(value);
|
|
1251
|
+
}
|
|
1252
|
+
function quoteYamlScalar(value) {
|
|
1253
|
+
if (value === "") return '""';
|
|
1254
|
+
const looksNumeric = !isNaN(Number(value));
|
|
1255
|
+
const looksKeyword = /^(true|false|null|yes|no|on|off)$/i.test(value);
|
|
1256
|
+
if (/[:"'\n#{}[\],&*?|<>=%!@`]/.test(value) || value !== value.trim() || value.startsWith("-") || looksNumeric || looksKeyword) {
|
|
1257
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")}"`;
|
|
1258
|
+
}
|
|
1259
|
+
return value;
|
|
1260
|
+
}
|
|
1261
|
+
function propertyLines(indent, key, value) {
|
|
1262
|
+
const pad = " ".repeat(indent);
|
|
1263
|
+
if (isList(value)) {
|
|
1264
|
+
if (value.length === 0) return [`${pad}${key}: []`];
|
|
1265
|
+
return [`${pad}${key}:`, ...value.map((item) => `${pad} - ${typeof item === "number" ? String(item) : quoteYamlScalar(item)}`)];
|
|
1266
|
+
}
|
|
1267
|
+
return [`${pad}${key}: ${typeof value === "number" ? String(value) : quoteYamlScalar(value)}`];
|
|
1268
|
+
}
|
|
1269
|
+
function missingChainLines(path, from, value, baseIndent) {
|
|
1270
|
+
const out = [];
|
|
1271
|
+
let indent = baseIndent;
|
|
1272
|
+
for (let i = from; i < path.length; i++) {
|
|
1273
|
+
if (i === path.length - 1) {
|
|
1274
|
+
out.push(...propertyLines(indent, path[i], value));
|
|
1275
|
+
} else {
|
|
1276
|
+
out.push(`${" ".repeat(indent)}${path[i]}:`);
|
|
1277
|
+
}
|
|
1278
|
+
indent += 2;
|
|
1279
|
+
}
|
|
1280
|
+
return out;
|
|
1281
|
+
}
|
|
1282
|
+
function inlineCommentIndex(line) {
|
|
1283
|
+
let inSingle = false;
|
|
1284
|
+
let inDouble = false;
|
|
1285
|
+
for (let i = 0; i < line.length; i++) {
|
|
1286
|
+
const c = line[i];
|
|
1287
|
+
if (inDouble) {
|
|
1288
|
+
if (c === "\\") i++;
|
|
1289
|
+
else if (c === '"') inDouble = false;
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1292
|
+
if (inSingle) {
|
|
1293
|
+
if (c === "'") inSingle = false;
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
if (c === '"') inDouble = true;
|
|
1297
|
+
else if (c === "'") inSingle = true;
|
|
1298
|
+
else if (c === "#" && (i === 0 || /\s/.test(line[i - 1]))) return i;
|
|
1299
|
+
}
|
|
1300
|
+
return -1;
|
|
1301
|
+
}
|
|
1302
|
+
function propertyExtent(lines, start, indent) {
|
|
1303
|
+
const extent = [start];
|
|
1304
|
+
let pending = [];
|
|
1305
|
+
for (let j = start + 1; j < lines.length; j++) {
|
|
1306
|
+
const line = lines[j];
|
|
1307
|
+
if (isBlankOrComment(line)) {
|
|
1308
|
+
pending.push(j);
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1311
|
+
if (line.length - line.trimStart().length > indent) {
|
|
1312
|
+
extent.push(...pending, j);
|
|
1313
|
+
pending = [];
|
|
1314
|
+
} else {
|
|
1315
|
+
break;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
return extent;
|
|
1319
|
+
}
|
|
1320
|
+
function findProperty(lines, key, indent, from, to) {
|
|
1321
|
+
const re = new RegExp(`^ {${indent}}${escapeRe(key)}\\s*:`);
|
|
1322
|
+
for (let i = from; i < to; i++) {
|
|
1323
|
+
if (re.test(lines[i])) return i;
|
|
1324
|
+
}
|
|
1325
|
+
return -1;
|
|
1326
|
+
}
|
|
1327
|
+
function patchFrontmatterProperty(raw, path, value) {
|
|
1328
|
+
if (path.length === 0 || !path.every((k) => typeof k === "string" && KEY_RE.test(k))) return raw;
|
|
1329
|
+
const eol = raw.includes("\r\n") ? "\r\n" : "\n";
|
|
1330
|
+
const m = raw.match(FRONTMATTER_RE);
|
|
1331
|
+
if (!m) {
|
|
1332
|
+
if (value === null) return raw;
|
|
1333
|
+
const inner = missingChainLines(path, 0, value, 0);
|
|
1334
|
+
const block = `---${eol}${inner.join(eol)}${eol}---${eol}`;
|
|
1335
|
+
return raw.length ? block + raw : block;
|
|
1336
|
+
}
|
|
1337
|
+
const lines = m[1] === "" ? [] : m[1].split(/\r?\n/);
|
|
1338
|
+
let searchStart = 0;
|
|
1339
|
+
let searchEnd = lines.length;
|
|
1340
|
+
let foundDepth = -1;
|
|
1341
|
+
let foundIdx = -1;
|
|
1342
|
+
let foundExtent = [];
|
|
1343
|
+
for (let d = 0; d < path.length; d++) {
|
|
1344
|
+
const indent = d * 2;
|
|
1345
|
+
const idx = findProperty(lines, path[d], indent, searchStart, searchEnd);
|
|
1346
|
+
if (idx === -1) break;
|
|
1347
|
+
foundDepth = d;
|
|
1348
|
+
foundIdx = idx;
|
|
1349
|
+
foundExtent = propertyExtent(lines, idx, indent);
|
|
1350
|
+
searchStart = idx + 1;
|
|
1351
|
+
searchEnd = foundExtent[foundExtent.length - 1] + 1;
|
|
1352
|
+
}
|
|
1353
|
+
if (value === null) {
|
|
1354
|
+
if (foundDepth !== path.length - 1) return raw;
|
|
1355
|
+
const doomed = new Set(foundExtent);
|
|
1356
|
+
for (let d = foundDepth - 1; d >= 0; d--) {
|
|
1357
|
+
const indent = d * 2;
|
|
1358
|
+
const idx = findProperty(lines, path[d], indent, 0, lines.length);
|
|
1359
|
+
if (idx === -1 || doomed.has(idx)) break;
|
|
1360
|
+
let hasChild = false;
|
|
1361
|
+
for (let j = idx + 1; j < lines.length; j++) {
|
|
1362
|
+
if (doomed.has(j)) continue;
|
|
1363
|
+
const line = lines[j];
|
|
1364
|
+
if (isBlankOrComment(line)) continue;
|
|
1365
|
+
if (line.length - line.trimStart().length > indent) hasChild = true;
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
if (hasChild) break;
|
|
1369
|
+
doomed.add(idx);
|
|
1370
|
+
}
|
|
1371
|
+
const next2 = lines.filter((_, i) => !doomed.has(i));
|
|
1372
|
+
return `---${eol}${next2.length ? next2.join(eol) + eol : ""}---` + raw.slice(m[0].length);
|
|
1373
|
+
}
|
|
1374
|
+
let spliceIndex;
|
|
1375
|
+
let removeCount;
|
|
1376
|
+
let replacement;
|
|
1377
|
+
if (foundDepth === path.length - 1) {
|
|
1378
|
+
replacement = propertyLines(foundDepth * 2, path[foundDepth], value);
|
|
1379
|
+
if (!isList(value)) {
|
|
1380
|
+
const ci = inlineCommentIndex(lines[foundIdx]);
|
|
1381
|
+
if (ci !== -1) {
|
|
1382
|
+
const comment = lines[foundIdx].slice(ci).trim();
|
|
1383
|
+
replacement[0] = `${replacement[0]} ${comment}`;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
spliceIndex = foundExtent[0];
|
|
1387
|
+
removeCount = foundExtent.length;
|
|
1388
|
+
} else {
|
|
1389
|
+
spliceIndex = foundDepth === -1 ? lines.length : searchEnd;
|
|
1390
|
+
removeCount = 0;
|
|
1391
|
+
replacement = missingChainLines(path, foundDepth + 1, value, (foundDepth + 1) * 2);
|
|
1392
|
+
}
|
|
1393
|
+
const next = [...lines];
|
|
1394
|
+
next.splice(spliceIndex, removeCount, ...replacement);
|
|
1395
|
+
return `---${eol}${next.length ? next.join(eol) + eol : ""}---` + raw.slice(m[0].length);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1214
1398
|
// src/version.ts
|
|
1215
|
-
var VERSION = "0.
|
|
1216
|
-
var GIT_SHA = "
|
|
1217
|
-
var BUILD_TIME = "2026-10-
|
|
1399
|
+
var VERSION = "0.37.2139";
|
|
1400
|
+
var GIT_SHA = "491ec71";
|
|
1401
|
+
var BUILD_TIME = "2026-10-17T15:36:01.834Z";
|
|
1218
1402
|
var SEMVER = {
|
|
1219
|
-
version: "0.
|
|
1220
|
-
gitSha: "
|
|
1221
|
-
buildTime: "2026-10-
|
|
1403
|
+
version: "0.37.2139",
|
|
1404
|
+
gitSha: "491ec71",
|
|
1405
|
+
buildTime: "2026-10-17T15:36:01.834Z"
|
|
1222
1406
|
};
|
|
1223
1407
|
|
|
1224
1408
|
exports.BUILD_TIME = BUILD_TIME;
|
|
@@ -1237,6 +1421,7 @@ exports.NOTEBOOK_TAG_PREFIX = NOTEBOOK_TAG_PREFIX;
|
|
|
1237
1421
|
exports.OutputStatement = OutputStatement;
|
|
1238
1422
|
exports.OwnershipResolver = OwnershipResolver;
|
|
1239
1423
|
exports.ParsedCodeStatement = ParsedCodeStatement;
|
|
1424
|
+
exports.REFERENCE_METADATA_KEY = REFERENCE_METADATA_KEY;
|
|
1240
1425
|
exports.SEMVER = SEMVER;
|
|
1241
1426
|
exports.SYSTEM_DEFAULT_OUTPUT_UNIT = SYSTEM_DEFAULT_OUTPUT_UNIT;
|
|
1242
1427
|
exports.UNIT_CATALOG = UNIT_CATALOG;
|
|
@@ -1258,6 +1443,7 @@ exports.findBlockAtLine = findBlockAtLine;
|
|
|
1258
1443
|
exports.flattenFieldLeaves = flattenFieldLeaves;
|
|
1259
1444
|
exports.fromNotebookTag = fromNotebookTag;
|
|
1260
1445
|
exports.getMetricOwnershipLayer = getMetricOwnershipLayer;
|
|
1446
|
+
exports.getReferenceMetadata = getReferenceMetadata;
|
|
1261
1447
|
exports.isNotebookTag = isNotebookTag;
|
|
1262
1448
|
exports.isWorkoutSectionType = isWorkoutSectionType;
|
|
1263
1449
|
exports.lookupUnit = lookupUnit;
|
|
@@ -1267,6 +1453,7 @@ exports.normalizeFieldComponent = normalizeFieldComponent;
|
|
|
1267
1453
|
exports.normalizeFieldPath = normalizeFieldPath;
|
|
1268
1454
|
exports.ownershipRank = ownershipRank;
|
|
1269
1455
|
exports.parseDocumentSections = parseDocumentSections;
|
|
1456
|
+
exports.patchFrontmatterProperty = patchFrontmatterProperty;
|
|
1270
1457
|
exports.reconcileNoteBlocks = reconcileNoteBlocks;
|
|
1271
1458
|
exports.resolveLayer = resolveLayer;
|
|
1272
1459
|
exports.runAffordance = runAffordance;
|