@descent-vtt/spec-graph 0.2.0

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +627 -0
  3. package/bin/spec-graph.js +24 -0
  4. package/dist/baseline.d.ts +93 -0
  5. package/dist/baseline.js +187 -0
  6. package/dist/baseline.js.map +1 -0
  7. package/dist/cli.d.ts +66 -0
  8. package/dist/cli.js +565 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +66 -0
  11. package/dist/config.js +183 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/directives.d.ts +56 -0
  14. package/dist/directives.js +125 -0
  15. package/dist/directives.js.map +1 -0
  16. package/dist/extract.d.ts +116 -0
  17. package/dist/extract.js +1043 -0
  18. package/dist/extract.js.map +1 -0
  19. package/dist/glob.d.ts +73 -0
  20. package/dist/glob.js +284 -0
  21. package/dist/glob.js.map +1 -0
  22. package/dist/graph.d.ts +55 -0
  23. package/dist/graph.js +201 -0
  24. package/dist/graph.js.map +1 -0
  25. package/dist/identity.d.ts +87 -0
  26. package/dist/identity.js +294 -0
  27. package/dist/identity.js.map +1 -0
  28. package/dist/index.d.ts +63 -0
  29. package/dist/index.js +45 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/lifecycle.d.ts +57 -0
  32. package/dist/lifecycle.js +258 -0
  33. package/dist/lifecycle.js.map +1 -0
  34. package/dist/markdown.d.ts +152 -0
  35. package/dist/markdown.js +820 -0
  36. package/dist/markdown.js.map +1 -0
  37. package/dist/paths.d.ts +22 -0
  38. package/dist/paths.js +58 -0
  39. package/dist/paths.js.map +1 -0
  40. package/dist/report.d.ts +89 -0
  41. package/dist/report.js +326 -0
  42. package/dist/report.js.map +1 -0
  43. package/dist/resolve.d.ts +61 -0
  44. package/dist/resolve.js +340 -0
  45. package/dist/resolve.js.map +1 -0
  46. package/dist/rules.d.ts +61 -0
  47. package/dist/rules.js +557 -0
  48. package/dist/rules.js.map +1 -0
  49. package/dist/runner.d.ts +108 -0
  50. package/dist/runner.js +186 -0
  51. package/dist/runner.js.map +1 -0
  52. package/dist/sections.d.ts +94 -0
  53. package/dist/sections.js +372 -0
  54. package/dist/sections.js.map +1 -0
  55. package/dist/select.d.ts +96 -0
  56. package/dist/select.js +413 -0
  57. package/dist/select.js.map +1 -0
  58. package/dist/source.d.ts +43 -0
  59. package/dist/source.js +109 -0
  60. package/dist/source.js.map +1 -0
  61. package/dist/state.d.ts +45 -0
  62. package/dist/state.js +330 -0
  63. package/dist/state.js.map +1 -0
  64. package/dist/types.d.ts +294 -0
  65. package/dist/types.js +52 -0
  66. package/dist/types.js.map +1 -0
  67. package/dist/yaml.d.ts +37 -0
  68. package/dist/yaml.js +240 -0
  69. package/dist/yaml.js.map +1 -0
  70. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAcH,MAAM,QAAQ,GAAG,mCAAmC,CAAC;AACrD,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,UAAU,GAAG,CAAC;IAC1D,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAc,CAAC;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,MAAM,MAAM,GAAI,KAAK,CAAC,CAAC,CAAY,CAAC,MAAM,CAAC;QAC3C,MAAM,GAAG,GAAI,KAAK,CAAC,CAAC,CAAY,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,GAAI,KAAK,CAAC,CAAC,CAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG;gBACH,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC;gBACjC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM;gBACvC,GAAG,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM;gBAC7C,UAAU,EAAE,UAAU,GAAG,UAAU;aACpC,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,oEAAoE;QACpE,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG;gBACH,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM;gBACvC,GAAG,EAAE,UAAU,GAAG,KAAK,CAAC,GAAG;gBAC3B,UAAU,EAAE,UAAU,GAAG,KAAK,CAAC,UAAU;aAC1C,CAAC,CAAC;YACH,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACtB,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClC,OAAO,CAAC,IAAI,CAAC;oBACX,GAAG,EAAE,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE;oBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,KAAK,EAAE,UAAU,GAAG,KAAK,CAAC,KAAK;oBAC/B,GAAG,EAAE,UAAU,GAAG,KAAK,CAAC,GAAG;oBAC3B,UAAU,EAAE,UAAU,GAAG,KAAK,CAAC,UAAU;iBAC1C,CAAC,CAAC;YACL,CAAC;YACD,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG;gBACH,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM;gBACvC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC,GAAG;gBAC1B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC,GAAG;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,OAA6B;IACpD,MAAM,GAAG,GAA+C,EAAE,CAAC;IAC3D,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,KAA4B;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QACpC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;YACf,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAYD,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACxC,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,IAAI,GAAG,GAAG,KAAK,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI;gBAAE,GAAG,IAAI,CAAC,CAAC;YACnD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACtD,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAK,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAe,CAAC,IAAI,KAAK,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACtG,OAAO,GAAG,CAAC;AACb,CAAC;AAOD,SAAS,SAAS,CAAC,KAA2B,EAAE,IAAY,EAAE,MAAc;IAC1E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAc,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,CAAC,CAAC;YACT,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;QACnE,IAAI,UAAU,IAAI,MAAM;YAAE,MAAM;QAEhC,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM;YAC5B,sEAAsE;YACtE,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;YACnF,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3E,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAW,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAG,GAAG,CAAC,CAAC,CAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACpF,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QACpC,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;IACtE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AAED,SAAS,aAAa,CACpB,KAA2B,EAC3B,IAAY,EACZ,MAAc;IAEd,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAc,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,CAAC,CAAC;YACT,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;QACnE,IAAI,UAAU,IAAI,MAAM;YAAE,MAAM;QAChC,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;IACpE,MAAM,KAAK,GAAI,KAAK,CAAC,IAAI,CAAe,CAAC,KAAK,CAAC;IAC/C,MAAM,IAAI,GAAI,KAAK,CAAC,IAAI,CAAe,CAAC,GAAG,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC;QAAE,KAAK,CAAC,IAAI,CAAE,KAAK,CAAC,CAAC,CAAe,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC1D,KAAK,IAAI,CAAC;AACZ,CAAC;AAED,uDAAuD;AACvD,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;QAC9B,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,EAAE,KAAK,IAAI;gBAAE,CAAC,IAAI,CAAC,CAAC;iBACnB,IAAI,EAAE,KAAK,KAAK;gBAAE,KAAK,GAAG,IAAI,CAAC;QACtC,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACpC,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;YACpF,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,kEAAkE;AAClE,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;QAC9B,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,EAAE,KAAK,IAAI;gBAAE,CAAC,IAAI,CAAC,CAAC;iBACnB,IAAI,EAAE,KAAK,KAAK;gBAAE,KAAK,GAAG,IAAI,CAAC;QACtC,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACpC,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACvC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACvE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["/**\n * A front-matter reader for the subset of YAML that specifications actually use.\n *\n * Front matter in an ADR is a flat bag of scalars and lists. Pulling in a full\n * YAML implementation to read `status: accepted` would add a parser with its own\n * CVE history, and would still need wrapping to recover the byte offset of the\n * value - which is the whole reason we parse it ourselves: when a status is\n * wrong, the report has to point at the line that declares it.\n *\n * Supported: scalars, quoted scalars, inline `[a, b]` sequences, block `- item`\n * sequences, one level of nested mapping (flattened to `parent.child`), and `#`\n * comments. Anything richer is preserved as the raw scalar text rather than\n * being silently mangled.\n */\n\nexport interface YamlEntry {\n /** Lower-cased key. Nested keys are flattened with a dot. */\n readonly key: string;\n readonly value: string | readonly string[];\n /** Offset of the key. */\n readonly start: number;\n /** Offset just past the value. */\n readonly end: number;\n /** Offset of the first character of the value, for precise diagnostics. */\n readonly valueStart: number;\n}\n\nconst KEY_LINE = /^(\\s*)([A-Za-z0-9_.$-]+)\\s*:(.*)$/;\nconst SEQUENCE_ITEM = /^(\\s*)-\\s*(.*)$/;\n\n/**\n * Parses front-matter text.\n *\n * @param raw The text between the delimiters.\n * @param baseOffset Offset of `raw` within the containing file, so the returned\n * spans address the file rather than the fragment.\n */\nexport function parseFrontMatter(raw: string, baseOffset = 0): YamlEntry[] {\n const entries: YamlEntry[] = [];\n const lines = splitLines(raw);\n\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i] as SplitLine;\n const match = KEY_LINE.exec(line.text);\n if (!match) continue;\n\n const indent = (match[1] as string).length;\n const key = (match[2] as string).toLowerCase();\n const rest = match[3] as string;\n const restStart = line.start + indent + (match[2] as string).length + 1;\n const trimmed = stripComment(rest).trim();\n\n if (trimmed.length > 0) {\n const valueStart = restStart + rest.indexOf(trimmed);\n entries.push({\n key,\n value: parseScalarOrFlow(trimmed),\n start: baseOffset + line.start + indent,\n end: baseOffset + valueStart + trimmed.length,\n valueStart: baseOffset + valueStart,\n });\n continue;\n }\n\n // An empty value opens either a block sequence or a nested mapping.\n const block = readBlock(lines, i + 1, indent);\n if (block.kind === 'sequence') {\n entries.push({\n key,\n value: block.items,\n start: baseOffset + line.start + indent,\n end: baseOffset + block.end,\n valueStart: baseOffset + block.valueStart,\n });\n i = block.lastIndex;\n } else if (block.kind === 'mapping') {\n for (const child of block.entries) {\n entries.push({\n key: `${key}.${child.key}`,\n value: child.value,\n start: baseOffset + child.start,\n end: baseOffset + child.end,\n valueStart: baseOffset + child.valueStart,\n });\n }\n i = block.lastIndex;\n } else {\n entries.push({\n key,\n value: '',\n start: baseOffset + line.start + indent,\n end: baseOffset + line.end,\n valueStart: baseOffset + line.end,\n });\n }\n }\n\n return entries;\n}\n\n/** Collapses parsed entries into the flat record stored on a document node. */\nexport function toRecord(entries: readonly YamlEntry[]): Record<string, string | readonly string[]> {\n const out: Record<string, string | readonly string[]> = {};\n for (const entry of entries) out[entry.key] = entry.value;\n return out;\n}\n\n/** Every value of a key as a flat list, whether it was a scalar or a sequence. */\nexport function valuesOf(entry: YamlEntry | undefined): string[] {\n if (!entry) return [];\n return typeof entry.value === 'string'\n ? entry.value.length > 0\n ? [entry.value]\n : []\n : [...entry.value];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Internals */\n/* -------------------------------------------------------------------------- */\n\ninterface SplitLine {\n readonly text: string;\n readonly start: number;\n readonly end: number;\n}\n\nfunction splitLines(raw: string): SplitLine[] {\n const out: SplitLine[] = [];\n let start = 0;\n for (let i = 0; i <= raw.length; i += 1) {\n if (i === raw.length || raw[i] === '\\n') {\n let end = i;\n if (end > start && raw[end - 1] === '\\r') end -= 1;\n out.push({ text: raw.slice(start, end), start, end });\n start = i + 1;\n }\n }\n if (out.length > 0 && (out[out.length - 1] as SplitLine).text === '' && raw.endsWith('\\n')) out.pop();\n return out;\n}\n\ntype Block =\n | { kind: 'sequence'; items: string[]; end: number; valueStart: number; lastIndex: number }\n | { kind: 'mapping'; entries: YamlEntry[]; lastIndex: number }\n | { kind: 'empty'; lastIndex: number };\n\nfunction readBlock(lines: readonly SplitLine[], from: number, indent: number): Block {\n const items: string[] = [];\n let valueStart = -1;\n let end = -1;\n let last = from - 1;\n\n for (let i = from; i < lines.length; i += 1) {\n const line = lines[i] as SplitLine;\n if (line.text.trim().length === 0) {\n last = i;\n continue;\n }\n const lineIndent = line.text.length - line.text.trimStart().length;\n if (lineIndent <= indent) break;\n\n const seq = SEQUENCE_ITEM.exec(line.text);\n if (!seq) {\n if (items.length > 0) break;\n // A nested mapping: re-parse the indented region as its own document.\n const region = collectRegion(lines, from, indent);\n if (region.text.trim().length === 0) return { kind: 'empty', lastIndex: from - 1 };\n const nested = parseFrontMatter(region.text, region.start);\n return { kind: 'mapping', entries: nested, lastIndex: region.lastIndex };\n }\n\n const value = stripComment(seq[2] as string).trim();\n const offset = line.start + line.text.indexOf(value, (seq[1] as string).length + 1);\n if (valueStart === -1) valueStart = value.length > 0 ? offset : line.start;\n items.push(unquote(value));\n end = line.start + line.text.length;\n last = i;\n }\n\n if (items.length === 0) return { kind: 'empty', lastIndex: from - 1 };\n return { kind: 'sequence', items, end, valueStart, lastIndex: last };\n}\n\nfunction collectRegion(\n lines: readonly SplitLine[],\n from: number,\n indent: number,\n): { text: string; start: number; lastIndex: number } {\n let last = from - 1;\n for (let i = from; i < lines.length; i += 1) {\n const line = lines[i] as SplitLine;\n if (line.text.trim().length === 0) {\n last = i;\n continue;\n }\n const lineIndent = line.text.length - line.text.trimStart().length;\n if (lineIndent <= indent) break;\n last = i;\n }\n if (last < from) return { text: '', start: 0, lastIndex: from - 1 };\n const start = (lines[from] as SplitLine).start;\n const stop = (lines[last] as SplitLine).end;\n const parts: string[] = [];\n for (let i = from; i <= last; i += 1) parts.push((lines[i] as SplitLine).text);\n return { text: parts.join('\\n'), start, lastIndex: last };\n void stop;\n}\n\n/** Drops a trailing `#` comment, respecting quotes. */\nfunction stripComment(value: string): string {\n let quote: string | null = null;\n for (let i = 0; i < value.length; i += 1) {\n const ch = value[i] as string;\n if (quote) {\n if (ch === '\\\\') i += 1;\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n } else if (ch === '#' && (i === 0 || value[i - 1] === ' ' || value[i - 1] === '\\t')) {\n return value.slice(0, i);\n }\n }\n return value;\n}\n\nfunction parseScalarOrFlow(value: string): string | string[] {\n if (value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1).trim();\n if (inner.length === 0) return [];\n return splitFlow(inner).map(unquote);\n }\n return unquote(value);\n}\n\n/** Splits `a, \"b, c\", d` on commas that are not inside quotes. */\nfunction splitFlow(value: string): string[] {\n const out: string[] = [];\n let quote: string | null = null;\n let start = 0;\n for (let i = 0; i < value.length; i += 1) {\n const ch = value[i] as string;\n if (quote) {\n if (ch === '\\\\') i += 1;\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n } else if (ch === ',') {\n out.push(value.slice(start, i).trim());\n start = i + 1;\n }\n }\n out.push(value.slice(start).trim());\n return out.filter((part) => part.length > 0);\n}\n\nfunction unquote(value: string): string {\n if (value.length >= 2) {\n const first = value[0];\n const last = value[value.length - 1];\n if ((first === '\"' && last === '\"') || (first === \"'\" && last === \"'\")) {\n return value.slice(1, -1).replace(/\\\\(.)/g, '$1');\n }\n }\n return value;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@descent-vtt/spec-graph",
3
+ "version": "0.2.0",
4
+ "description": "Turn Markdown specs into a verifiable relational graph. Catches ghost handovers, stale premises and broken references in CI.",
5
+ "keywords": [
6
+ "adr",
7
+ "architecture",
8
+ "documentation",
9
+ "graph",
10
+ "kep",
11
+ "lifecycle",
12
+ "madr",
13
+ "markdown",
14
+ "rfc",
15
+ "spec",
16
+ "traceability"
17
+ ],
18
+ "license": "MIT",
19
+ "type": "module",
20
+ "engines": {
21
+ "node": ">=22"
22
+ },
23
+ "bin": {
24
+ "spec-graph": "bin/spec-graph.js"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "files": [
36
+ "LICENSE",
37
+ "README.md",
38
+ "bin",
39
+ "dist"
40
+ ],
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.build.json",
46
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
47
+ "lint": "tsc -p tsconfig.json --noEmit",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:coverage": "vitest run --coverage",
51
+ "selfcheck": "node ./bin/spec-graph.js check --verbose",
52
+ "prepublishOnly": "npm run clean && npm run build",
53
+ "test:mutation": "stryker run"
54
+ },
55
+ "devDependencies": {
56
+ "@stryker-mutator/core": "^10.0.0",
57
+ "@stryker-mutator/vitest-runner": "^10.0.0",
58
+ "@types/node": "^26.4.1",
59
+ "@vitest/coverage-v8": "^4.1.11",
60
+ "typescript": "^7.0.2",
61
+ "vitest": "^4.1.11"
62
+ },
63
+ "repository": {
64
+ "type": "git",
65
+ "url": "git+https://github.com/DescentVTT/spec-graph.git"
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/DescentVTT/spec-graph/issues"
69
+ },
70
+ "homepage": "https://github.com/DescentVTT/spec-graph#readme"
71
+ }