@bitcobblers/wod-wiki-tools 0.36.2134 → 0.36.2136

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.
Files changed (59) hide show
  1. package/dist/bin/wod.cjs +274 -69
  2. package/dist/bin/wod.cjs.map +1 -1
  3. package/dist/bin/wod.mjs +5 -14
  4. package/dist/bin/wod.mjs.map +1 -1
  5. package/dist/{chunk-B3QJYJVI.mjs → chunk-6QNX4FED.mjs} +217 -52
  6. package/dist/chunk-6QNX4FED.mjs.map +1 -0
  7. package/dist/{chunk-EUQWEX6Z.mjs → chunk-CYKNTEGY.mjs} +3 -3
  8. package/dist/chunk-CYKNTEGY.mjs.map +1 -0
  9. package/dist/{compiler-KT6P3AC6.mjs → chunk-FZKXOYMJ.mjs} +4 -5
  10. package/dist/chunk-FZKXOYMJ.mjs.map +1 -0
  11. package/dist/{chunk-32FASQP5.mjs → chunk-MA6BBTWC.mjs} +54 -12
  12. package/dist/chunk-MA6BBTWC.mjs.map +1 -0
  13. package/dist/{chunk-K3GZZFAC.mjs → chunk-V23POHG2.mjs} +10 -9
  14. package/dist/chunk-V23POHG2.mjs.map +1 -0
  15. package/dist/compiler-CTPLIZJK.mjs +9 -0
  16. package/dist/compiler-CTPLIZJK.mjs.map +1 -0
  17. package/dist/index.cjs +274 -58
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +3 -1
  20. package/dist/index.d.ts +3 -1
  21. package/dist/index.mjs +5 -4
  22. package/dist/server/app.cjs +7 -6
  23. package/dist/server/app.cjs.map +1 -1
  24. package/dist/server/app.mjs +1 -1
  25. package/dist/server-JXECWS4A.mjs +11 -0
  26. package/dist/{server-3TJZDKQC.mjs.map → server-JXECWS4A.mjs.map} +1 -1
  27. package/dist/web/playground/assets/main-B-bffxwE.css +2 -0
  28. package/dist/web/playground/assets/main-iLSeEl2E.js +188 -0
  29. package/dist/web/playground/assets/{statementBuilderFlow-DXlHS86r.js → statementBuilderFlow-ugwi0fu0.js} +2 -2
  30. package/dist/web/playground/assets/{vendor-codemirror-BtJgoBjf.js → vendor-codemirror-C41SFn-r.js} +2 -2
  31. package/dist/web/playground/assets/vendor-g-NJOjvC.js +198 -0
  32. package/dist/web/playground/index.html +4 -4
  33. package/dist/web/playground/seed/core/chunks/canvas.20048125.json +1 -0
  34. package/dist/web/playground/seed/core/manifest.json +7 -7
  35. package/dist/web/playground/seed/core/report.html +11 -11
  36. package/dist/web/server/assets/main-B-bffxwE.css +2 -0
  37. package/dist/web/server/assets/main-CRyLxlPN.js +187 -0
  38. package/dist/web/server/assets/{statementBuilderFlow-CXugzTXB.js → statementBuilderFlow-40WaYjdq.js} +2 -2
  39. package/dist/web/server/assets/{vendor-codemirror-BtJgoBjf.js → vendor-codemirror-C41SFn-r.js} +2 -2
  40. package/dist/web/server/assets/vendor-g-NJOjvC.js +198 -0
  41. package/dist/web/server/index.html +4 -4
  42. package/dist/web/server/seed/core/chunks/canvas.20048125.json +1 -0
  43. package/dist/web/server/seed/core/manifest.json +7 -7
  44. package/dist/web/server/seed/core/report.html +9 -9
  45. package/package.json +6 -8
  46. package/dist/chunk-32FASQP5.mjs.map +0 -1
  47. package/dist/chunk-B3QJYJVI.mjs.map +0 -1
  48. package/dist/chunk-EUQWEX6Z.mjs.map +0 -1
  49. package/dist/chunk-K3GZZFAC.mjs.map +0 -1
  50. package/dist/compiler-KT6P3AC6.mjs.map +0 -1
  51. package/dist/server-3TJZDKQC.mjs +0 -11
  52. package/dist/web/playground/assets/main-Bhn9NHgQ.css +0 -2
  53. package/dist/web/playground/assets/main-Bj_mxNMk.js +0 -212
  54. package/dist/web/playground/assets/vendor-BlJqgFME.js +0 -201
  55. package/dist/web/playground/seed/core/chunks/canvas.054cd7db.json +0 -1
  56. package/dist/web/server/assets/main-Bhn9NHgQ.css +0 -2
  57. package/dist/web/server/assets/main-CfAVkURA.js +0 -211
  58. package/dist/web/server/assets/vendor-BlJqgFME.js +0 -201
  59. package/dist/web/server/seed/core/chunks/canvas.054cd7db.json +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/db.ts"],"names":[],"mappings":";;;;;;;AAgDO,IAAM,QAAA,GAAW,MAAgB,WAAA,EAAY,CAAE,WAAW;AAC1D,IAAM,MAAA,GAAS,MAAc,WAAA,EAAY,CAAE,SAAS;AACpD,IAAM,UAAA,GAAa,MAAkB,WAAA,EAAY,CAAE,aAAa;AAGvE,SAAS,WAAA,GAA0B;AACjC,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,IAAI,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,SAAS,WAAA,IAAe,OAAO,CAAA,CAAE,GAAA,KAAQ,WAAA,EAAa;AACpF,IAAA,MAAM,IAAI,MAAM,iEAAiE,CAAA;AAAA,EACnF;AACA,EAAA,MAAM,MAAM,CAAA,CAAE,OAAA,KAAY,OAAO,SAAA,KAAY,aAAa,SAAA,GAAU,MAAA,CAAA;AACpE,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAC/F,EAAA,OAAO,GAAA;AACT;AAmBA,IAAI,gBAAA;AAGG,SAAS,OAAA,GAA2B;AACzC,EAAA,gBAAA,KAAqB;AAAA;AAAA,IAA0B;AAAA,GAAmC;AAClF,EAAA,OAAO,gBAAA;AACT;AAeO,SAAS,cAAc,MAAA,EAAyB;AACrD,EAAA,MAAM,MAAA,GAAS,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,WAAA,IAAe,cAAA;AACpD,EAAA,OAAO,UAAS,CAAE,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,MAAM,CAAA;AACjD;AAgBA,eAAsB,SAAA,CACpB,QACA,IAAA,EACgB;AAChB,EAAA,IAAI,MAAA,KAAW,MAAA,IAAa,OAAO,MAAA,KAAW,QAAA,EAAU;AACtD,IAAA,OAAO,YAAA,CAAa,aAAA,CAAc,MAAM,CAAA,EAAG,IAAI,CAAA;AAAA,EACjD;AACA,EAAA,QAAQ,OAAO,IAAA;AAAM,IACnB,KAAK,QAAA;AACH,MAAA,OAAO,YAAA,CAAa,MAAA,CAAO,IAAA,EAAM,IAAI,CAAA;AAAA,IACvC,KAAK,OAAA;AACH,MAAA,OAAO,YAAA;AAAA,QACL,EAAE,WAAW,OAAA,EAAS,YAAA,EAAc,OAAO,GAAA,EAAK,iBAAA,EAAmB,OAAO,SAAA,EAAU;AAAA,QACpF,MAAA,CAAO,KAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF,KAAK,UAAA;AACH,MAAA,OAAO,YAAA,CAAa,EAAE,SAAA,EAAW,UAAA,EAAY,YAAA,EAAc,OAAO,GAAA,EAAI,EAAG,MAAA,CAAO,KAAA,EAAO,IAAI,CAAA;AAAA;AAEjG;AAEA,eAAe,YAAA,CAAa,UAAkB,IAAA,EAAmE;AAC/G,EAAA,MAAM,CAAC,EAAE,YAAA,EAAa,EAAG,GAAG,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAChD;AAAA;AAAA,MAA0B;AAAA,KAAgB;AAAA,IAC1C,OAAA;AAAQ,GACT,CAAA;AACD,EAAA,MAAM,UAAA,GAAa,MAAM,UAAA,IAAc,IAAA;AACvC,EAAA,IAAI,CAAC,UAAA,IAAc,CAAC,QAAO,CAAE,UAAA,CAAW,QAAQ,CAAA,EAAG;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,QAAQ,CAAA,oDAAA,CAAiD,CAAA;AAAA,EACnG;AACA,EAAA,IAAI,UAAA,EAAY,MAAA,EAAO,CAAE,SAAA,CAAU,QAAA,EAAS,CAAE,OAAA,CAAQ,QAAQ,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AACpF,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,cAAA,CAAe,YAAA,CAAa,EAAE,KAAK,CAAA,KAAA,EAAQ,QAAQ,CAAA,CAAA,EAAI,CAAC,CAAA;AACvE,EAAA,IAAI;AACF,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,GAAA,CAAI,gBAAgB,EAAE,CAAA;AAC5B,MAAA,MAAM,GAAA,CAAI,iBAAiB,EAAE,CAAA;AAAA,IAC/B,CAAA,MAAO;AAEL,MAAA,MAAM,IAAI,eAAA,CAAgB,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAmB;AACtD,QAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,QAAA,MAAM,IAAI,MAAM,CAAA,EAAG,OAAO,6CAAwC,EAAE,KAAA,EAAO,OAAO,CAAA;AAAA,MACpF,CAAC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,OAAA,EAAS,IAAI,IAAI,UAAA,CAAW,EAAE,CAAA,EAAG,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,MAAM,EAAA,CAAG,OAAM,EAAE;AAAA,EACxF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,GAAG,KAAA,EAAM;AACf,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAKA,eAAe,YAAA,CACb,GAAA,EACA,KAAA,EACA,IAAA,EACgB;AAChB,EAAA,MAAM,CAAC,EAAE,YAAA,EAAa,EAAG,GAAG,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAChD;AAAA;AAAA,MAA0B;AAAA,KAAwC;AAAA,IAGlE,OAAA;AAAQ,GACT,CAAA;AACD,EAAA,IAAI,EAAA;AACJ,EAAA,IAAI;AACF,IAAA,EAAA,GAAK,MAAM,YAAA,CAAa,GAAA,EAAK,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AACrD,IAAA,IAAI,IAAA,EAAM,eAAe,KAAA,EAAO;AAC9B,MAAA,MAAM,GAAA,CAAI,gBAAgB,EAAE,CAAA;AAAA,IAC9B,CAAA,MAAO;AACL,MAAA,MAAM,GAAA,CAAI,gBAAgB,EAAE,CAAA;AAC5B,MAAA,MAAM,GAAA,CAAI,iBAAiB,EAAE,CAAA;AAAA,IAC/B;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,EAAA,EAAI,KAAA,EAAM,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAChC,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,MAAA,EAAS,KAAK,CAAA,EAAA,EAAK,OAAO,GAAG,IAAA,EAAM,UAAA,KAAe,KAAA,GAAQ,yCAAA,GAAuC,EAAE,CAAA,CAAA;AAAA,MACnG,EAAE,OAAO,KAAA;AAAM,KACjB;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,OAAA,EAAS,IAAI,IAAI,UAAA,CAAW,EAAE,CAAA,EAAG,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAM,EAAA,CAAG,OAAM,EAAE;AACrF;AAOO,SAAS,eAAe,MAAA,EAA4B;AACzD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChC,EAAA,KAAA,CAAM,CAAC,CAAA,GAAK,KAAA,CAAM,CAAC,IAAI,EAAA,GAAQ,EAAA;AAC/B,EAAA,KAAA,CAAM,CAAC,CAAA,GAAK,KAAA,CAAM,CAAC,IAAI,EAAA,GAAQ,GAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,KAAK,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA;AACjE,EAAA,OAAO,CAAA,EAAG,IAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,EAAI,IAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,EAAI,IAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,EAAI,IAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,EAAI,IAAI,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACvJ;AAGO,SAAS,KAAA,CAAM,WAAmB,IAAA,EAAsB;AAC7D,EAAA,OAAO,cAAA,CAAe,UAAA,EAAW,CAAE,UAAA,CAAW,MAAM,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,IAAI,CAAA,CAAE,QAAQ,CAAA;AAC/F;AAGO,IAAM,kBAAA,GAAqB;AAO3B,SAAS,YAAA,CAAa,aAAqB,OAAA,EAAyB;AACzE,EAAA,IAAI,WAAA,IAAe,gBAAgB,GAAA,EAAK;AACtC,IAAA,OAAO,KAAA,CAAM,kBAAA,EAAoB,CAAA,QAAA,EAAW,QAAA,EAAS,CAAE,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,EAAG,WAAW,CAAC,CAAA,CAAE,CAAA;AAAA,EAC9F;AACA,EAAA,OAAO,KAAA,CAAM,kBAAA,EAAoB,CAAA,cAAA,EAAiB,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,CAAA;AAC7F;AAEO,SAAS,QAAA,GAAmB;AACjC,EAAA,OAAO,UAAA,GAAa,UAAA,EAAW;AACjC;AAMA,eAAe,OAAA,CAAQ,GAAA,EAAa,EAAA,EAAc,KAAA,EAAmC;AACnF,EAAA,OAAO,IAAI,QAAA,CAAS,EAAA,EAAI,GAAA,CAAI,eAAA,CAAgB,KAAK,CAAC,CAAA;AACpD;AAEA,eAAe,WAAA,CAAY,GAAA,EAAa,EAAA,EAAc,KAAA,EAAe,OAAe,IAAA,EAAkC;AACpH,EAAA,OAAO,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,GAAA,CAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,EAAE,IAAA,EAAK,EAAG,MAAA,EAAW,KAAK,CAAA;AAChF;AAGO,SAAS,iBAAiB,EAAA,EAA0B;AACzD,EAAA,MAAM,GAAA,GAAM,YAAqC,MAAM,OAAA,CAAQ,MAAM,OAAA,EAAQ,EAAG,IAAI,QAAQ,CAAA;AAC5F,EAAA,OAAO;AAAA,IACL,oBAAA,EAAsB,OAAO,KAAA,EAAO,GAAA,KAAA,CAAS,MAAM,GAAA,EAAI,EAAG,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,SAAA,IAAa,KAAA,IAAS,CAAA,CAAE,aAAa,GAAG,CAAA;AAAA,IAClH,iBAAA,EAAmB,OAAO,QAAA,KAAA,CAAc,MAAM,GAAA,EAAI,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,QAAQ,CAAA;AAAA,IAC1F,gBAAA,EAAkB,OAAO,MAAA,KAAA,CAAY,MAAM,GAAA,EAAI,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,MAAM,CAAA;AAAA,IACnF,kBAAA,EAAoB,OAAO,cAAA,KAAA,CAAoB,MAAM,GAAA,EAAI,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,KAAmB,cAAc,CAAA;AAAA,IAC7G,OAAA,EAAS,GAAA;AAAA,IACT,YAAA,EAAc,OAAO,QAAA,KAAa;AAChC,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,EAAA,CAAG,WAAA,CAAY,OAAO,EAAA,KAAO;AACjC,QAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAA;AAC9C,QAAA,KAAA,MAAW,OAAO,QAAA,EAAU,MAAM,IAAI,MAAA,CAAO,EAAA,EAAI,WAAW,GAAG,CAAA;AAAA,MACjE,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,iBAAA,EAAmB,OAAO,QAAA,EAAU,MAAA,KAAW;AAC7C,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,EAAA,CAAG,WAAA,CAAY,OAAO,EAAA,KAAO;AACjC,QAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAA;AAC9C,QAAA,MAAM,YAAa,MAAM,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,SAAS,CAAA,EAAqB,MAAA;AAAA,UACtE,CAAC,MAAM,CAAA,CAAE,QAAA,KAAa,YAAY,CAAA,CAAE,KAAA,KAAU,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW;AAAA,SAC1E;AACA,QAAA,KAAA,MAAW,GAAA,IAAO,UAAU,MAAM,GAAA,CAAI,WAAW,EAAA,EAAI,SAAA,EAAW,IAAI,EAAE,CAAA;AACtE,QAAA,KAAA,MAAW,OAAO,MAAA,EAAQ,MAAM,IAAI,MAAA,CAAO,EAAA,EAAI,WAAW,GAAG,CAAA;AAAA,MAC/D,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,YAAA,EAAc,OAAO,GAAA,KAAQ;AAC3B,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,EAAA,CAAG,WAAA,CAAY,OAAO,EAAA,KAAO;AACjC,QAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAA;AAC9C,QAAA,KAAA,MAAW,MAAM,GAAA,EAAK,MAAM,IAAI,UAAA,CAAW,EAAA,EAAI,WAAW,EAAE,CAAA;AAAA,MAC9D,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;AAMO,SAAS,gBAAgB,EAAA,EAA8B;AAC5D,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,YAAa,MAAM,OAAA,CAAQ,MAAM,OAAA,EAAQ,EAAG,IAAI,OAAO,CAAA;AAAA,IACpE,aAAA,EAAe,OAAO,OAAA,KAAY;AAChC,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,GAAA,CAAI,eAAA,CAAgB,OAAO,CAAA,EAAG,CAAC,GAAG,OAAO,CAAC,CAAA;AAC7E,MAAA,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,GAAA,KAAqB,QAAQ,MAAS,CAAA;AAAA,IAC5D,CAAA;AAAA,IACA,gBAAA,EAAkB,OAAO,KAAA,KAAU;AACjC,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,IAAA,GAAA,CAAS,MAAM,OAAA,CAAQ,GAAA,EAAK,EAAA,EAAI,MAAM,CAAA,EAAmB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA;AAC9F,MAAA,MAAM,MAA4B,EAAC;AACnC,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,KAAA,MAAW,GAAA,IAAO,MAAM,WAAA,CAAY,GAAA,EAAK,IAAI,WAAA,EAAa,QAAA,EAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AAC3E,UAAA,GAAA,CAAK,GAAA,CAAsB,MAAM,CAAA,GAAI,IAAA;AAAA,QACvC;AAAA,MACF;AACA,MAAA,OAAO,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,gBAAA,EAAkB,OAAO,MAAA,KAAW;AAClC,MAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,MAAA,MAAM,OAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK,IAAI,MAAM,CAAA;AAC9C,MAAA,MAAM,YAAoC,EAAC;AAC3C,MAAA,KAAA,MAAW,KAAK,OAAA,EAAS,SAAA,CAAU,CAAA,CAAE,EAAE,IAAI,CAAA,CAAE,KAAA;AAC7C,MAAA,MAAM,QAAS,MAAM,WAAA,CAAY,KAAK,EAAA,EAAI,WAAA,EAAa,WAAW,MAAM,CAAA;AACxE,MAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,UAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAAA,IAC9F,CAAA;AAAA,IACA,WAAA,EAAa,OAAO,OAAA,KAAY;AAE9B,MAAA,MAAM,SAAS,MAAA,CAAO,MAAM,SAAQ,EAAG,iBAAA,CAAkB,IAAI,OAAgB,CAAA;AAC7E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AACF;AAGO,SAAS,iBAAiB,EAAA,EAA+B;AAC9D,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,YAAa,MAAM,OAAA,CAAQ,MAAM,OAAA,EAAQ,EAAG,IAAI,aAAa,CAAA;AAAA,IAC3E,WAAA,EAAa,OAAO,OAAA,KAAY;AAC9B,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAM,OAAA,EAAQ,EAAG,iBAAA,CAAkB,EAAA,EAAI,EAAE,GAAG,OAAA,EAAS,IAAA,EAAM,QAAA,EAAmB,CAAA;AACpG,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AACF;AASO,SAAS,kBAAkB,EAAA,EAAgC;AAChE,EAAA,OAAO;AAAA,IACL,eAAe,YAAY;AACzB,MAAA,MAAM,SAAU,MAAM,OAAA,CAAQ,MAAM,OAAA,EAAQ,EAAG,IAAI,SAAS,CAAA;AAC5D,MAAA,MAAM,SAAkC,EAAC;AACzC,MAAA,KAAA,MAAW,MAAA,IAAU,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,GAAI,MAAA;AACnD,MAAA,KAAA,MAAW,UAAU,cAAA,EAAwC;AAC3D,QAAA,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,KAAM,MAAA;AAAA,MAC1B;AACA,MAAA,OAAO,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,IAC7B;AAAA,GACF;AACF;AAMO,SAAS,gBAAA,CAAiB,IAAc,KAAA,EAA2D;AACxG,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB,OAAO,KAAA,EAAO,GAAA,KAAQ,WAAA,CAAY,MAAM,OAAA,EAAQ,EAAG,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,GAAG;AAAA,GAC3F;AACF;AAgBA,eAAsB,aAAA,CAAc,IAAc,MAAA,EAAqC;AACrF,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,MAAA,CAAO,IAAI,GAAA,CAAI,eAAA,CAAgB,OAAO,CAAA,EAAG,MAAM,CAAA;AACtE,EAAA,OAAO,EAAE,IAAA,EAAK;AAChB;AAGA,eAAsB,gBAAA,CAAiB,IAAc,QAAA,EAAsD;AACzG,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,MAAA,CAAO,IAAI,GAAA,CAAI,eAAA,CAAgB,UAAU,CAAA,EAAG,QAAQ,CAAA;AAC9E,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,QAAA,CAAS,IAAI,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAS,EAAG,QAAW,iBAAiB,CAAA;AACrH,EAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAC3B;AAGA,eAAsB,eAAA,CAAgB,IAAc,IAAA,EAA4D;AAC9G,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,EAAA,MAAM,OAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK,IAAI,SAAS,CAAA;AACjD,EAAA,OAAO,QAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAC5C;AAGA,eAAsB,cAAA,CAAe,IAAc,IAAA,EAA4E;AAC7H,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,EAAQ;AAC1B,EAAA,MAAM,IAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,EAAK,IAAI,MAAM,CAAA;AAC3C,EAAA,OAAO,KAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAC3C","file":"chunk-CYKNTEGY.mjs","sourcesContent":["/**\n * Local SQLite seam for the `wod` CLI.\n *\n * Opens a libsql `file:` database, initializes the shared storage schema\n * (KV store tables + domain projections), and adapts the rows into the WQL\n * store interfaces — the same shape the playground builds over IndexedDB.\n *\n * Everything heavy is loaded lazily (`@libsql/client`,\n * `@bitcobblers/wod-wiki-storage/sql`, node `fs`/`crypto`) so browser\n * bundles that import the engine index never pull native drivers; the\n * dynamic specifiers stay external in the CLI bundle.\n */\n\nimport type { EventRecord } from '@bitcobblers/wod-wiki-core';\nimport type { IStorage, KeyDTO, Note, Session } from '@bitcobblers/wod-wiki-storage';\nimport type { RangeDTO, StoreDef } from '@bitcobblers/wod-wiki-storage';\nimport type {\n Database,\n LibsqlClient,\n SqlConnection,\n} from '@bitcobblers/wod-wiki-storage/sql';\nimport type { CliDatabaseConfig } from './config';\nimport type {\n BlockQueryStore,\n EventStore,\n EffortQueryStore,\n NoteQueryStore,\n WqlDomainReadResult,\n} from '@bitcobblers/wod-wiki-wql';\nimport { bundledEfforts } from '@bitcobblers/wod-wiki-lang';\n\n/** Structural CJS require — avoids the deprecated NodeJS namespace type. */\ntype CjsRequire = (id: string) => unknown;\n\n/** Minimal node builtin surfaces the CLI uses (kept out of browser bundles). */\nexport interface PathShim { resolve(...parts: string[]): string; join(...parts: string[]): string; dirname(p: string): string; basename(p: string): string }\nexport interface FsShim {\n mkdirSync(p: string, opts: { recursive: boolean }): void;\n existsSync(p: string): boolean;\n unlinkSync(p: string): void;\n readFileSync(p: string, encoding: string): string;\n writeFileSync(p: string, data: string, encoding: string): void;\n}\nexport interface HashShim { update(data: string): HashShim; digest(): Uint8Array }\nexport interface CryptoShim {\n createHash(algorithm: string): HashShim;\n randomUUID(): string;\n}\nexport const nodePath = (): PathShim => nodeRequire()('node:path') as PathShim;\nexport const nodeFs = (): FsShim => nodeRequire()('node:fs') as FsShim;\nexport const nodeCrypto = (): CryptoShim => nodeRequire()('node:crypto') as CryptoShim;\n\n/** Lazy CJS require — keeps node builtins out of browser bundles. */\nfunction nodeRequire(): CjsRequire {\n const g = globalThis as { process?: { versions?: Record<string, string> }; Bun?: unknown; require?: CjsRequire };\n if (typeof g.process?.versions?.node === 'undefined' && typeof g.Bun === 'undefined') {\n throw new Error('SQLite operations are only supported in Node / Bun environments');\n }\n const req = g.require ?? (typeof require === 'function' ? require : undefined);\n if (!req) throw new Error('SQLite operations require a CJS require shim (missing tsup banner?)');\n return req;\n}\n\n/** The storage/sql surface the CLI uses — structural mirror so the lazy import types check. */\nexport interface SqlApi {\n libsqlDatabase(client: LibsqlClient): Database;\n SqlStorage: new (db: Database) => IStorage;\n initializeStore(db: Database): Promise<void>;\n initializeDomain(db: Database): Promise<void>;\n verifyReadiness(db: Database): Promise<void>;\n storeDefinition(name: string): StoreDef;\n listRows(conn: SqlConnection, def: StoreDef, range?: RangeDTO, count?: number, indexName?: string): Promise<unknown[]>;\n getRow(conn: SqlConnection, def: StoreDef, key: KeyDTO): Promise<unknown | undefined>;\n getRows(conn: SqlConnection, def: StoreDef, keys: KeyDTO[]): Promise<(unknown | undefined)[]>;\n putRow(conn: SqlConnection, def: StoreDef, value: unknown): Promise<unknown>;\n deleteRows(conn: SqlConnection, def: StoreDef, keyOrRange: unknown): Promise<void>;\n refreshDomain(conn: SqlConnection, ops: unknown[]): Promise<unknown>;\n handleDomainQuery(db: Database, body: unknown): Promise<unknown>;\n}\n\nlet sqlModulePromise: Promise<SqlApi> | undefined;\n\n/** Lazily import the storage SQL subpath (kept external in the CLI bundle). */\nexport function loadSql(): Promise<SqlApi> {\n sqlModulePromise ??= import(/* @vite-ignore */ '@bitcobblers/wod-wiki-storage/sql') as Promise<SqlApi>;\n return sqlModulePromise;\n}\n\nexport interface CliDb {\n db: Database;\n storage: IStorage;\n /** Absolute path of the underlying .sqlite file — or the sanitized display\n * label (URL without credentials) for remote backends. */\n path: string;\n close(): Promise<void>;\n}\n\n/**\n * Resolve the effective database path: explicit flag wins, then\n * WOD_WIKI_DB, then ./wodwiki.db in the current working directory.\n */\nexport function resolveDbPath(dbPath?: string): string {\n const chosen = dbPath ?? process.env.WOD_WIKI_DB ?? './wodwiki.db';\n return nodePath().resolve(process.cwd(), chosen);\n}\n\n/**\n * Open the CLI database: a legacy local sqlite path (internal callers,\n * created/initialized as before) or a resolved backend config from ./config.\n *\n * opts.initialize (default true): run the schema + projection\n * initialization. false → verify the schema/projection guards only: a\n * missing local sqlite file is NOT created and yields an actionable\n * `wod init` error; remote targets are only probed, never created.\n *\n * opts.create (explicit init requests only, postgres): when the configured\n * PostgreSQL database is missing, openDatabase creates it through the admin\n * \"postgres\" database before initializing. Turso has no management API —\n * its hosted target must already exist.\n */\nexport async function openCliDb(\n target?: string | CliDatabaseConfig,\n opts?: { initialize?: boolean; create?: boolean },\n): Promise<CliDb> {\n if (target === undefined || typeof target === 'string') {\n return openSqliteDb(resolveDbPath(target), opts);\n }\n switch (target.kind) {\n case 'sqlite':\n return openSqliteDb(target.path, opts);\n case 'turso':\n return openRemoteDb(\n { DB_DRIVER: 'turso', DATABASE_URL: target.url, LIBSQL_AUTH_TOKEN: target.authToken },\n target.label,\n opts,\n );\n case 'postgres':\n return openRemoteDb({ DB_DRIVER: 'postgres', DATABASE_URL: target.url }, target.label, opts);\n }\n}\n\nasync function openSqliteDb(resolved: string, opts?: { initialize?: boolean; create?: boolean }): Promise<CliDb> {\n const [{ createClient }, sql] = await Promise.all([\n import(/* @vite-ignore */ '@libsql/client') as Promise<{ createClient: (config: { url: string }) => LibsqlClient }>,\n loadSql(),\n ]);\n const initialize = opts?.initialize ?? true;\n if (!initialize && !nodeFs().existsSync(resolved)) {\n throw new Error(`[wod] no database at ${resolved} — run \\`wod init\\` to create and initialize it`);\n }\n if (initialize) nodeFs().mkdirSync(nodePath().dirname(resolved), { recursive: true });\n const db = sql.libsqlDatabase(createClient({ url: `file:${resolved}` }));\n try {\n if (initialize) {\n await sql.initializeStore(db);\n await sql.initializeDomain(db);\n } else {\n // Guards only — no schema creation on an existing file either.\n await sql.verifyReadiness(db).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message} — run \\`wod init\\` to initialize it`, { cause: error });\n });\n }\n return { db, storage: new sql.SqlStorage(db), path: resolved, close: () => db.close() };\n } catch (error) {\n await db.close();\n throw error;\n }\n}\n\n/** Open a postgres/turso/remote-sqlite backend through the extracted server\n * adapter (dynamic on purpose: node-only subpath kept out of browser\n * bundles and external in the CLI bundle). Never falls back locally. */\nasync function openRemoteDb(\n env: Record<string, string | undefined>,\n label: string,\n opts?: { initialize?: boolean; create?: boolean },\n): Promise<CliDb> {\n const [{ openDatabase }, sql] = await Promise.all([\n import(/* @vite-ignore */ '@bitcobblers/wod-wiki-storage/sql/node') as Promise<{\n openDatabase: (env?: Record<string, string | undefined>, opts?: { create?: boolean }) => Promise<Database>;\n }>,\n loadSql(),\n ]);\n let db: Database | undefined;\n try {\n db = await openDatabase(env, { create: opts?.create });\n if (opts?.initialize === false) {\n await sql.verifyReadiness(db);\n } else {\n await sql.initializeStore(db);\n await sql.initializeDomain(db);\n }\n } catch (error) {\n await db?.close().catch(() => {});\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `[wod] ${label}: ${message}${opts?.initialize === false ? ' — run `wod init` to initialize it' : ''}`,\n { cause: error },\n );\n }\n return { db, storage: new sql.SqlStorage(db), path: label, close: () => db.close() };\n}\n\n// ---------------------------------------------------------------------------\n// Identity helpers\n// ---------------------------------------------------------------------------\n\n/** RFC-4122 byte munging + formatting over a 16-byte digest slice. */\nexport function formatV5Digest(digest: Uint8Array): string {\n const bytes = digest.slice(0, 16);\n bytes[6] = (bytes[6] & 0x0f) | 0x50; // version 5\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC-4122 variant\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, '0'));\n 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('')}`;\n}\n\n/** RFC-4122 v5 (SHA-1) name-based UUID — deterministic seed/note identity. */\nexport function uuid5(namespace: string, name: string): string {\n return formatV5Digest(nodeCrypto().createHash('sha1').update(namespace).update(name).digest());\n}\n\n/** Local namespace for wod-CLI derived identities (not shared with seed ids). */\nexport const CLI_UUID_NAMESPACE = 'c0ffee00-8b1a-4e2c-9d3f-5a6b7c8d9e0f';\n\n/**\n * Stable note identity for a parsed/run source: the same file always maps\n * to the same note, so re-parsing updates instead of duplicating. Stdin\n * sources content-address (no stable path exists).\n */\nexport function stableNoteId(sourceLabel: string, content: string): string {\n if (sourceLabel && sourceLabel !== '-') {\n return uuid5(CLI_UUID_NAMESPACE, `wod-cli:${nodePath().resolve(process.cwd(), sourceLabel)}`);\n }\n return uuid5(CLI_UUID_NAMESPACE, `wod-cli:stdin:${content.length}:${content.slice(0, 256)}`);\n}\n\nexport function randomId(): string {\n return nodeCrypto().randomUUID();\n}\n\n// ---------------------------------------------------------------------------\n// WQL store adapters over the sqlite rows\n// ---------------------------------------------------------------------------\n\nasync function allRows(sql: SqlApi, db: Database, store: string): Promise<unknown[]> {\n return sql.listRows(db, sql.storeDefinition(store));\n}\n\nasync function rowsByIndex(sql: SqlApi, db: Database, store: string, index: string, only: string): Promise<unknown[]> {\n return sql.listRows(db, sql.storeDefinition(store), { only }, undefined, index);\n}\n\n/** EventStore over the `events` table — whole-table reads, keyed writes. */\nexport function sqliteEventStore(db: Database): EventStore {\n const all = async (): Promise<EventRecord[]> => (await allRows(await loadSql(), db, 'events')) as EventRecord[];\n return {\n getEventsByTimeRange: async (start, end) => (await all()).filter((r) => r.timestamp >= start && r.timestamp <= end),\n getEventsByResult: async (resultId) => (await all()).filter((r) => r.resultId === resultId),\n getEventsForNote: async (noteId) => (await all()).filter((r) => r.noteId === noteId),\n getEventsByContent: async (blockContentId) => (await all()).filter((r) => r.blockContentId === blockContentId),\n scanAll: all,\n appendEvents: async (appended) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n for (const row of appended) await sql.putRow(tx, eventsDef, row);\n });\n },\n finalizeSummaries: async (resultId, finals) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n const existing = ((await sql.listRows(tx, eventsDef)) as EventRecord[]).filter(\n (r) => r.resultId === resultId && r.grain === 'summary' && r.origin !== 'user',\n );\n for (const row of existing) await sql.deleteRows(tx, eventsDef, row.id);\n for (const row of finals) await sql.putRow(tx, eventsDef, row);\n });\n },\n deleteEvents: async (ids) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n for (const id of ids) await sql.deleteRows(tx, eventsDef, id);\n });\n },\n };\n}\n\ninterface StoredTag { id: string; label: string; type?: string }\ninterface StoredNoteTag { id: string; noteId: string; tagId: string }\n\n/** NoteQueryStore over the notes/tags/note_tags rows + domain projection reads. */\nexport function sqliteNoteStore(db: Database): NoteQueryStore {\n return {\n getAllNotes: async () => (await allRows(await loadSql(), db, 'notes')) as never,\n getNotesByIds: async (noteIds) => {\n const sql = await loadSql();\n const rows = await sql.getRows(db, sql.storeDefinition('notes'), [...noteIds]) as Array<Note | undefined>;\n return rows.filter((row): row is Note => row !== undefined);\n },\n getNoteIdsForTag: async (label) => {\n const sql = await loadSql();\n const tags = ((await allRows(sql, db, 'tags')) as StoredTag[]).filter((t) => t.label === label);\n const ids: Record<string, true> = {};\n for (const tag of tags) {\n for (const row of await rowsByIndex(sql, db, 'note_tags', 'by-tag', tag.id)) {\n ids[(row as StoredNoteTag).noteId] = true;\n }\n }\n return new Set(Object.keys(ids));\n },\n getNoteTagLabels: async (noteId) => {\n const sql = await loadSql();\n const tagRows = (await allRows(sql, db, 'tags')) as StoredTag[];\n const labelById: Record<string, string> = {};\n for (const t of tagRows) labelById[t.id] = t.label;\n const links = (await rowsByIndex(sql, db, 'note_tags', 'by-note', noteId)) as StoredNoteTag[];\n return links.map((l) => labelById[l.tagId]).filter((l): l is string => typeof l === 'string');\n },\n queryDomain: async (request) => {\n // WQL's domain wire is a structural mirror of the storage DomainQuery.\n const result = await (await loadSql()).handleDomainQuery(db, request as never);\n return result as WqlDomainReadResult;\n },\n };\n}\n\n/** BlockQueryStore over the block_index rows + domain projection reads. */\nexport function sqliteBlockStore(db: Database): BlockQueryStore {\n return {\n getAllBlocks: async () => (await allRows(await loadSql(), db, 'block_index')) as never,\n queryDomain: async (request) => {\n const result = await (await loadSql()).handleDomainQuery(db, { ...request, plan: 'blocks' } as never);\n return result as WqlDomainReadResult;\n },\n };\n}\n\ninterface Slugged { slug: string }\n\n/**\n * EffortQueryStore: rows the seed wrote into the `efforts` registry win by\n * slug; the lang-bundled registry fills the rest (same fallback the\n * playground's RegistryEffortStore performs).\n */\nexport function sqliteEffortStore(db: Database): EffortQueryStore {\n return {\n getAllEfforts: async () => {\n const stored = (await allRows(await loadSql(), db, 'efforts')) as Slugged[];\n const bySlug: Record<string, unknown> = {};\n for (const effort of stored) bySlug[effort.slug] = effort;\n for (const effort of bundledEfforts as unknown as Slugged[]) {\n bySlug[effort.slug] ??= effort;\n }\n return Object.values(bySlug) as never;\n },\n };\n}\n\n/** Generic by-index reader over a store table — the QueryService seam shape. */\nexport interface IndexStore { getAllFromIndex(index: string, key: string): Promise<unknown[]> }\n\n/** Indexed reads over `block_efforts` / `tags` / `note_tags` rows. */\nexport function sqliteIndexStore(db: Database, store: 'block_efforts' | 'tags' | 'note_tags'): IndexStore {\n return {\n getAllFromIndex: async (index, key) => rowsByIndex(await loadSql(), db, store, index, key),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Download bundles (exchange feedstock)\n// ---------------------------------------------------------------------------\n\nexport interface NoteBundle {\n note: Note | undefined;\n}\n\nexport interface SessionBundle {\n session: Session;\n events: EventRecord[];\n}\n\n/** Fetch the whole authored Note. */\nexport async function getNoteBundle(db: Database, noteId: string): Promise<NoteBundle> {\n const sql = await loadSql();\n const note = await sql.getRow(db, sql.storeDefinition('notes'), noteId) as Note | undefined;\n return { note };\n}\n\n/** Fetch a session + its event/summary rows. */\nexport async function getSessionBundle(db: Database, resultId: string): Promise<SessionBundle | undefined> {\n const sql = await loadSql();\n const session = await sql.getRow(db, sql.storeDefinition('sessions'), resultId) as Session | undefined;\n if (!session) return undefined;\n const events = await sql.listRows(db, sql.storeDefinition('events'), { only: resultId }, undefined, 'by-result-grain') as EventRecord[];\n return { session, events };\n}\n\n/** Fetch one effort registry row by slug. */\nexport async function getEffortBySlug(db: Database, slug: string): Promise<Record<string, unknown> | undefined> {\n const sql = await loadSql();\n const efforts = (await allRows(sql, db, 'efforts')) as Array<{ slug: string } & Record<string, unknown>>;\n return efforts.find((e) => e.slug === slug);\n}\n\n/** Fetch tag rows of one type (e.g. 'equipment'). */\nexport async function listTagsByType(db: Database, type: string): Promise<Array<{ id: string; label: string; type?: string }>> {\n const sql = await loadSql();\n const tags = (await allRows(sql, db, 'tags')) as Array<{ id: string; label: string; type?: string }>;\n return tags.filter((t) => t.type === type);\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import { createRequire } from 'module';
2
- import './chunk-6L5ZDZJ7.mjs';
3
2
  import { parseScript, whiteboardParser, isEffortDiscipline } from '@bitcobblers/wod-wiki-lang';
4
3
  import { reconcileNoteBlocks, KNOWN_SECTION_WIDGETS, parseDocumentSections, blockContentId } from '@bitcobblers/wod-wiki-core';
5
4
  import { parseDashboardNote, buildDashboardDocument, isDashboardWidgetType, resolveWidgetType, parseQuery } from '@bitcobblers/wod-wiki-wql';
6
5
  import { execSync } from 'child_process';
7
- import { readFileSync, existsSync, mkdirSync, writeFileSync, rmSync, readdirSync } from 'fs';
6
+ import { writeFileSync, readFileSync, existsSync, mkdirSync, rmSync, readdirSync } from 'fs';
8
7
  import { join, relative } from 'path';
9
8
  import { createHash } from 'crypto';
10
9
 
@@ -725,6 +724,6 @@ ${shown}${more}`);
725
724
  return { manifest, outDir, totalFiles, reportPath, passMs };
726
725
  }
727
726
 
728
- export { buildBlockEffortRows, buildBlockIndexRows, chunkIdFor, collectCorpusMarkdown, compileSeedRow, discoverUncatalogedEfforts, feedDateToCreatedAt, generateSeed, loadExistingEffortMap, partitionIntoChunks, scaffoldDiscoveredEfforts, validateDashboardNote, validateWodBlockSyntax };
729
- //# sourceMappingURL=compiler-KT6P3AC6.mjs.map
730
- //# sourceMappingURL=compiler-KT6P3AC6.mjs.map
727
+ export { SEED_SCHEMA, buildBlockEffortRows, buildBlockIndexRows, chunkIdFor, collectCorpusMarkdown, compileSeedRow, discoverUncatalogedEfforts, feedDateToCreatedAt, generateSeed, loadExistingEffortMap, partitionIntoChunks, scaffoldDiscoveredEfforts, validateDashboardNote, validateWodBlockSyntax, writeBuildReport };
728
+ //# sourceMappingURL=chunk-FZKXOYMJ.mjs.map
729
+ //# sourceMappingURL=chunk-FZKXOYMJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/seedbuild/contract.ts","../src/seedbuild/effort-slugs.ts","../src/seedbuild/filename.ts","../src/seedbuild/frontmatter.ts","../src/seedbuild/effort-file.ts","../src/seedbuild/git-version.ts","../src/seedbuild/report.ts","../src/seedbuild/compiler.ts"],"names":["join","execSync","section","writeFileSync"],"mappings":"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","file":"chunk-FZKXOYMJ.mjs","sourcesContent":["import type { BlockEffort, BlockIndexRow, NoteBlock } from '@bitcobblers/wod-wiki-core';\nimport { KNOWN_SECTION_WIDGETS } from '@bitcobblers/wod-wiki-core';\n\nexport const SEED_SCHEMA = 8;\nexport const SEED_REGISTERED_WIDGETS = KNOWN_SECTION_WIDGETS;\n\n/** Source and all current derived rows commit as one chunk. */\nexport interface SeedRow {\n path: string;\n content: string;\n blocks: Record<string, NoteBlock>;\n blockIndex: BlockIndexRow[];\n blockEfforts: BlockEffort[];\n}\n\nexport type ChunkKind = 'notes';\nexport interface ManifestChunk {\n id: string;\n path: string;\n sha256: string;\n bytes: number;\n count: number;\n kind?: ChunkKind;\n}\nexport interface SeedManifest {\n schema: number;\n version: number;\n versionLabel?: string;\n commit?: string;\n dirty?: boolean;\n builtAt: string;\n chunks: ManifestChunk[];\n}\nexport interface SeedMetaRecord {\n key: string;\n schema: number;\n seedVersion: number;\n builtAt: string;\n importedAt: number;\n chunks: Record<string, { sha256: string; noteIds?: string[] }>;\n claim?: { owner: string; at: number } | null;\n}\nexport const SEED_BROADCAST_CHANNEL = 'wodwiki.seed';\nexport const EFFORTS_CHUNK_ID = 'efforts';\nexport const CANVAS_CHUNK_ID = 'canvas';\nexport const DASHBOARDS_CHUNK_ID = 'dashboards';\nexport const TEMPLATE_CHUNK_ID = 'template';\nexport function seedMetaKey(sourceId: string): string { return `seed:${sourceId}`; }\nexport function emptySeedMeta(key: string): SeedMetaRecord {\n return { key, schema: SEED_SCHEMA, seedVersion: 0, builtAt: '', importedAt: 0, chunks: {}, claim: null };\n}\nexport function catalogForChunkId(chunkId: string): string | undefined {\n const value = /^(?:collection|feed)\\.(.+)$/.exec(chunkId)?.[1];\n return value && value !== '_root' ? value : undefined;\n}\nexport function canvasRouteSlug(content: string): string | null {\n const fm = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(content);\n if (fm?.[1] && !/^template:\\s*canvas\\s*$/m.test(fm[1])) return null;\n return fm?.[1]?.match(/^route:\\s*(\\S+)\\s*$/m)?.[1]?.replace(/^\\//, '') || null;\n}\nexport function seedNoteSourceId(path: string, content: string, chunkId: string): string | undefined {\n const parts = path.split('/');\n const stem = (parts.at(-1) ?? '').replace(/\\.md$/i, '');\n const under = parts.slice(2).map((p) => p.replace(/\\.md$/i, '')).join('/');\n if (chunkId === CANVAS_CHUNK_ID) return `guides:${canvasRouteSlug(content) ?? under}`;\n if (chunkId === DASHBOARDS_CHUNK_ID) return 'dashboards';\n if (chunkId === EFFORTS_CHUNK_ID) return 'efforts';\n if (chunkId === TEMPLATE_CHUNK_ID) return 'playground';\n if (chunkId.startsWith('collection.')) {\n const catalog = catalogForChunkId(chunkId);\n return !catalog ? 'collection:_root' : stem.toLowerCase() === 'readme' ? `collection:${catalog}` : `collection:${catalog}/${stem}`;\n }\n if (chunkId.startsWith('feed.')) return `feed:feeds/${under}`;\n return undefined;\n}\n","/**\n * extractEffortSlugs — port of wod-wiki's\n * apps/playground/src/services/storage/StorageService.ts (the pure function\n * only). Derives canonical effort slugs referenced by script statements for\n * the block-efforts containment index.\n */\nimport type { ICodeStatement } from '@bitcobblers/wod-wiki-core';\n\nexport function extractEffortSlugs(statements: ICodeStatement[]): string[] {\n const slugs = new Set<string>();\n for (const statement of statements) {\n if (statement.exerciseId) {\n slugs.add(statement.exerciseId);\n } else {\n const effortMetric = statement.metrics?.getMetric?.('effort');\n const effort = effortMetric && typeof effortMetric.value === 'string' ? effortMetric.value : undefined;\n if (effort) {\n const slug = effort.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n if (slug) slugs.add(slug);\n }\n }\n }\n return Array.from(slugs);\n}\n","/**\n * fileToDisplayName — port of wod-wiki's\n * apps/playground/src/repositories/groupings.ts (display-name derivation\n * only). Block-index rows carry the same note titles the app renders, so\n * titles must derive identically on both sides.\n */\n\n/** Lowercased mid-title words — \"and\", \"of\", \"70.3\"-style fragments read wrong capped. */\nconst FILE_TITLE_STOP_WORDS: Record<string, true> = {\n and: true, or: true, of: true, for: true, to: true, in: true, on: true,\n at: true, by: true, with: true, the: true, a: true, an: true,\n};\n\n/**\n * Parse a filename into a display name.\n * \"simple-and-sinister.md\" -> \"Simple and Sinister\"\n */\nexport function fileToDisplayName(filename: string): string {\n const base = filename.replace(/\\.md$/, '');\n if (base.toUpperCase() === 'README') return 'Overview';\n // Strip leading \"day-01-\" prefixes if present, then humanise\n const cleaned = base.replace(/^day-\\d+-/, '');\n const tokens = cleaned.split(/[-_]/);\n const titled: string[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i]!;\n const next = tokens[i + 1];\n const after = tokens[i + 2];\n const prev = tokens[i - 1];\n // Race distances keep their dot: a lone 1-2-digit pair (\"70-3\" -> \"70.3\").\n // Longer numeric runs are dates (2009-12-01) or rep ladders (5-3-1) —\n // only an isolated pair between words is a distance.\n if (\n /^\\d{1,2}$/.test(token) && /^\\d{1,2}$/.test(next ?? '')\n && !/^\\d+$/.test(prev ?? '') && !/^\\d+$/.test(after ?? '')\n ) {\n titled.push(`${token}.${next}`);\n i++;\n continue;\n }\n if (titled.length > 0 && FILE_TITLE_STOP_WORDS[token.toLowerCase()]) {\n titled.push(token.toLowerCase());\n continue;\n }\n titled.push(token.charAt(0).toUpperCase() + token.slice(1));\n }\n return titled.join(' ');\n}\n","/**\n * Frontmatter parser — port of wod-wiki's apps/playground/src/lib/frontmatter.ts\n * (parseFrontmatter/getScalar/getList only; the editor-only helpers\n * (LinkWidget, YouTube, serialize) stay in the app).\n *\n * ponytail: semantics must match the app's parser exactly — the seed\n * compiler and the app runtime derive frontmatter from the same corpus.\n * Upgrade path: publish the parser in @bitcobblers/wod-wiki-core and import\n * from both sides.\n */\n\nexport interface ParsedFrontmatter {\n meta: Record<string, string | number | string[]>\n body: string\n}\n\n/** Leading `---` … `---` block; body is everything after the closing delimiter. */\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/;\n\n/** Strip matched wrapping quotes: `\"x\"` / `'x'` → `x`; mismatched quotes are kept.\n * Double-quoted values also collapse the serializer's escapes (`\\\\\"`, `\\\\\\\\`). */\nfunction unquote(value: string): string {\n return value.replace(/^(['\"])(.*)\\1$/, (_match, quote: string, inner: string) =>\n quote === '\"' ? inner.replace(/\\\\([\"\\\\])/g, '$1') : inner,\n );\n}\n\n/**\n * Parse the leading YAML frontmatter block of a markdown string.\n *\n * Semantics (mirrors the app):\n * - Scalar `key: value` (key `/^[A-Za-z][\\w.-]*$/`, dots allow flat nested\n * keys like `book.title`): wrapping quotes stripped; bare numeric strings\n * become `number`, quoted scalars always stay strings.\n * - `key:` with empty value followed by indented `- item` lines → `string[]`.\n * - `key:` with empty value and no list items → `''`.\n * - Inline `key: [a, b]` stays a plain scalar string.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = raw.match(FRONTMATTER_RE);\n if (!match) return { meta: {}, body: raw };\n return { meta: parseMetaLines(match[1].split(/\\r?\\n/)), body: raw.slice(match[0].length) };\n}\n\nfunction parseMetaLines(lines: string[]): ParsedFrontmatter['meta'] {\n const meta: ParsedFrontmatter['meta'] = {};\n\n for (let i = 0; i < lines.length; i++) {\n const keyMatch = lines[i].match(/^([A-Za-z][\\w.-]*)\\s*:(.*)$/);\n if (!keyMatch) continue; // indented/nested/list lines are not top-level keys\n\n const key = keyMatch[1];\n const rawVal = keyMatch[2].trim();\n\n if (rawVal === '') {\n const items: string[] = [];\n while (i + 1 < lines.length) {\n const itemMatch = lines[i + 1].match(/^\\s+-\\s+(.+)$/);\n if (!itemMatch) break;\n items.push(itemMatch[1].trim());\n i++;\n }\n meta[key] = items.length > 0 ? items : '';\n } else {\n const wasQuoted = /^(['\"])(.*)\\1$/.test(rawVal);\n const value = unquote(rawVal);\n const num = Number(value);\n meta[key] = !wasQuoted && value !== '' && !isNaN(num) ? num : value;\n }\n }\n\n return meta;\n}\n\n/** Scalar value at `key`, or `undefined` when absent or a list. */\nexport function getScalar(\n meta: ParsedFrontmatter['meta'],\n key: string,\n): string | number | undefined {\n const value = meta[key];\n return typeof value === 'string' || typeof value === 'number' ? value : undefined;\n}\n\n/** List value at `key`, or `[]` when absent or a scalar. */\nexport function getList(meta: ParsedFrontmatter['meta'], key: string): string[] {\n const value = meta[key];\n return Array.isArray(value) ? value : [];\n}\n","/**\n * Effort-file parsing — port of wod-wiki's\n * apps/playground/src/repositories/effort-markdown.ts (parse-frontmatter\n * direction only; effortToDocument/documentToEffort stay in the app).\n *\n * The compiler needs `parseEffortFile` to build the effort alias map used by\n * block-efforts row derivation. Semantics MUST match the app's runtime effort\n * materialization — alias/slug drift would desync the block plane from the\n * note plane.\n *\n * ponytail: duplicated rather than package-shared to keep this repo\n * standalone; upgrade path is the same published effort-format module\n * imported by both sides.\n */\nimport {\n isEffortDiscipline,\n type IEffort,\n type EffortRegistrySource,\n type IntensityTier,\n} from '@bitcobblers/wod-wiki-lang';\nimport { parseFrontmatter, getScalar, getList } from './frontmatter';\n\n/** Validate a parsed discipline against the canonical vocabulary. */\nfunction parseDiscipline(val: string | undefined): IEffort['baseAttributes']['discipline'] {\n if (!val) return undefined;\n const normalized = unquoteYaml(val.trim()).toLowerCase();\n if (isEffortDiscipline(normalized)) return normalized as IEffort['baseAttributes']['discipline'];\n console.warn(`[effort-file] unknown discipline '${val}' — treating as unset`);\n return undefined;\n}\n\nfunction unquoteYaml(val: string): string {\n if (val.startsWith('\"') && val.endsWith('\"')) {\n return val.slice(1, -1).replace(/\\\\([\"\\\\])/g, '$1');\n }\n if (val.startsWith(\"'\") && val.endsWith(\"'\")) {\n return val.slice(1, -1).replace(/\\\\'/g, \"'\");\n }\n return val;\n}\n\n/** Coerce a scalar from a nested block: booleans/numbers are coerced; everything else stays a string. */\nfunction coerceNestedScalar(raw: string): unknown {\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n if (raw !== '' && !Number.isNaN(Number(raw))) return Number(raw);\n return raw;\n}\n\n/**\n * Read a nested (`key:` followed by indented entries) section from frontmatter\n * lines. Two levels are supported (`derivation.coefficients.*`).\n */\nfunction readNestedSection(lines: string[], key: string): Record<string, unknown> | undefined {\n const start = lines.findIndex(l => new RegExp(`^${key}:\\\\s*$`).test(l));\n if (start === -1) return undefined;\n\n const result: Record<string, unknown> = {};\n let subKey: string | null = null;\n\n for (let i = start + 1; i < lines.length; i++) {\n const line = lines[i];\n if (/^\\S/.test(line)) break; // next top-level key ends the block\n\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const indent = line.length - line.trimStart().length;\n const m = trimmed.match(/^([\\w.-]+):\\s*(.*)$/);\n if (!m) continue;\n const [, k, rawVal] = m;\n\n if (indent === 2) {\n if (rawVal === '') {\n subKey = k;\n result[k] = {};\n } else {\n subKey = null;\n result[k] = coerceNestedScalar(rawVal);\n }\n } else if (indent >= 4 && subKey !== null) {\n (result[subKey] as Record<string, unknown>)[k] = coerceNestedScalar(rawVal);\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/** Parse a single bundled effort markdown file into an IEffort (null when malformed). */\nexport function parseEffortFile(raw: string): IEffort | null {\n const blockMatch = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!blockMatch) return null;\n\n const { meta, body } = parseFrontmatter(raw);\n const innerLines = blockMatch[1].split(/\\r?\\n/);\n\n const id = getScalar(meta, 'id');\n const slug = getScalar(meta, 'slug');\n const label = getScalar(meta, 'label');\n const aliases = getList(meta, 'aliases');\n\n const baseAttrs = readNestedSection(innerLines, 'baseAttributes');\n const hints = readNestedSection(innerLines, 'hints');\n const derivation = readNestedSection(innerLines, 'derivation');\n\n const metRaw = baseAttrs?.met;\n const met = typeof metRaw === 'number' ? metRaw : Number(metRaw);\n if (!id || !slug || !label || metRaw === undefined || Number.isNaN(met)) return null;\n\n const discipline = parseDiscipline(\n typeof baseAttrs?.discipline === 'string' ? baseAttrs.discipline : undefined,\n );\n const intensityTier = baseAttrs?.intensityTier;\n const trimmedBody = body.trim();\n\n return {\n id: String(id),\n slug: String(slug),\n label: String(label),\n aliases,\n baseAttributes: {\n met,\n ...(discipline ? { discipline } : {}),\n ...(intensityTier ? { intensityTier: intensityTier as IntensityTier } : {}),\n },\n registrySource: 'bundled' as EffortRegistrySource,\n ...(trimmedBody ? { body: trimmedBody } : {}),\n ...(hints ? { hints } : {}),\n ...(derivation ? { derivation: derivation as IEffort['derivation'] } : {}),\n };\n}\n","/**\n * Git-derived versioning — the seed artifact's version IS this repo's git\n * history. Every merged MR advances `version` (commit count), and\n * `versionLabel`/`commit` make an artifact traceable to its exact source\n * tree, so the app (and humans diffing manifests) can answer \"what changed\n * and what needs syncing\" from the manifest alone.\n */\nimport { execSync } from 'node:child_process';\n\nexport interface GitVersion {\n /** Monotonic commit count — the import-order version stamped on the manifest. */\n version: number;\n /** `git describe --tags --long --always --dirty`, e.g. `v1.2.0-4-gdeadbee`. */\n versionLabel: string;\n /** Full HEAD sha. */\n commit: string;\n /** True when built with uncommitted working-tree changes. */\n dirty: boolean;\n}\n\n/** Unversioned fallback for source trees without git history (e.g. exported tarballs). */\nexport const UNKNOWN_GIT_VERSION: GitVersion = {\n version: 0,\n versionLabel: 'unknown',\n commit: '',\n dirty: false,\n};\n\nexport function resolveGitVersion(repoRoot: string): GitVersion {\n try {\n const run = (args: string): string =>\n execSync(`git ${args}`, { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();\n const count = Number(run('rev-list --count HEAD'));\n return {\n version: Number.isFinite(count) && count > 0 ? count : 0,\n versionLabel: run('describe --tags --long --always --dirty'),\n commit: run('rev-parse HEAD'),\n dirty: run('status --porcelain') !== '',\n };\n } catch {\n return UNKNOWN_GIT_VERSION;\n }\n}\n","/**\n * Build report — a static HTML benchmark page for each seed build\n * (`dist/report.html`). Per-chunk sizes, row counts, pass timings, and the\n * git version stamp, so CI and contributors see build health at a glance.\n * Deliberately dependency-free (one string template + a file write).\n */\nimport { writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { SeedManifest } from './contract';\n\nexport interface BuildReportData {\n manifest: SeedManifest;\n /** Wall-clock ms for the full build. */\n totalMs: number;\n /** Per-pass timings (ms): corpus scan, block-index derivation, effort-row derivation, chunk writes. */\n passMs: { scan: number; blockIndex: number; parseGate: number; blockEfforts: number; write: number };\n /** Number of corpus markdown files. */\n fileCount: number;\n outDir: string;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\nfunction rowHtml(c: SeedManifest['chunks'][number]): string {\n const kind = c.kind ?? 'notes';\n return `<tr><td>${escapeHtml(c.id)}</td><td>${kind}</td><td>${c.count}</td><td>${(c.bytes / 1024).toFixed(1)} KB</td><td><code>${c.sha256.slice(0, 8)}</code></td></tr>`;\n}\n\nexport function writeBuildReport(outDir: string, data: BuildReportData): string {\n const { manifest, totalMs, passMs, fileCount } = data;\n const totalBytes = manifest.chunks.reduce((s, c) => s + c.bytes, 0);\n const dirtyBadge = manifest.dirty\n ? ' <strong style=\"color:#b45309\">(dirty working tree — not reproducible from <code>' + escapeHtml(manifest.commit ?? '') + '</code>)</strong>'\n : '';\n const html = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<title>Seed build report</title>\n<style>\n body { font-family: system-ui, sans-serif; max-width: 960px; margin: 2rem auto; padding: 0 1rem; color: #1f2937; }\n h1 { font-size: 1.4rem; } h2 { font-size: 1.1rem; margin-top: 2rem; }\n table { border-collapse: collapse; width: 100%; font-size: 0.9rem; }\n th, td { text-align: left; padding: 0.3rem 0.6rem; border-bottom: 1px solid #e5e7eb; }\n code { font-size: 0.85em; }\n dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.2rem 1rem; font-size: 0.95rem; }\n dt { font-weight: 600; }\n</style>\n</head>\n<body>\n<h1>Seed build report</h1>\n<h2>Version</h2>\n<dl>\n <dt>version</dt><dd>${manifest.version} <code>${escapeHtml(manifest.versionLabel ?? '')}</code>${dirtyBadge}</dd>\n <dt>commit</dt><dd><code>${escapeHtml(manifest.commit ?? 'unknown')}</code></dd>\n <dt>built at</dt><dd>${escapeHtml(manifest.builtAt)}</dd>\n <dt>schema</dt><dd>v${manifest.schema}</dd>\n</dl>\n<h2>Benchmarks</h2>\n<dl>\n <dt>total</dt><dd>${totalMs} ms</dd>\n <dt>corpus scan + partition</dt><dd>${passMs.scan} ms (${fileCount} files)</dd>\n <dt>block-index derivation</dt><dd>${passMs.blockIndex} ms</dd>\n <dt>block syntax gate</dt><dd>${passMs.parseGate} ms</dd>\n <dt>block-efforts derivation</dt><dd>${passMs.blockEfforts} ms</dd>\n <dt>chunk writes</dt><dd>${passMs.write} ms</dd>\n</dl>\n<h2>Chunks (${manifest.chunks.length}, ${(totalBytes / 1024).toFixed(0)} KB total)</h2>\n<table>\n<thead><tr><th>id</th><th>kind</th><th>rows</th><th>size</th><th>sha256</th></tr></thead>\n<tbody>\n${manifest.chunks.map(rowHtml).join('\\n')}\n</tbody>\n</table>\n</body>\n</html>\n`;\n const file = join(outDir, 'report.html');\n writeFileSync(file, html, 'utf8');\n return file;\n}\n","/** Compiles exact source, occurrence maps and sparse projections into atomic notes chunks. */\nimport { parseScript, whiteboardParser } from '@bitcobblers/wod-wiki-lang';\nimport { blockContentId, parseDocumentSections, reconcileNoteBlocks } from '@bitcobblers/wod-wiki-core';\nimport type { BlockEffort, BlockIndexRow } from '@bitcobblers/wod-wiki-storage';\nimport {\n buildDashboardDocument,\n isDashboardWidgetType,\n parseDashboardNote,\n parseQuery,\n resolveWidgetType,\n} from '@bitcobblers/wod-wiki-wql';\nimport {\n DASHBOARDS_CHUNK_ID,\n SEED_SCHEMA,\n SEED_REGISTERED_WIDGETS,\n TEMPLATE_CHUNK_ID,\n canvasRouteSlug,\n seedNoteSourceId,\n type ManifestChunk,\n type SeedManifest,\n type SeedRow,\n} from './contract';\nimport { extractEffortSlugs } from './effort-slugs';\nimport { fileToDisplayName } from './filename';\nimport { parseEffortFile } from './effort-file';\nimport { resolveGitVersion } from './git-version';\nimport { writeBuildReport } from './report';\nimport { parseFrontmatter } from './frontmatter';\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { join, relative } from 'node:path';\n\n// BlockEffort/BlockIndexRow row types come from @bitcobblers/wod-wiki-storage\n// (type-only import — chunk rows are plain JSON applied structurally by the\n// app, mirroring cli/seed.ts).\n\n/** Scan `dir` recursively for `*.md` files; returns POSIX paths relative to `dir`, sorted. */\nfunction listMarkdownFiles(dir: string, prefix = ''): string[] {\n if (!existsSync(dir)) return [];\n const out: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) out.push(...listMarkdownFiles(join(dir, entry.name), rel));\n else if (entry.isFile() && entry.name.endsWith('.md')) out.push(rel);\n }\n return out.sort();\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\nexport interface ChunkGroup {\n id: string;\n files: string[];\n}\n\nexport interface GenerateSeedOptions {\n /** The corpus directory (`markdown/`). Defaults to `<corpusRoot>/markdown`. */\n markdownDir?: string;\n /** Optional playground template file — the host passes its own; standalone builds omit the `template` chunk. */\n templateFile?: string;\n /**\n * Row path recorded for the template chunk (the runtime derives the\n * template note's id from it, so it must stay stable across builds). The\n * host pins its historical in-repo path; defaults to the path relative to\n * `corpusRoot`.\n */\n templateRowPath?: string;\n /** Output directory. Defaults to `<corpusRoot>/dist`. */\n outDir?: string;\n /**\n * Explicit manifest version (tests). Defaults to the corpus repo's git\n * commit count — see git-version.ts.\n */\n version?: number;\n /** Repo root the corpus paths resolve against and versioning derives from. Defaults to cwd. */\n corpusRoot?: string;\n /** Automatically scaffold markdown files for newly discovered efforts. */\n scaffoldDiscoveredEfforts?: boolean;\n}\n\nexport interface GenerateSeedResult {\n manifest: SeedManifest;\n outDir: string;\n totalFiles: number;\n reportPath: string;\n /** ms timings per pass (mirrored into report.html). */\n passMs: { scan: number; blockIndex: number; parseGate: number; blockEfforts: number; write: number };\n}\n\n// ── Corpus partition ──────────────────────────────────────────────────────\n\n/**\n * Map one `markdown/…` path to its chunk id. Returns null for files outside\n * the known corpora — callers MUST treat that as a parity failure so new\n * content directories cannot bypass the seed.\n */\nexport function chunkIdFor(relPath: string): string | null {\n const parts = relPath.split('/');\n if (parts[0] !== 'markdown' || parts.length < 2) return null;\n const corpus = parts[1];\n // markdown/<corpus>/<rest…>; a file directly under markdown/ has no corpus.\n if (parts.length === 2) return null;\n const slug = parts[2]?.replace(/\\.md$/, '');\n switch (corpus) {\n case 'canvas':\n case 'dashboards':\n case 'efforts':\n return corpus;\n case 'collections':\n return parts.length === 3 ? `collection._root` : `collection.${slug}`;\n case 'feeds':\n return parts.length === 3 ? `feed._root` : `feed.${slug}`;\n default:\n return null;\n }\n}\n\n/** Scan the markdown corpus; returns repo-relative POSIX paths of all .md files. */\nexport function collectCorpusMarkdown(markdownDir: string): string[] {\n return listMarkdownFiles(markdownDir).map((p) => `markdown/${p}`);\n}\n\n/** Group markdown corpus paths into chunk groups; throws on paths outside the known corpora. */\nexport function partitionIntoChunks(paths: string[]): ChunkGroup[] {\n const byId = new Map<string, string[]>();\n for (const p of paths) {\n const id = chunkIdFor(p);\n if (id === null) {\n throw new Error(\n `[generate-seed] Parity failure: '${p}' is not part of any known corpus ` +\n `(canvas | dashboards | efforts | collections | feeds). ` +\n `Extend chunkIdFor() if this is a new corpus.`,\n );\n }\n const list = byId.get(id);\n if (list) list.push(p);\n else byId.set(id, [p]);\n }\n return [...byId.entries()]\n .sort(([a], [b]) => (a < b ? -1 : 1))\n .map(([id, files]) => ({ id, files }));\n}\n\n// ── Dashboard gate (#906) ─────────────────────────────────────────────────\n\n/**\n * Validate one dashboard note in the locked #899 format: dashboard\n * frontmatter, a title, known widget types, WQL bodies that parse (and are\n * aggregate queries, not find queries), and every `$token` reference\n * declared. Returns the problems found (empty = valid).\n */\nexport function validateDashboardNote(raw: string): string[] {\n const problems: string[] = [];\n const { meta } = parseFrontmatter(raw);\n const { sections } = parseDashboardNote(raw);\n const doc = buildDashboardDocument(sections, meta);\n if (!doc.isDashboard) return ['file is not a dashboard note (missing dashboard frontmatter)'];\n if (doc.title === undefined) problems.push('dashboard has no title');\n if (doc.widgets.length < 3) problems.push(`dashboard has only ${doc.widgets.length} widgets (the locked format has ≥ 3)`);\n const declared = new Set(doc.tokens.map((t) => t.name));\n for (const widget of doc.widgets) {\n const where = `widget '${widget.title ?? widget.body.slice(0, 40)}'`;\n if (widget.title === undefined) problems.push(`${where}: missing title`);\n if (!isDashboardWidgetType(resolveWidgetType(widget.type))) {\n problems.push(`${where}: unknown widget type '${widget.type}'`);\n }\n const parsed = parseQuery(widget.body);\n if (parsed.error !== undefined) problems.push(`${where}: WQL parse error: ${parsed.error}`);\n for (const ref of [\n ...widget.body.matchAll(/\\$([A-Za-z][\\w-]*)/g),\n ...Object.values(widget.attributes).flatMap((v) => [...String(v).matchAll(/\\$([A-Za-z][\\w-]*)/g)]),\n ]) {\n if (!declared.has(ref[1])) problems.push(`${where}: undeclared token $${ref[1]}`);\n }\n }\n return problems;\n}\n\n/** Validate every dashboard file in a chunk group; throws on the first invalid file. */\nfunction gateDashboards(groups: ChunkGroup[], corpusRoot: string): void {\n for (const group of groups) {\n if (group.id !== DASHBOARDS_CHUNK_ID) continue;\n for (const p of group.files) {\n const problems = validateDashboardNote(readFileSync(join(corpusRoot, p), 'utf8'));\n if (problems.length > 0) {\n throw new Error(`[generate-seed] Dashboard validation failed for '${p}':\\n - ${problems.join('\\n - ')}`);\n }\n }\n }\n}\n\n// ── Block index derivation ────────────────────────────────────────────────\n\n\n/** Created-at from the corpus repo's git history (collections/guides), 0 fallback when unknown. */\nfunction getFileCreatedAt(file: string, repoRoot: string): number {\n try {\n const out = execSync(`git log -1 --format=%ct -- '${file}'`, { cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();\n const ts = Number(out) * 1000;\n return Number.isFinite(ts) && ts > 0 ? ts : 0;\n } catch {\n return 0;\n }\n}\n\n/** Created-at timestamp for a feed entry's date key (`yyyy-mm-dd` from the path). */\nexport function feedDateToCreatedAt(dateKey: string): number {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(dateKey)) return 0;\n const ts = Date.parse(`${dateKey}T00:00:00Z`);\n return Number.isNaN(ts) ? 0 : ts;\n}\n\n// canvasRouteSlug lives in contract.ts — one derivation shared by the\n// block plane (here) and the app's importer (note plane).\n\n\nexport function compileSeedRow(path: string, content: string, metadata: { routeId?: string; noteTitle?: string; sourceId?: string; createdAt?: number } = {}): SeedRow {\n let ordinal = 0;\n const blocks = reconcileNoteBlocks(content, { sourceRevision: 1, registeredWidgets: SEED_REGISTERED_WIDGETS, createId: () => `seed:${path}:${ordinal++}` });\n const noteId = metadata.routeId ?? path;\n const sections = parseDocumentSections(content);\n const blockIndex: BlockIndexRow[] = Object.values(blocks).map((block, position) => {\n const section = sections.find((section) => section.from === block.from && section.to === block.to);\n 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: 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 };\n });\n return { path, content, blocks, blockIndex, blockEfforts: [] };\n}\n\nexport function buildBlockIndexRows(markdownDir: string, corpusRoot: string): BlockIndexRow[] {\n const rows: BlockIndexRow[] = [];\n for (const path of collectCorpusMarkdown(markdownDir)) {\n const chunkId = chunkIdFor(path);\n if (!chunkId) continue;\n const content = readFileSync(join(corpusRoot, path), 'utf8');\n const parts = path.split('/');\n const stem = (parts.at(-1) ?? '').replace(/\\.md$/, '');\n const catalog = parts[2];\n const routeId = chunkId === 'canvas' ? canvasRouteSlug(content) ?? undefined : chunkId.startsWith('collection.') ? (stem.toLowerCase() === 'readme' ? catalog : `${catalog}/${stem}`) : chunkId.startsWith('feed.') ? parts.slice(1).join('/').replace(/\\.md$/, '') : undefined;\n const sourceId = seedNoteSourceId(path, content, chunkId);\n const createdAt = chunkId.startsWith('feed.') ? feedDateToCreatedAt(parts.at(-2) ?? '') : getFileCreatedAt(path, corpusRoot);\n rows.push(...compileSeedRow(path, content, { routeId, sourceId, createdAt }).blockIndex);\n }\n return rows;\n}\n\n/**\n * Syntax gate — every `wod` block's script must parse cleanly.\n *\n * Plain fences get a strict scan of the Lezer tree for error nodes\n * (`WhiteboardScript.errors` only carries mapper exceptions; the parser\n * recovers silently, so the tree is scanned directly) with `path:line`\n * diagnostics. Dialect-fenced blocks (`log:climbing`, …) are owned by the\n * dialect stack — their `key: value` lines are recovered by dialect\n * handlers, not the base grammar — so those gate on the exception channel\n * of a dialect-aware parse instead, matching how the app consumes them.\n */\nexport function validateWodBlockSyntax(blocks: BlockIndexRow[]): string[] {\n const problems: string[] = [];\n for (const block of blocks) {\n if (block.dataType !== 'wod' || !block.rawContent?.trim()) continue;\n const section = parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS })\n .find((s) => s.scriptBlock);\n const source = section?.scriptBlock?.content ?? block.rawContent;\n if (!source.trim()) continue;\n\n const where = block.sourcePath ?? block.noteId;\n if (section?.sport) {\n const parsed = parseScript(source, { sport: section.sport });\n for (const error of parsed.errors ?? []) {\n problems.push(`${where}: ${error.message}`);\n }\n continue;\n }\n\n const doc = source.endsWith('\\n') ? source : source + '\\n';\n const tree = whiteboardParser.parse(doc);\n tree.iterate({\n enter: (node) => {\n if (!node.type.isError) return;\n const line = doc.slice(0, node.from).split('\\n').length;\n const snippet = source.slice(node.from, Math.min(node.to, node.from + 60)).split('\\n')[0];\n problems.push(`${where}:${line} \\`${snippet}\\``);\n },\n });\n }\n return problems;\n}\n\n/**\n * Uncataloged effort discovered during workout block analysis.\n */\nexport interface DiscoveredEffort {\n slug: string;\n label: string;\n rawLabels: string[];\n}\n\n/** Static lookup — syntax/structure keywords and known non-effort labels that must never scaffold. */\nconst NON_EFFORT_SLUGS: Record<string, true> = {\n 'amrap': true, 'emom': true, 'tabata': true, 'for-time': true, 'rounds': true, 'sets': true,\n 'repetitions': true, 'count-down': true, 'total-reps': true,\n 'warmup': true, 'cooldown': true, 'cool-down': true, 'transition': true, 'rest': true, 'break': true, 'work': true,\n 'i-suck-at-this': true, 'isuckatthis': true, 'movement': true, 'movement-you': true, 'selected-exercise': true,\n 'training-setup': true, 'grade-system': true, 'hangs': true, 'warm-light-wind': true, 'basin': true, 'rock-canyon': true,\n 'b-onsight': true, 'a-redpoint': true, 'd-redpoint': true, 'v0-flash': true, 'v2-flash': true, 'v7-redpoint': true,\n 'avgrpe-mean': true, 'calculate': true, 'totalload-sum': true, 'query': true, 'by': true,\n '': true, '-': true, '...': true, 'x': true, 's': true, 'bw': true,\n};\n\nfunction formatDiscoveredLabel(raw: string): string {\n const clean = raw.replace(/[-_]+/g, ' ').trim();\n return clean\n .split(/\\s+/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join(' ');\n}\n\nexport function loadExistingEffortMap(markdownDir: string): {\n slugs: Set<string>;\n aliasToCanonical: Map<string, string>;\n} {\n const slugs = new Set<string>();\n const aliasToCanonical = new Map<string, string>();\n const effortsDir = join(markdownDir, 'efforts');\n for (const file of listMarkdownFiles(effortsDir)) {\n const raw = readFileSync(join(effortsDir, file), 'utf8');\n const parsed = parseEffortFile(raw);\n if (!parsed) continue;\n\n slugs.add(parsed.slug);\n aliasToCanonical.set(parsed.slug, parsed.slug);\n aliasToCanonical.set(parsed.label.toLowerCase(), parsed.slug);\n aliasToCanonical.set(parsed.slug.replace(/-/g, ' '), parsed.slug);\n\n for (const alias of parsed.aliases) {\n aliasToCanonical.set(alias.toLowerCase(), parsed.slug);\n aliasToCanonical.set(alias.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''), parsed.slug);\n }\n }\n\n return { slugs, aliasToCanonical };\n}\n\nexport function discoverUncatalogedEfforts(markdownDir: string, corpusRoot: string): DiscoveredEffort[] {\n const { slugs, aliasToCanonical } = loadExistingEffortMap(markdownDir);\n const blocks = buildBlockIndexRows(markdownDir, corpusRoot);\n const discovered = new Map<string, { label: string; rawLabels: Set<string> }>();\n\n for (const block of blocks) {\n if (block.dataType !== 'wod' || !block.rawContent) continue;\n const section = parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((section) => section.scriptBlock);\n const script = parseScript(section?.scriptBlock?.content ?? block.rawContent);\n for (const statement of script.statements) {\n const effortMetric = statement.metrics?.getMetric?.('effort');\n const effortLabel = (effortMetric && typeof effortMetric.value === 'string' ? effortMetric.value : undefined) ?? statement.exerciseId;\n if (!effortLabel) continue;\n\n const slugified = effortLabel.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');\n if (!slugified || NON_EFFORT_SLUGS[slugified]) continue;\n\n const canonical = aliasToCanonical.get(slugified) ?? aliasToCanonical.get(effortLabel.toLowerCase());\n if (canonical && slugs.has(canonical)) continue;\n\n const existing = discovered.get(slugified);\n if (existing) {\n existing.rawLabels.add(effortLabel);\n } else {\n discovered.set(slugified, {\n label: formatDiscoveredLabel(effortLabel),\n rawLabels: new Set([effortLabel]),\n });\n }\n }\n }\n\n return Array.from(discovered.entries()).map(([slug, data]) => ({\n slug,\n label: data.label,\n rawLabels: Array.from(data.rawLabels),\n }));\n}\n\nexport function scaffoldDiscoveredEfforts(\n discovered: DiscoveredEffort[],\n markdownDir: string,\n): string[] {\n const targetDir = join(markdownDir, 'efforts', 'discovered');\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n const createdPaths: string[] = [];\n for (const effort of discovered) {\n const filePath = join(targetDir, `${effort.slug}.md`);\n if (existsSync(filePath)) continue;\n\n const aliases = effort.rawLabels\n .filter((l) => l.toLowerCase() !== effort.label.toLowerCase())\n .map((l) => ` - \"${l.replace(/\"/g, '\\\\\"')}\"`);\n\n const content = [\n '---',\n `id: effort-bundled-${effort.slug}`,\n `slug: ${effort.slug}`,\n `label: \"${effort.label.replace(/\"/g, '\\\\\"')}\"`,\n aliases.length > 0 ? `aliases:\\n${aliases.join('\\n')}` : 'aliases: []',\n 'baseAttributes:',\n ' met: 5.0',\n ' discipline: general',\n ' intensityTier: moderate',\n 'registrySource: bundled',\n '---',\n '',\n ].join('\\n');\n\n writeFileSync(filePath, content, 'utf8');\n createdPaths.push(filePath);\n }\n\n return createdPaths;\n}\n\n/**\n * Derive BlockEffort[] containment rows from the block-index row set.\n * Requires a second pass over the source markdown to parse the script AST,\n * which is safe because the corpus is static and the pass is compile-time.\n */\nexport function buildBlockEffortRows(markdownDir: string, corpusRoot: string, blocks: BlockIndexRow[] = buildBlockIndexRows(markdownDir, corpusRoot)): BlockEffort[] {\n const efforts: BlockEffort[] = [];\n const { aliasToCanonical } = loadExistingEffortMap(markdownDir);\n for (const block of blocks) {\n if (block.dataType !== 'wod' || !block.rawContent) continue;\n const section = parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((section) => section.scriptBlock);\n const script = parseScript(section?.scriptBlock?.content ?? block.rawContent);\n const effortSlugs = extractEffortSlugs(script.statements);\n const linked = new Set<string>();\n for (const rawSlug of effortSlugs) {\n const norm = rawSlug.toLowerCase().trim();\n const canonicalSlug =\n aliasToCanonical.get(norm) ??\n aliasToCanonical.get(norm.replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')) ??\n norm.replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');\n if (!canonicalSlug || NON_EFFORT_SLUGS[canonicalSlug] || NON_EFFORT_SLUGS[norm]) {\n continue;\n }\n if (linked.has(canonicalSlug)) continue;\n linked.add(canonicalSlug);\n efforts.push({\n id: `${block.id}:${canonicalSlug}`,\n noteId: block.noteId,\n blockId: block.blockId,\n blockContentId: block.blockContentId,\n effortSlug: canonicalSlug,\n isStatic: block.isStatic,\n sourcePath: block.sourcePath,\n createdAt: block.createdAt,\n });\n }\n }\n return efforts;\n}\n\n\n// ── Generation ────────────────────────────────────────────────────────────\n\nfunction sha256Hex(data: string | Buffer): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nexport function generateSeed(options: GenerateSeedOptions = {}): GenerateSeedResult {\n const t0 = Date.now();\n const passMs = { scan: 0, blockIndex: 0, parseGate: 0, blockEfforts: 0, write: 0 };\n const corpusRoot = options.corpusRoot ?? process.cwd();\n const markdownDir = options.markdownDir ?? join(corpusRoot, 'markdown');\n const outDir = options.outDir ?? join(corpusRoot, 'dist');\n const gitVersion = options.version !== undefined\n ? { ...resolveGitVersion(corpusRoot), version: options.version }\n : resolveGitVersion(corpusRoot);\n if (options.scaffoldDiscoveredEfforts) {\n const discovered = discoverUncatalogedEfforts(markdownDir, corpusRoot);\n if (discovered.length > 0) {\n scaffoldDiscoveredEfforts(discovered, markdownDir);\n }\n }\n\n const tScan = Date.now();\n const paths = collectCorpusMarkdown(markdownDir);\n const groups = partitionIntoChunks(paths);\n gateDashboards(groups, corpusRoot);\n if (options.templateFile && existsSync(options.templateFile)) {\n const templateRowPath = options.templateRowPath\n ?? relative(corpusRoot, options.templateFile).split('\\\\').join('/');\n groups.push({ id: TEMPLATE_CHUNK_ID, files: [templateRowPath] });\n }\n passMs.scan = Date.now() - tScan;\n\n const tBlockIndex = Date.now();\n const blockRows = buildBlockIndexRows(markdownDir, corpusRoot);\n passMs.blockIndex = Date.now() - tBlockIndex;\n const tParseGate = Date.now();\n const syntaxProblems = validateWodBlockSyntax(blockRows);\n passMs.parseGate = Date.now() - tParseGate;\n if (syntaxProblems.length > 0) {\n const shown = syntaxProblems.slice(0, 20).map((p) => ` ${p}`).join('\\n');\n const more = syntaxProblems.length > 20 ? `\\n … and ${syntaxProblems.length - 20} more` : '';\n throw new Error(`[wod build] block syntax gate failed — ${syntaxProblems.length} block(s) do not parse:\\n${shown}${more}`);\n }\n\n const chunksDir = join(outDir, 'chunks');\n rmSync(outDir, { recursive: true, force: true });\n mkdirSync(chunksDir, { recursive: true });\n\n const manifestChunks: ManifestChunk[] = [];\n const tBlockEfforts = Date.now();\n const effortRows = buildBlockEffortRows(markdownDir, corpusRoot, blockRows);\n passMs.blockEfforts = Date.now() - tBlockEfforts;\n const blocksByPath = new Map<string, BlockIndexRow[]>();\n const effortsByPath = new Map<string, BlockEffort[]>();\n for (const row of blockRows) {\n const rows = blocksByPath.get(row.sourcePath!) ?? [];\n rows.push(row); blocksByPath.set(row.sourcePath!, rows);\n }\n for (const row of effortRows) {\n const rows = effortsByPath.get(row.sourcePath!) ?? [];\n rows.push(row); effortsByPath.set(row.sourcePath!, rows);\n }\n let totalFiles = 0;\n\n const tWrite = Date.now();\n for (const { id, files } of groups) {\n // The template chunk's row path is the host-pinned historical identity,\n // not a path inside this repo — read it from the template file itself.\n const templateSource = id === TEMPLATE_CHUNK_ID ? options.templateFile : undefined;\n const rows: SeedRow[] = files.map((p) => {\n const raw = readFileSync(templateSource ?? join(corpusRoot, p), 'utf8');\n const content = id === TEMPLATE_CHUNK_ID ? raw.replace(/\\$CURSOR/g, '') : raw;\n const compiled = compileSeedRow(p, content);\n compiled.blockIndex = blocksByPath.get(p) ?? compiled.blockIndex;\n compiled.blockEfforts = effortsByPath.get(p) ?? [];\n return compiled;\n });\n const bytes = Buffer.from(JSON.stringify(rows), 'utf8');\n const sha = sha256Hex(bytes);\n const file = `chunks/${id}.${sha.slice(0, 8)}.json`;\n writeFileSync(join(outDir, file), bytes);\n manifestChunks.push({ id, path: file, sha256: sha, bytes: bytes.length, count: rows.length });\n totalFiles += rows.length;\n }\n\n passMs.write = Date.now() - tWrite;\n\n const manifest: SeedManifest = {\n schema: SEED_SCHEMA,\n version: gitVersion.version,\n versionLabel: gitVersion.versionLabel,\n commit: gitVersion.commit,\n dirty: gitVersion.dirty,\n builtAt: new Date().toISOString(),\n chunks: manifestChunks,\n };\n writeFileSync(join(outDir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\\n');\n\n const reportPath = writeBuildReport(outDir, {\n manifest,\n totalMs: Date.now() - t0,\n passMs,\n fileCount: paths.length,\n outDir,\n });\n\n return { manifest, outDir, totalFiles, reportPath, passMs };\n}\n"]}
@@ -1,18 +1,61 @@
1
1
  import { createRequire } from 'module';
2
- import { openCliDb, nodePath, nodeFs } from './chunk-EUQWEX6Z.mjs';
3
- import { createHandler } from './chunk-K3GZZFAC.mjs';
2
+ import { openCliDb, nodePath, nodeFs } from './chunk-CYKNTEGY.mjs';
3
+ import { createHandler } from './chunk-V23POHG2.mjs';
4
+ import http from 'http';
5
+ import { Readable } from 'stream';
4
6
 
5
7
  if (typeof globalThis.require === 'undefined') {
6
8
  try { globalThis.require = createRequire(import.meta.url); } catch {}
7
9
  }
8
-
9
- // src/cli/server.ts
10
- function bun() {
10
+ function withResolvers() {
11
+ let resolve;
12
+ let reject;
13
+ const promise = new Promise((res, rej) => {
14
+ resolve = res;
15
+ reject = rej;
16
+ });
17
+ return { promise, resolve, reject };
18
+ }
19
+ function startHttpServer(handler, host, port) {
11
20
  const b = globalThis.Bun;
12
- if (!b) {
13
- throw new Error("wod server/playground requires the Bun runtime (https://bun.sh)");
21
+ if (b?.serve) {
22
+ const s = b.serve({ port, hostname: host, fetch: handler });
23
+ return Promise.resolve({ stop: () => s.stop() });
14
24
  }
15
- return b;
25
+ const { promise, resolve, reject } = withResolvers();
26
+ const server = http.createServer(async (req, res) => {
27
+ try {
28
+ const url = new URL(req.url || "/", `http://${req.headers.host || `${host}:${port}`}`);
29
+ const hasBody = req.method !== "GET" && req.method !== "HEAD";
30
+ const webReq = new Request(url, {
31
+ method: req.method,
32
+ headers: req.headers,
33
+ body: hasBody ? Readable.toWeb(req) : null,
34
+ ...hasBody ? { duplex: "half" } : {}
35
+ });
36
+ const webRes = await handler(webReq);
37
+ res.writeHead(webRes.status, Object.fromEntries(webRes.headers.entries()));
38
+ if (webRes.body) {
39
+ Readable.fromWeb(webRes.body).pipe(res);
40
+ } else {
41
+ res.end();
42
+ }
43
+ } catch {
44
+ res.statusCode = 500;
45
+ res.end("internal server error");
46
+ }
47
+ });
48
+ server.once("error", reject);
49
+ server.listen(port, host, () => {
50
+ resolve({
51
+ stop: () => {
52
+ const close = withResolvers();
53
+ server.close(() => close.resolve());
54
+ return close.promise;
55
+ }
56
+ });
57
+ });
58
+ return promise;
16
59
  }
17
60
  function moduleDir() {
18
61
  const p = nodePath();
@@ -66,7 +109,6 @@ function resolveBind(mode, options) {
66
109
  return { host, port };
67
110
  }
68
111
  async function runCliServer(mode, options, writeOut) {
69
- const runtime = bun();
70
112
  const { host, port } = resolveBind(mode, options);
71
113
  let db;
72
114
  let dbLabel = "no database";
@@ -87,7 +129,7 @@ async function runCliServer(mode, options, writeOut) {
87
129
  try {
88
130
  const dist = resolveDist(mode, options);
89
131
  const handler = createHandler(db?.db ?? null, { playgroundDist: dist });
90
- server = runtime.serve({ port, hostname: host, fetch: handler });
132
+ server = await startHttpServer(handler, host, port);
91
133
  if (mode === "server") {
92
134
  writeOut(`wod server: http://${host}:${port} \u2014 ${dbLabel} \xB7 dist ${dist}`);
93
135
  } else {
@@ -119,5 +161,5 @@ async function runCliServer(mode, options, writeOut) {
119
161
  }
120
162
 
121
163
  export { runCliServer };
122
- //# sourceMappingURL=chunk-32FASQP5.mjs.map
123
- //# sourceMappingURL=chunk-32FASQP5.mjs.map
164
+ //# sourceMappingURL=chunk-MA6BBTWC.mjs.map
165
+ //# sourceMappingURL=chunk-MA6BBTWC.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/server.ts"],"names":["dist"],"mappings":"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","file":"chunk-MA6BBTWC.mjs","sourcesContent":["/**\n * server.ts — `wod server` (alias `serve`) / `wod playground` (Bun-only front\n * door).\n *\n * Serves the packaged engine stack: the shared fetch handler shipped in this\n * package (the same code the Docker image serves) plus the frontend build\n * packaged under the engine's dist/web/ — no repository checkout, no runtime\n * build.\n *\n * server probes the configured database first (never creates schema —\n * that's `wod init`), then serves API + SPA.\n * playground serves the browser-storage SPA build and never opens a database\n * (every /api request answers 404).\n *\n * Retains the event loop until SIGINT/SIGTERM; shutdown drains in-flight\n * requests before closing the database.\n */\n\nimport http from 'node:http';\nimport { Readable } from 'node:stream';\nimport { openCliDb, nodeFs, nodePath } from './db';\nimport type { CliDatabaseConfig } from './config';\nimport type { CliDb } from './db';\nimport { createHandler } from '../server/app';\ntype WriteOut = (text: string) => void;\n\nexport type CliServerMode = 'server' | 'playground';\n\nexport interface CliServerOptions {\n /** Resolved database configuration. REQUIRED for 'server'; ignored — never\n * opened or validated — for 'playground'. */\n database?: CliDatabaseConfig;\n host?: string;\n port?: string;\n /** Explicit dist directory (flag or PLAYGROUND_DIST); must already exist. */\n dist?: string;\n /** Merged CLI environment (process env + .env). */\n env: Record<string, string | undefined>;\n}\n\ninterface HttpServerLike {\n stop(): Promise<void>;\n}\n\nfunction withResolvers<T>() {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n}\n\nfunction startHttpServer(\n handler: (request: Request) => Promise<Response>,\n host: string,\n port: number,\n): Promise<HttpServerLike> {\n const b = (globalThis as { Bun?: { serve(opts: { port: number; hostname: string; fetch: (req: Request) => Promise<Response> }): { stop(): Promise<void> } } }).Bun;\n if (b?.serve) {\n const s = b.serve({ port, hostname: host, fetch: handler });\n return Promise.resolve({ stop: () => s.stop() });\n }\n\n // ponytail: node:http adapter streams Web Request/Response in pure Node (v18+) without express/fastify dependencies\n const { promise, resolve, reject } = withResolvers<HttpServerLike>();\n const server = http.createServer(async (req, res) => {\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host || `${host}:${port}`}`);\n const hasBody = req.method !== 'GET' && req.method !== 'HEAD';\n const webReq = new Request(url, {\n method: req.method,\n headers: req.headers as Record<string, string>,\n body: hasBody ? (Readable.toWeb(req) as unknown as BodyInit) : null,\n ...(hasBody ? { duplex: 'half' } : {}),\n } as RequestInit);\n const webRes = await handler(webReq);\n res.writeHead(webRes.status, Object.fromEntries(webRes.headers.entries()));\n if (webRes.body) {\n Readable.fromWeb(webRes.body as any).pipe(res);\n } else {\n res.end();\n }\n } catch {\n res.statusCode = 500;\n res.end('internal server error');\n }\n });\n\n server.once('error', reject);\n server.listen(port, host, () => {\n resolve({\n stop: () => {\n const close = withResolvers<void>();\n server.close(() => close.resolve());\n return close.promise;\n },\n });\n });\n return promise;\n}\n\n/**\n * This module's directory, robust across shipped layouts: ESM via\n * import.meta.url (works under node and Bun; esbuild shims it in CJS too) and\n * Bun's import.meta.dir. ESM code splitting may relocate this module to a\n * chunk at dist/ root, so never assume dist/cli.\n */\nfunction moduleDir(): string {\n const p = nodePath();\n const meta: { dir?: unknown; url?: unknown } = import.meta; // Bun adds `dir`; the TS lib knows neither.\n if (typeof meta.dir === 'string') return p.resolve(meta.dir);\n if (typeof meta.url === 'string' && meta.url.startsWith('file:')) {\n return p.resolve(p.dirname(decodeURIComponent(new URL('.', meta.url).pathname)));\n }\n throw new Error('wod server/playground: cannot determine the installed engine module directory');\n}\n\n/**\n * The installed engine package root: nearest enclosing package.json belonging\n * to this package, walking up from the executing module (dist/cli, a split\n * chunk at dist/ root, dist/bin, or src/cli in a checkout).\n */\nfunction engineRoot(): string {\n const p = nodePath();\n const fs = nodeFs();\n for (let dir = moduleDir(); ; dir = p.dirname(dir)) {\n try {\n if (JSON.parse(fs.readFileSync(p.resolve(dir, 'package.json'), 'utf8')).name === '@bitcobblers/wod-wiki-tools') return dir;\n } catch { /* no manifest here — keep walking */ }\n const parent = p.dirname(dir);\n if (parent === dir) break;\n }\n throw new Error('wod server/playground: cannot locate the installed @bitcobblers/wod-wiki-tools package');\n}\n\n/**\n * Resolve the frontend dist directory. The packaged default lives inside the\n * installed engine module (dist/web/server or dist/web/playground); an\n * explicit --dist/PLAYGROUND_DIST is cwd-relative and must already contain a\n * built SPA (index.html). Nothing is built at runtime.\n */\nfunction resolveDist(mode: CliServerMode, options: CliServerOptions): string {\n const p = nodePath();\n const explicit = options.dist?.trim() || options.env.PLAYGROUND_DIST?.trim() || undefined;\n if (explicit) {\n const dist = p.resolve(explicit); // cwd-relative override\n if (!nodeFs().existsSync(p.resolve(dist, 'index.html'))) {\n throw new Error(\n `wod ${mode}: no built frontend (index.html) at ${dist} — --dist/PLAYGROUND_DIST must `\n + 'point at an already-built directory (the CLI never builds frontends at runtime)',\n );\n }\n return dist;\n }\n const dist = p.resolve(engineRoot(), 'dist', 'web', mode === 'playground' ? 'playground' : 'server');\n if (!nodeFs().existsSync(p.resolve(dist, 'index.html'))) {\n throw new Error(\n `wod ${mode}: packaged frontend missing — expected ${dist}/index.html. `\n + 'Reinstall @bitcobblers/wod-wiki-tools (bun add @bitcobblers/wod-wiki-tools), '\n + 'or rebuild the release assets from a checkout (bun run build:cli) and reinstall the package.',\n );\n }\n return dist;\n}\n\n/** Validate bind address first: flag > HOST/PORT env > loopback:3000. */\nfunction resolveBind(mode: CliServerMode, options: CliServerOptions): { host: string; port: number } {\n const host = options.host?.trim() || options.env.HOST?.trim() || '127.0.0.1';\n const rawPort = options.port?.trim() || options.env.PORT?.trim() || '3000';\n const port = Number(rawPort);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`wod ${mode}: invalid port ${JSON.stringify(rawPort)} (need integer 1..65535)`);\n }\n return { host, port };\n}\n\n/**\n * Start the shared server for `wod server` / `wod playground`. Throws on any\n * startup failure; on success it never returns until SIGINT/SIGTERM (drain,\n * close database, exit 0).\n */\nexport async function runCliServer(\n mode: CliServerMode,\n options: CliServerOptions,\n writeOut: WriteOut,\n): Promise<void> {\n const { host, port } = resolveBind(mode, options); // Validate bind before opening anything.\n\n // Server probes the database BEFORE binding a socket: a missing/uninitialized\n // database refuses with `wod init` guidance.\n let db: CliDb | undefined;\n let dbLabel = 'no database';\n if (mode === 'server') {\n const database = options.database; // hoisted so the guard's narrowing sticks\n if (!database) {\n throw new Error('wod server: no database configuration resolved — this is a runner bug (expected resolveDatabaseConfig output)');\n }\n try {\n db = await openCliDb(database, { initialize: false });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`wod server: database not ready — run \\`wod init\\` first. ${message}`, { cause: e });\n }\n dbLabel = db.path;\n }\n\n let server: HttpServerLike;\n try {\n const dist = resolveDist(mode, options);\n // Bundled server handler\n const handler = createHandler(db?.db ?? null, { playgroundDist: dist });\n // Playground: no database exists to close — createHandler(null) answers\n server = await startHttpServer(handler, host, port);\n if (mode === 'server') {\n writeOut(`wod server: http://${host}:${port} — ${dbLabel} · dist ${dist}`);\n } else {\n writeOut(`wod playground: http://${host}:${port} — in-browser storage (no database) · dist ${dist}`);\n }\n } catch (e) {\n if (db) await db.close(); // never leak the probe connection when startup fails\n throw e;\n }\n\n let closing = false;\n const shutdown = async (): Promise<void> => {\n if (closing) process.exit(0); // second signal forces the exit\n closing = true;\n try {\n await server.stop();\n } finally {\n if (db) await db.close();\n process.exit(0);\n }\n };\n process.on('SIGINT', () => { void shutdown(); });\n process.on('SIGTERM', () => { void shutdown(); });\n\n // Park until a signal handler exits the process.\n await new Promise<never>(() => {});\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  import { createRequire } from 'module';
2
2
  import { resolve, sep, join } from 'path';
3
3
  import { stat, realpath } from 'fs/promises';
4
- import { realpathSync } from 'fs';
4
+ import { realpathSync, createReadStream } from 'fs';
5
+ import { Readable } from 'stream';
5
6
  import { StorageError, wipeRows, wipeDomain, refreshDomain, handleDomainQuery, storeDefinition, MAX_BODY, getRow, listRows, countRows } from '@bitcobblers/wod-wiki-storage/sql';
6
7
  import { keyFromValue } from '@bitcobblers/wod-wiki-storage';
7
8
 
@@ -21,10 +22,10 @@ var HttpError = class extends Error {
21
22
  code;
22
23
  };
23
24
  var json = (value, status) => new Response(JSON.stringify(value), { status, headers: { "content-type": "application/json" } });
24
- function bunFile(path) {
25
- const bun = globalThis;
26
- if (!bun.Bun) throw new Error("the wod-wiki server handler requires the Bun runtime (https://bun.sh)");
27
- return bun.Bun.file(path);
25
+ function streamFile(path) {
26
+ const bun = globalThis.Bun;
27
+ if (bun?.file) return bun.file(path);
28
+ return Readable.toWeb(createReadStream(path));
28
29
  }
29
30
  var plain = (body, status) => new Response(body, { status, headers: { "content-type": "text/plain; charset=utf-8" } });
30
31
  var notFound = () => json({ error: "not found" }, 404);
@@ -140,14 +141,14 @@ async function realpathSafe(path) {
140
141
  async function serveFile(real, rel) {
141
142
  const cache = rel.includes("seed/chunks/") ? "public, max-age=31536000, immutable" : "no-cache";
142
143
  const ext = rel.slice(rel.lastIndexOf(".") + 1).toLowerCase();
143
- return new Response(bunFile(real), {
144
+ return new Response(streamFile(real), {
144
145
  headers: { "content-type": MIME[ext] ?? "application/octet-stream", "cache-control": cache }
145
146
  });
146
147
  }
147
148
  async function serveSpaShell(distRoot) {
148
149
  const index = await realpathSafe(join(distRoot, "index.html"));
149
150
  if (index && (index === distRoot || index.startsWith(distRoot + sep)) && await stat(index).then((s) => s.isFile(), () => false)) {
150
- return new Response(bunFile(index), {
151
+ return new Response(streamFile(index), {
151
152
  headers: { "content-type": MIME.html, "cache-control": "no-cache" }
152
153
  });
153
154
  }
@@ -296,5 +297,5 @@ function createHandler(db, options) {
296
297
  }
297
298
 
298
299
  export { createHandler };
299
- //# sourceMappingURL=chunk-K3GZZFAC.mjs.map
300
- //# sourceMappingURL=chunk-K3GZZFAC.mjs.map
300
+ //# sourceMappingURL=chunk-V23POHG2.mjs.map
301
+ //# sourceMappingURL=chunk-V23POHG2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/errors.ts","../src/server/app.ts"],"names":[],"mappings":"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","file":"chunk-V23POHG2.mjs","sourcesContent":["/**\n * errors.ts — the single HTTP error type every layer throws; app.ts maps it\n * to the wire's { error, code? } JSON with the matching status.\n */\nexport class HttpError extends Error {\n constructor(readonly status: number, message: string, readonly code?: string) {\n super(message);\n this.name = 'HttpError';\n }\n}\n","/**\n * app.ts — one native fetch handler for the whole surface:\n * GET /api/health\n * GET /api/v1/:store/get?key= GET /api/v1/:store/all?range=&count=\n * GET /api/v1/:store/index/:idx?range=&count=\n * GET /api/v1/:store/count?range=&index=\n * PUT /api/v1/:store {value} DELETE /api/v1/:store?key=\n * POST /api/v1/:store/clear POST /api/v1/tx {ops}\n * POST /api/v1/wipe POST /api/v1/query\n * everything else: static SPA serving from playgroundDist (asset miss with an\n * extension → 404; extensionless → index.html; traversal/symlink escapes →\n * 403; /api never falls through to the SPA).\n *\n * `db` may be null for the CLI playground mode: static SPA serving only, every\n * /api request answers 404 — the playground never touches a server database.\n */\n\nimport { join, resolve, sep } from 'node:path';\nimport { stat, realpath } from 'node:fs/promises';\nimport { realpathSync, createReadStream } from 'node:fs';\nimport { Readable } from 'node:stream';\nimport { HttpError } from './errors';\nimport {\n handleDomainQuery,\n refreshDomain,\n wipeDomain,\n MAX_BODY,\n StorageError,\n storeDefinition,\n getRow,\n listRows,\n countRows,\n wipeRows,\n type Database,\n} from '@bitcobblers/wod-wiki-storage/sql';\nimport { keyFromValue, type KeyDTO, type RangeDTO, type TxOp } from '@bitcobblers/wod-wiki-storage';\n\nconst json = (value: unknown, status: number): Response =>\n new Response(JSON.stringify(value), { status, headers: { 'content-type': 'application/json' } });\n\nfunction streamFile(path: string): BodyInit {\n const bun = (globalThis as { Bun?: { file(p: string): BodyInit } }).Bun;\n if (bun?.file) return bun.file(path);\n // ponytail: node:fs Readable.toWeb streams files in pure Node.js (v18+) without dependencies\n return Readable.toWeb(createReadStream(path)) as unknown as BodyInit;\n}\n\nconst plain = (body: string, status: number): Response =>\n new Response(body, { status, headers: { 'content-type': 'text/plain; charset=utf-8' } });\n\nconst notFound = (): Response => json({ error: 'not found' }, 404);\nconst methodNotAllowed = (): Response => json({ error: 'method not allowed' }, 405);\n\nconst noContent = (): Response => new Response(null, { status: 204 });\n\n/** URLSearchParams already applies the form-urlencoded '+' → space then %XX\n * decoding the wire contract relies on. */\nconst qget = (url: URL, name: string): string | undefined => url.searchParams.get(name) ?? undefined;\n\nfunction jsonParam(url: URL, name: string): unknown {\n const raw = qget(url, name);\n if (raw === undefined) return undefined;\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new HttpError(400, `invalid JSON in ?${name}`);\n }\n}\n\n/** ?range accepts a RangeDTO object or a bare key (scalar/tuple → {only}). */\nfunction rangeParam(url: URL): RangeDTO | undefined {\n const v = jsonParam(url, 'range');\n if (v === undefined) return undefined;\n if (v !== null && typeof v === 'object' && !Array.isArray(v)) return v as RangeDTO;\n return { only: v as KeyDTO };\n}\n\nfunction countParam(url: URL): number | undefined {\n const raw = qget(url, 'count');\n if (raw === undefined) return undefined;\n const n = Number(raw); // Number('') === 0, matching the wire contract\n if (!Number.isFinite(n) || n < 0) throw new HttpError(400, 'invalid ?count');\n return Math.trunc(n);\n}\n\nasync function readJsonBody(req: Request, maxBytes?: number): Promise<unknown> {\n const body = await req.text();\n if (maxBytes !== undefined && body.length > maxBytes) {\n throw new HttpError(413, `domain query body exceeds ${maxBytes} bytes`);\n }\n try {\n return JSON.parse(body) as unknown;\n } catch {\n throw new HttpError(400, 'body must be valid JSON');\n }\n}\n\nfunction txOps(value: unknown): TxOp[] {\n if (!Array.isArray(value)) throw new HttpError(400, 'tx body must be {ops: []}');\n return value.map((op: unknown): TxOp => {\n if (op === null || typeof op !== 'object' || Array.isArray(op) || !('store' in op) || typeof op.store !== 'string' || !('op' in op)) {\n throw new HttpError(400, 'tx op must have a store and operation');\n }\n const def = storeDefinition(op.store);\n const store = def.name;\n switch (op.op) {\n case 'put':\n if (!('value' in op)) throw new HttpError(400, 'put requires value');\n return { op: 'put', store, value: op.value };\n case 'delete':\n if (!('key' in op)) throw new HttpError(400, 'delete requires key');\n return { op: 'delete', store, key: op.key as KeyDTO };\n case 'clear':\n return { op: 'clear', store };\n case 'check': {\n if (!('key' in op) || !('value' in op)) throw new HttpError(400, 'check requires key and value');\n const scalar = (key: unknown): key is string | number => typeof key === 'string' || (typeof key === 'number' && Number.isFinite(key));\n if (!scalar(op.key) && !(Array.isArray(op.key) && op.key.length > 0 && op.key.every(scalar))) {\n throw new HttpError(400, 'check requires a scalar key or non-empty scalar tuple');\n }\n if (op.value !== null && (typeof op.value !== 'object' || Array.isArray(op.value))) {\n throw new HttpError(400, 'check value must be a row or null');\n }\n const parts = Array.isArray(op.key) ? op.key : [op.key];\n if (parts.length !== def.keyPath.length) throw new HttpError(400, 'check key arity must match the store');\n if (op.value !== null) {\n let rowKey: KeyDTO;\n try { rowKey = keyFromValue(def, op.value); }\n catch { throw new HttpError(400, 'check row must have its primary key'); }\n if (JSON.stringify(rowKey) !== JSON.stringify(op.key)) throw new HttpError(400, 'check row primary key must match key');\n }\n return { op: 'check', store, key: op.key, value: op.value };\n }\n default:\n throw new HttpError(400, 'tx op must be put | delete | clear | check');\n }\n });\n}\n\n// ── Static SPA serving ───────────────────────────────────────────────────────\n\nconst MIME: Record<string, string> = {\n html: 'text/html; charset=utf-8',\n js: 'text/javascript; charset=utf-8',\n mjs: 'text/javascript; charset=utf-8',\n css: 'text/css; charset=utf-8',\n json: 'application/json; charset=utf-8',\n map: 'application/json; charset=utf-8',\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n ico: 'image/x-icon',\n woff: 'font/woff',\n woff2: 'font/woff2',\n ttf: 'font/ttf',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n webmanifest: 'application/manifest+json',\n xml: 'application/xml',\n txt: 'text/plain; charset=utf-8',\n};\n\nasync function realpathSafe(path: string): Promise<string | undefined> {\n try {\n return await realpath(path);\n } catch {\n return undefined;\n }\n}\n\nasync function serveFile(real: string, rel: string): Promise<Response> {\n // Seed chunks are content-hashed; everything else revalidates.\n const cache = rel.includes('seed/chunks/')\n ? 'public, max-age=31536000, immutable'\n : 'no-cache';\n const ext = rel.slice(rel.lastIndexOf('.') + 1).toLowerCase();\n return new Response(streamFile(real), {\n headers: { 'content-type': MIME[ext] ?? 'application/octet-stream', 'cache-control': cache },\n });\n}\n\nasync function serveSpaShell(distRoot: string): Promise<Response | undefined> {\n const index = await realpathSafe(join(distRoot, 'index.html'));\n // Same symlink confinement as assets: a dist/index.html symlink pointing\n // outside must not become the shell.\n if (index && (index === distRoot || index.startsWith(distRoot + sep))\n && (await stat(index).then((s) => s.isFile(), () => false))) {\n return new Response(streamFile(index), {\n headers: { 'content-type': MIME.html, 'cache-control': 'no-cache' },\n });\n }\n return undefined;\n}\n\nasync function staticResponse(distRoot: string | undefined, method: string, pathname: string): Promise<Response> {\n if (method !== 'GET') return plain('method not allowed', 405);\n if (!distRoot) {\n return plain('wod-wiki-api: playground dist not found. Set PLAYGROUND_DIST or run the playground server build.', 503);\n }\n let rel: string;\n try {\n rel = decodeURIComponent(pathname).replace(/^\\/+/, '');\n } catch {\n return plain('bad request', 400);\n }\n if (rel === '') rel = 'index.html';\n const parts = rel.split('/');\n if (parts.some((p) => p === '..')) return plain('forbidden', 403);\n const base = parts[parts.length - 1] ?? '';\n const hasExtension = base.includes('.');\n\n const abs = resolve(distRoot, ...parts);\n const real = await realpathSafe(abs);\n // Symlink confinement: serve only paths that really live under the dist root.\n if (real && (real === distRoot || real.startsWith(distRoot + sep))) {\n const info = await stat(real).then((s) => s.isFile(), () => false);\n if (info) return serveFile(real, rel);\n }\n // SPA fallback: extensionless paths render the app shell.\n if (!hasExtension) {\n const shell = await serveSpaShell(distRoot);\n if (shell) return shell;\n }\n return plain('not found', 404);\n}\n\n// ── API routing ──────────────────────────────────────────────────────────────\n\nasync function storeRoutes(db: Database, method: string, sub: string, url: URL, req: Request): Promise<Response> {\n let inner = sub.slice('/v1/'.length);\n if (inner.endsWith('/')) inner = inner.slice(0, -1);\n if (inner === '') return notFound();\n const segments = inner.split('/');\n let name: string;\n let action: string | undefined;\n if (segments.length === 1) {\n name = segments[0];\n } else if (segments.length === 2) {\n [name, action] = segments;\n } else if (segments.length === 3 && segments[1] === 'index' && segments[2] !== '') {\n [name, , action] = segments;\n action = `index/${action}`;\n } else {\n return notFound();\n }\n const def = storeDefinition(name); // 404 for unknown stores\n\n const range = rangeParam(url);\n const count = countParam(url);\n\n if (action === 'get' && method === 'GET') {\n const key = jsonParam(url, 'key');\n if (key === undefined) throw new HttpError(400, 'missing ?key');\n const row = await getRow(db, def, key as KeyDTO);\n return row === undefined ? notFound() : json(row, 200);\n }\n if (action === 'all' && method === 'GET') {\n return json(await listRows(db, def, range, count), 200);\n }\n if (action === 'count' && method === 'GET') {\n const indexName = qget(url, 'index');\n const n = indexName\n ? await countRows(db, def, range, indexName)\n : await countRows(db, def, range);\n return json({ count: Number(n) }, 200);\n }\n if (action === 'clear' && method === 'POST') {\n await db.transaction((tx) => refreshDomain(tx, [{ op: 'clear', store: def.name }]));\n return noContent();\n }\n if (action?.startsWith('index/') && method === 'GET') {\n return json(await listRows(db, def, range, count, action.slice('index/'.length)), 200);\n }\n if (action === undefined && method === 'PUT') {\n const parsed = await readJsonBody(req);\n const value = typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed) && 'value' in parsed\n ? parsed.value\n : undefined;\n if (value === undefined) throw new HttpError(400, 'body must be {value: ...}');\n const [key] = await db.transaction((tx) => refreshDomain(tx, [{ op: 'put', store: def.name, value }]));\n return json({ key }, 200);\n }\n if (action === undefined && method === 'DELETE') {\n const keyParam = jsonParam(url, 'key');\n const target = keyParam !== undefined ? keyParam : range;\n if (target === undefined || target === null) throw new HttpError(400, 'DELETE requires ?key or ?range');\n // Wire DELETE accepts a key or a range; the TxOp delete variant types the\n // narrower KeyDTO even though deleteRows honours both.\n await db.transaction((tx) => refreshDomain(tx, [{ op: 'delete', store: def.name, key: target as KeyDTO }]));\n return noContent();\n }\n return methodNotAllowed();\n}\n\nasync function apiRoutes(db: Database, req: Request, method: string, sub: string, url: URL): Promise<Response> {\n if (sub === '/health') {\n return json({ ok: true, driver: db.dialect }, 200);\n }\n if (sub === '/v1/wipe' && method === 'POST') {\n await db.transaction(async (tx) => {\n // System memberships survive; derived projections follow (empty is consistent).\n await wipeRows(tx);\n await wipeDomain(tx);\n });\n return noContent();\n }\n if (sub === '/v1/tx' && method === 'POST') {\n const parsed = await readJsonBody(req);\n const ops = typeof parsed === 'object' && parsed !== null && 'ops' in parsed ? parsed.ops : undefined;\n const parsedOps = txOps(ops);\n const results = await db.transaction((tx) => refreshDomain(tx, parsedOps));\n return json({ results }, 200);\n }\n if (sub === '/v1/query') {\n if (method !== 'POST') return methodNotAllowed();\n const body = await readJsonBody(req, MAX_BODY);\n return json(await handleDomainQuery(db, body), 200);\n }\n if (sub.startsWith('/v1/')) return storeRoutes(db, method, sub, url, req);\n return notFound();\n}\n\n// ── Handler factory ──────────────────────────────────────────────────────────\n\nfunction distRootOf(playgroundDist: string | undefined): string | undefined {\n if (!playgroundDist) return undefined;\n try {\n return realpathSync(playgroundDist);\n } catch {\n return undefined;\n }\n}\n\nexport function createHandler(\n db: Database | null,\n options: { playgroundDist: string },\n): (request: Request) => Promise<Response> {\n const distRoot = distRootOf(options.playgroundDist);\n return async (request: Request): Promise<Response> => {\n try {\n const url = new URL(request.url);\n const method = request.method === 'HEAD' ? 'GET' : request.method; // Bun strips HEAD bodies\n const path = url.pathname;\n const response = path === '/api' || path.startsWith('/api/')\n ? db\n ? await apiRoutes(db, request, method, path.slice('/api'.length) || '/', url)\n : notFound()\n : await staticResponse(distRoot, method, path);\n return response;\n } catch (e) {\n if (e instanceof HttpError || e instanceof StorageError) {\n const status = e.status;\n if (status >= 500) console.error('[wod-wiki-api]', e.message);\n const body: { error: string; code?: string } = { error: status >= 500 ? 'internal error' : e.message };\n if (e.code) body.code = e.code;\n return json(body, status);\n }\n console.error('[wod-wiki-api]', e);\n return json({ error: 'internal error' }, 500);\n }\n };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { createRequire } from 'module';
2
+ export { buildBlockEffortRows, buildBlockIndexRows, chunkIdFor, collectCorpusMarkdown, compileSeedRow, discoverUncatalogedEfforts, feedDateToCreatedAt, generateSeed, loadExistingEffortMap, partitionIntoChunks, scaffoldDiscoveredEfforts, validateDashboardNote, validateWodBlockSyntax } from './chunk-FZKXOYMJ.mjs';
3
+ import './chunk-6L5ZDZJ7.mjs';
4
+
5
+ if (typeof globalThis.require === 'undefined') {
6
+ try { globalThis.require = createRequire(import.meta.url); } catch {}
7
+ }
8
+ //# sourceMappingURL=compiler-CTPLIZJK.mjs.map
9
+ //# sourceMappingURL=compiler-CTPLIZJK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"compiler-CTPLIZJK.mjs"}