@wildo-ai/saas-technical-doc 1.1.5 → 1.1.7

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 (156) hide show
  1. package/dist/esm/build/csp-emit.d.ts.map +1 -1
  2. package/dist/esm/build/load-materialized-frontend-providers.d.ts.map +1 -1
  3. package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts.map +1 -1
  4. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
  5. package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts.map +1 -1
  6. package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts.map +1 -1
  7. package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.d.ts.map +1 -1
  8. package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts.map +1 -1
  9. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
  10. package/dist/esm/companion/application-documentation/technical-documentation-operational-evidence.d.ts.map +1 -1
  11. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
  12. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.d.ts.map +1 -1
  13. package/dist/esm/companion/content/application-consumer-documentation-content-loader.d.ts.map +1 -1
  14. package/dist/esm/companion/index.d.ts.map +1 -1
  15. package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -1
  16. package/dist/esm/companion/openapi-example-derivation.d.ts +53 -0
  17. package/dist/esm/companion/openapi-example-derivation.d.ts.map +1 -0
  18. package/dist/esm/companion/openapi-example-derivation.js +229 -0
  19. package/dist/esm/companion/openapi-example-derivation.js.map +1 -0
  20. package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
  21. package/dist/esm/companion/openapi-generator.js +284 -16
  22. package/dist/esm/companion/openapi-generator.js.map +1 -1
  23. package/dist/esm/companion/operation-projection.schemas.d.ts +36 -0
  24. package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
  25. package/dist/esm/companion/operation-projection.schemas.js +18 -0
  26. package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
  27. package/dist/esm/companion/publish-result.types.d.ts.map +1 -1
  28. package/dist/esm/companion/rendering/technical-documentation-authorized-bundle-reader.d.ts.map +1 -1
  29. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
  30. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.d.ts.map +1 -1
  31. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js +20 -0
  32. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js.map +1 -1
  33. package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts.map +1 -1
  34. package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts +2 -0
  35. package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.d.ts.map +1 -1
  36. package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js +48 -31
  37. package/dist/esm/companion/rendering/technical-documentation-openapi-renderer.js.map +1 -1
  38. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
  39. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts.map +1 -1
  40. package/dist/esm/companion/spec-to-operation-doc.d.ts +52 -10
  41. package/dist/esm/companion/spec-to-operation-doc.d.ts.map +1 -1
  42. package/dist/esm/companion/spec-to-operation-doc.js +125 -7
  43. package/dist/esm/companion/spec-to-operation-doc.js.map +1 -1
  44. package/dist/esm/companion/technical-documentation-asset-path.d.ts.map +1 -1
  45. package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts.map +1 -1
  46. package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -1
  47. package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
  48. package/dist/esm/companion/technical-documentation-placeholder-materializer.d.ts.map +1 -1
  49. package/dist/esm/companion/zod-to-openapi.d.ts.map +1 -1
  50. package/dist/esm/companion-exports.d.ts.map +1 -1
  51. package/dist/esm/config/define-tech-doc-config.d.ts.map +1 -1
  52. package/dist/esm/config/index.d.ts.map +1 -1
  53. package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
  54. package/dist/esm/content/application-consumer-documentation-content-manifest.schemas.d.ts.map +1 -1
  55. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +10 -10
  56. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
  57. package/dist/esm/content/application-consumer-documentation-content.techdoc.js +43 -28
  58. package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
  59. package/dist/esm/content.exports.d.ts.map +1 -1
  60. package/dist/esm/index.d.ts.map +1 -1
  61. package/dist/esm/openapi/api-reference-link-index.d.ts +3 -0
  62. package/dist/esm/openapi/api-reference-link-index.d.ts.map +1 -1
  63. package/dist/esm/openapi/api-reference-link-index.js +26 -15
  64. package/dist/esm/openapi/api-reference-link-index.js.map +1 -1
  65. package/dist/esm/openapi/api-reference-pages.d.ts +55 -0
  66. package/dist/esm/openapi/api-reference-pages.d.ts.map +1 -0
  67. package/dist/esm/openapi/api-reference-pages.js +229 -0
  68. package/dist/esm/openapi/api-reference-pages.js.map +1 -0
  69. package/dist/esm/openapi/api-reference-search.d.ts +53 -0
  70. package/dist/esm/openapi/api-reference-search.d.ts.map +1 -0
  71. package/dist/esm/openapi/api-reference-search.js +100 -0
  72. package/dist/esm/openapi/api-reference-search.js.map +1 -0
  73. package/dist/esm/openapi/api-reference-targets.d.ts +11 -0
  74. package/dist/esm/openapi/api-reference-targets.d.ts.map +1 -1
  75. package/dist/esm/openapi/api-reference-targets.js +8 -0
  76. package/dist/esm/openapi/api-reference-targets.js.map +1 -1
  77. package/dist/esm/openapi/index.d.ts +2 -0
  78. package/dist/esm/openapi/index.d.ts.map +1 -1
  79. package/dist/esm/openapi/index.js +2 -0
  80. package/dist/esm/openapi/index.js.map +1 -1
  81. package/dist/esm/openapi/openapi-generation-output.schemas.d.ts.map +1 -1
  82. package/dist/esm/openapi-reference-model.exports.d.ts +2 -0
  83. package/dist/esm/openapi-reference-model.exports.d.ts.map +1 -1
  84. package/dist/esm/openapi-reference-model.exports.js +2 -0
  85. package/dist/esm/openapi-reference-model.exports.js.map +1 -1
  86. package/dist/esm/runtime/AuthExchangePage.d.ts +45 -4
  87. package/dist/esm/runtime/AuthExchangePage.d.ts.map +1 -1
  88. package/dist/esm/runtime/AuthExchangePage.js +45 -12
  89. package/dist/esm/runtime/AuthExchangePage.js.map +1 -1
  90. package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
  91. package/dist/esm/runtime/DocsFrontendProviders.d.ts +15 -1
  92. package/dist/esm/runtime/DocsFrontendProviders.d.ts.map +1 -1
  93. package/dist/esm/runtime/DocsFrontendProviders.js +16 -3
  94. package/dist/esm/runtime/DocsFrontendProviders.js.map +1 -1
  95. package/dist/esm/runtime/DocsProviderComponent.d.ts +41 -0
  96. package/dist/esm/runtime/DocsProviderComponent.d.ts.map +1 -0
  97. package/dist/esm/runtime/DocsProviderComponent.js +17 -0
  98. package/dist/esm/runtime/DocsProviderComponent.js.map +1 -0
  99. package/dist/esm/runtime/decode-jwt-claims.d.ts.map +1 -1
  100. package/dist/esm/runtime/docs-auth-client.d.ts.map +1 -1
  101. package/dist/esm/runtime/docs-auth-session.schemas.d.ts.map +1 -1
  102. package/dist/esm/runtime/documentation-site-translator.d.ts +53 -0
  103. package/dist/esm/runtime/documentation-site-translator.d.ts.map +1 -0
  104. package/dist/esm/runtime/documentation-site-translator.js +51 -0
  105. package/dist/esm/runtime/documentation-site-translator.js.map +1 -0
  106. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
  107. package/dist/esm/runtime/index.d.ts +6 -0
  108. package/dist/esm/runtime/index.d.ts.map +1 -1
  109. package/dist/esm/runtime/index.js +6 -0
  110. package/dist/esm/runtime/index.js.map +1 -1
  111. package/dist/esm/runtime/openapi-reference-conservation.d.ts.map +1 -1
  112. package/dist/esm/runtime/openapi-reference-model.d.ts +25 -0
  113. package/dist/esm/runtime/openapi-reference-model.d.ts.map +1 -1
  114. package/dist/esm/runtime/openapi-reference-model.js +82 -13
  115. package/dist/esm/runtime/openapi-reference-model.js.map +1 -1
  116. package/dist/esm/runtime/openapi-reference-navigation.d.ts +50 -0
  117. package/dist/esm/runtime/openapi-reference-navigation.d.ts.map +1 -0
  118. package/dist/esm/runtime/openapi-reference-navigation.js +46 -0
  119. package/dist/esm/runtime/openapi-reference-navigation.js.map +1 -0
  120. package/dist/esm/runtime/openapi-reference-samples.d.ts +40 -0
  121. package/dist/esm/runtime/openapi-reference-samples.d.ts.map +1 -0
  122. package/dist/esm/runtime/openapi-reference-samples.js +169 -0
  123. package/dist/esm/runtime/openapi-reference-samples.js.map +1 -0
  124. package/dist/esm/runtime/openapi-reference-styles.d.ts +28 -0
  125. package/dist/esm/runtime/openapi-reference-styles.d.ts.map +1 -0
  126. package/dist/esm/runtime/openapi-reference-styles.js +292 -0
  127. package/dist/esm/runtime/openapi-reference-styles.js.map +1 -0
  128. package/dist/esm/runtime/openapi-reference-view.d.ts +40 -5
  129. package/dist/esm/runtime/openapi-reference-view.d.ts.map +1 -1
  130. package/dist/esm/runtime/openapi-reference-view.js +828 -82
  131. package/dist/esm/runtime/openapi-reference-view.js.map +1 -1
  132. package/dist/esm/runtime/openapi-reference-words-context.d.ts +12 -0
  133. package/dist/esm/runtime/openapi-reference-words-context.d.ts.map +1 -0
  134. package/dist/esm/runtime/openapi-reference-words-context.js +30 -0
  135. package/dist/esm/runtime/openapi-reference-words-context.js.map +1 -0
  136. package/dist/esm/runtime/openapi-reference-words.d.ts +205 -0
  137. package/dist/esm/runtime/openapi-reference-words.d.ts.map +1 -0
  138. package/dist/esm/runtime/openapi-reference-words.js +162 -0
  139. package/dist/esm/runtime/openapi-reference-words.js.map +1 -0
  140. package/dist/esm/runtime/provider-component-registry.techdoc.d.ts +31 -0
  141. package/dist/esm/runtime/provider-component-registry.techdoc.d.ts.map +1 -0
  142. package/dist/esm/runtime/provider-component-registry.techdoc.js +35 -0
  143. package/dist/esm/runtime/provider-component-registry.techdoc.js.map +1 -0
  144. package/dist/esm/runtime/use-docs-auth-session.d.ts.map +1 -1
  145. package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts.map +1 -1
  146. package/dist/esm/runtime/use-docs-provider-component.d.ts +29 -0
  147. package/dist/esm/runtime/use-docs-provider-component.d.ts.map +1 -0
  148. package/dist/esm/runtime/use-docs-provider-component.js +42 -0
  149. package/dist/esm/runtime/use-docs-provider-component.js.map +1 -0
  150. package/dist/esm/runtime/use-docs-provider-scripts.d.ts +12 -5
  151. package/dist/esm/runtime/use-docs-provider-scripts.d.ts.map +1 -1
  152. package/dist/esm/runtime/use-docs-provider-scripts.js +15 -8
  153. package/dist/esm/runtime/use-docs-provider-scripts.js.map +1 -1
  154. package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -1
  155. package/dist/tsconfig.build.tsbuildinfo +1 -1
  156. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"content.exports.d.ts","sourceRoot":"","sources":["../../../src/content.exports.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,uEAAuE,CAAC;AACtF,cAAc,8DAA8D,CAAC"}
1
+ {"version":3,"file":"content.exports.d.ts","sourceRoot":"","sources":["../../src/content.exports.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,uEAAuE,CAAC;AACtF,cAAc,8DAA8D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { OpenApiSection, type OpenApiSectionOutput } from './openapi-generation-output.schemas';
12
12
  import { type TechnicalDocumentationApiReferenceTargetV1 } from '@wildo-ai/saas-specifications/technical-documentation';
13
+ import { ApplicationConsumerDocumentationRoute } from './api-reference-targets';
13
14
  /** The semantic source identity a guide may resolve to a consumer API URL. */
14
15
  export declare enum ApiReferenceLinkIdentityKind {
15
16
  /** A generated section exists and its root page is a valid public destination. */
@@ -69,6 +70,8 @@ export declare enum TechnicalDocumentationApiReferenceTargetAvailability {
69
70
  AVAILABLE = "AVAILABLE",
70
71
  UNAVAILABLE = "UNAVAILABLE"
71
72
  }
73
+ /** The consumer-documentation route that roots an API-reference section. */
74
+ export declare function apiReferenceRouteForSection(section: OpenApiSection): ApplicationConsumerDocumentationRoute;
72
75
  /**
73
76
  * Creates links from the exact generated OpenAPI documents.
74
77
  *
@@ -1 +1 @@
1
- {"version":3,"file":"api-reference-link-index.d.ts","sourceRoot":"","sources":["../../../../src/openapi/api-reference-link-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChG,OAAO,EAGL,KAAK,0CAA0C,EAChD,MAAM,uDAAuD,CAAC;AAQ/D,8EAA8E;AAC9E,oBAAY,4BAA4B;IACtC,kFAAkF;IAClF,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;IACrC,iBAAiB,sBAAsB;IACvC,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,IAAI,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtF;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,gBAAgB,CAAC;IAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,iBAAiB,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GACvG;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvH;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,gBAAgB,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG,mGAAmG;AACnG,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;CACzD;AAED;;;;;;GAMG;AACH,oBAAY,oDAAoD;IAC9D,SAAS,cAAc;IACvB,WAAW,gBAAgB;CAC5B;AAoED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,qBAAqB,CAyH5G;AAED,yGAAyG;AACzG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAKzI;AAwCD;;;;GAIG;AACH,wBAAgB,uDAAuD,CACrE,KAAK,EAAE,qBAAqB,EAC5B,MAAM,EAAE,0CAA0C,GACjD,oDAAoD,CAMtD;AAED;;;;;;;GAOG;AACH,wBAAgB,6CAA6C,CAC3D,KAAK,EAAE,qBAAqB,EAC5B,MAAM,EAAE,0CAA0C,GACjD,MAAM,CAGR"}
1
+ {"version":3,"file":"api-reference-link-index.d.ts","sourceRoot":"","sources":["../../../src/openapi/api-reference-link-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChG,OAAO,EAGL,KAAK,0CAA0C,EAChD,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAEL,qCAAqC,EAKtC,MAAM,yBAAyB,CAAC;AAGjC,8EAA8E;AAC9E,oBAAY,4BAA4B;IACtC,kFAAkF;IAClF,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;IACrC,iBAAiB,sBAAsB;IACvC,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,IAAI,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtF;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,gBAAgB,CAAC;IAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,iBAAiB,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GACvG;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvH;IAAE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC,gBAAgB,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG,mGAAmG;AACnG,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;CACzD;AAED;;;;;;GAMG;AACH,oBAAY,oDAAoD;IAC9D,SAAS,cAAc;IACvB,WAAW,gBAAgB;CAC5B;AAUD,4EAA4E;AAC5E,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,cAAc,GAAG,qCAAqC,CAW1G;AAqDD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,qBAAqB,CA2H5G;AAED,yGAAyG;AACzG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAKzI;AAwCD;;;;GAIG;AACH,wBAAgB,uDAAuD,CACrE,KAAK,EAAE,qBAAqB,EAC5B,MAAM,EAAE,0CAA0C,GACjD,oDAAoD,CAMtD;AAED;;;;;;;GAOG;AACH,wBAAgB,6CAA6C,CAC3D,KAAK,EAAE,qBAAqB,EAC5B,MAAM,EAAE,0CAA0C,GACjD,MAAM,CAGR"}
@@ -10,7 +10,8 @@
10
10
  */
11
11
  import { OpenApiSection } from './openapi-generation-output.schemas.js';
12
12
  import { TechnicalDocumentationApiReferenceSection, TechnicalDocumentationApiReferenceTargetKind, } from '@wildo-ai/saas-specifications/technical-documentation';
13
- import { ApiReferenceTargetKind, ApplicationConsumerDocumentationRoute, applicationConsumerDocumentationTargetPath, } from './api-reference-targets.js';
13
+ import { ApiReferenceTargetKind, ApplicationConsumerDocumentationRoute, applicationConsumerDocumentationRoutePath, applicationConsumerDocumentationTargetPath, apiReferenceTargetFragment, } from './api-reference-targets.js';
14
+ import { apiReferencePageHref, buildApiReferencePagePlan } from './api-reference-pages.js';
14
15
  /** The semantic source identity a guide may resolve to a consumer API URL. */
15
16
  export var ApiReferenceLinkIdentityKind;
16
17
  (function (ApiReferenceLinkIdentityKind) {
@@ -40,7 +41,8 @@ const OPENAPI_HTTP_METHODS = new Set(['get', 'put', 'post', 'delete', 'options',
40
41
  function isRecord(value) {
41
42
  return typeof value === 'object' && value !== null && !Array.isArray(value);
42
43
  }
43
- function routeForSection(section) {
44
+ /** The consumer-documentation route that roots an API-reference section. */
45
+ export function apiReferenceRouteForSection(section) {
44
46
  switch (section) {
45
47
  case OpenApiSection.API_REFERENCE:
46
48
  return ApplicationConsumerDocumentationRoute.API_REFERENCE;
@@ -64,12 +66,18 @@ function familyName(operationFamilyRef) {
64
66
  throw new Error(`API-reference family identity is not canonical: '${operationFamilyRef}'`);
65
67
  return name;
66
68
  }
67
- function targetHref(section, target) {
68
- return applicationConsumerDocumentationTargetPath(routeForSection(section), target);
69
+ /**
70
+ * A target's public href. Each resource has its own page (#1623), so a resource-scoped target is
71
+ * addressed on that page (`/api/tasks#operation-create-task`) and only a category stays on the
72
+ * section root — the page plan that registers the routes decides, so a guide link and a route can
73
+ * never disagree about where a target lives.
74
+ */
75
+ function targetHref(section, plan, target) {
76
+ return apiReferencePageHref(applicationConsumerDocumentationRoutePath(apiReferenceRouteForSection(section)), apiReferenceTargetFragment(target), plan);
69
77
  }
70
78
  /** The root is an index entry too: a guide may cite it only when that section was generated. */
71
79
  function sectionRootHref(section) {
72
- return applicationConsumerDocumentationTargetPath(routeForSection(section));
80
+ return applicationConsumerDocumentationTargetPath(apiReferenceRouteForSection(section));
73
81
  }
74
82
  function identityKey(section, identity) {
75
83
  switch (identity.kind) {
@@ -126,6 +134,7 @@ export function createApiReferenceLinkIndex(sections) {
126
134
  const document = sectionOutput.document;
127
135
  if (!isRecord(document) || !isRecord(document.paths))
128
136
  throw new Error(`API-reference ${sectionOutput.section} document has no OpenAPI paths object`);
137
+ const pagePlan = buildApiReferencePagePlan(document);
129
138
  add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.ROOT }, sectionRootHref(sectionOutput.section));
130
139
  const tags = new Map();
131
140
  const usedResourceRefs = new Set();
@@ -150,7 +159,7 @@ export function createApiReferenceLinkIndex(sections) {
150
159
  if (resourceName(tagResourceRef) !== tag.name)
151
160
  throw new Error(`API-reference resource tag '${tag.name}' disagrees with its resource identity`);
152
161
  tags.set(tag.name, { resourceRef: tagResourceRef });
153
- add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: tagResourceRef }, targetHref(sectionOutput.section, {
162
+ add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: tagResourceRef }, targetHref(sectionOutput.section, pagePlan, {
154
163
  kind: ApiReferenceTargetKind.RESOURCE,
155
164
  resourceName: tag.name,
156
165
  }));
@@ -165,7 +174,7 @@ export function createApiReferenceLinkIndex(sections) {
165
174
  const categoryIdentity = { kind: ApiReferenceLinkIdentityKind.CATEGORY, categoryId };
166
175
  const key = identityKey(sectionOutput.section, categoryIdentity);
167
176
  if (!seen.has(key))
168
- add(sectionOutput.section, categoryIdentity, targetHref(sectionOutput.section, {
177
+ add(sectionOutput.section, categoryIdentity, targetHref(sectionOutput.section, pagePlan, {
169
178
  kind: ApiReferenceTargetKind.CATEGORY,
170
179
  categoryName: categoryId,
171
180
  }));
@@ -193,22 +202,22 @@ export function createApiReferenceLinkIndex(sections) {
193
202
  const operationTarget = { kind: ApiReferenceTargetKind.OPERATION, operationId: operation.operationId };
194
203
  const familyIdentity = { kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY, operationFamilyRef: metadata.operationFamilyRef };
195
204
  if (!seen.has(identityKey(sectionOutput.section, familyIdentity))) {
196
- add(sectionOutput.section, familyIdentity, targetHref(sectionOutput.section, {
205
+ add(sectionOutput.section, familyIdentity, targetHref(sectionOutput.section, pagePlan, {
197
206
  kind: ApiReferenceTargetKind.OPERATION_FAMILY,
198
207
  resourceName: resourceName(metadata.resourceRef),
199
208
  operationName: familyName(metadata.operationFamilyRef),
200
209
  }));
201
210
  }
202
- add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, operationTarget));
211
+ add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, pagePlan, operationTarget));
203
212
  if (isRecord(operation.requestBody)) {
204
- add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, {
213
+ add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, pagePlan, {
205
214
  kind: ApiReferenceTargetKind.REQUEST,
206
215
  operationId: operation.operationId,
207
216
  }));
208
217
  }
209
218
  if (isRecord(operation.responses)) {
210
219
  for (const status of Object.keys(operation.responses)) {
211
- add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESPONSE, operationVariantRef: metadata.operationVariantRef, status }, targetHref(sectionOutput.section, {
220
+ add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESPONSE, operationVariantRef: metadata.operationVariantRef, status }, targetHref(sectionOutput.section, pagePlan, {
212
221
  kind: ApiReferenceTargetKind.RESPONSE,
213
222
  operationId: operation.operationId,
214
223
  status,
@@ -224,10 +233,12 @@ export function createApiReferenceLinkIndex(sections) {
224
233
  }
225
234
  const componentSchemas = isRecord(document.components) && isRecord(document.components.schemas) ? document.components.schemas : {};
226
235
  for (const schemaName of Object.keys(componentSchemas)) {
227
- add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName }, targetHref(sectionOutput.section, {
228
- kind: ApiReferenceTargetKind.COMPONENT_SCHEMA,
229
- schemaName,
230
- }));
236
+ const target = { kind: ApiReferenceTargetKind.COMPONENT_SCHEMA, schemaName };
237
+ // A schema no operation reaches is rendered on no page, so it is not offered as a target at all
238
+ // — a guide asking for it gets UNAVAILABLE rather than a link to nothing.
239
+ if (pagePlan.pageSlugByFragment[apiReferenceTargetFragment(target)] === undefined)
240
+ continue;
241
+ add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName }, targetHref(sectionOutput.section, pagePlan, target));
231
242
  }
232
243
  }
233
244
  return { schemaVersion: 1, entries: entries.sort((left, right) => identityKey(left.section, left.identity).localeCompare(identityKey(right.section, right.identity))) };
@@ -1 +1 @@
1
- {"version":3,"file":"api-reference-link-index.js","sourceRoot":"","sources":["../../../../src/openapi/api-reference-link-index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Semantic links into the generated API reference.\n *\n * This module projects a canonical OpenAPI document into a small index of\n * public paths. It does not describe or navigate API contracts itself: every\n * entry is derived from standard OpenAPI fields plus the strict `x-wildo`\n * source identities already present in the document. Guide generation can use\n * the index to link to exact API targets without hard-coding Docusaurus URLs\n * or duplicating operations, request DTOs, responses, or schemas.\n */\n\nimport { OpenApiSection, type OpenApiSectionOutput } from './openapi-generation-output.schemas';\nimport {\n TechnicalDocumentationApiReferenceSection,\n TechnicalDocumentationApiReferenceTargetKind,\n type TechnicalDocumentationApiReferenceTargetV1,\n} from '@wildo-ai/saas-specifications/technical-documentation';\nimport {\n ApiReferenceTargetKind,\n ApplicationConsumerDocumentationRoute,\n applicationConsumerDocumentationTargetPath,\n type ApiReferencePublicTarget,\n} from './api-reference-targets';\n\n/** The semantic source identity a guide may resolve to a consumer API URL. */\nexport enum ApiReferenceLinkIdentityKind {\n /** A generated section exists and its root page is a valid public destination. */\n ROOT = 'ROOT',\n CATEGORY = 'CATEGORY',\n RESOURCE = 'RESOURCE',\n OPERATION_FAMILY = 'OPERATION_FAMILY',\n OPERATION_VARIANT = 'OPERATION_VARIANT',\n REQUEST = 'REQUEST',\n RESPONSE = 'RESPONSE',\n COMPONENT_SCHEMA = 'COMPONENT_SCHEMA',\n}\n\nexport type ApiReferenceLinkIdentity =\n | { readonly kind: ApiReferenceLinkIdentityKind.ROOT }\n | { readonly kind: ApiReferenceLinkIdentityKind.CATEGORY; readonly categoryId: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.RESOURCE; readonly resourceRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY; readonly operationFamilyRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT; readonly operationVariantRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.REQUEST; readonly operationVariantRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.RESPONSE; readonly operationVariantRef: string; readonly status: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA; readonly schemaName: string };\n\n/** One resolved public URL. `section` keeps an identity unambiguous across both API references. */\nexport interface ApiReferenceLinkIndexEntry {\n readonly section: OpenApiSection;\n readonly identity: ApiReferenceLinkIdentity;\n readonly href: string;\n}\n\n/** JSON-safe result of projecting the selected OpenAPI documents. */\nexport interface ApiReferenceLinkIndex {\n readonly schemaVersion: 1;\n readonly entries: readonly ApiReferenceLinkIndexEntry[];\n}\n\n/**\n * Result of asking whether one semantic guide target exists in the exact\n * generated OpenAPI index. This is deliberately not a boolean: the named\n * vocabulary keeps availability decisions readable at guide-composition call\n * sites and leaves room for future source-owned states without overloading\n * `false`.\n */\nexport enum TechnicalDocumentationApiReferenceTargetAvailability {\n AVAILABLE = 'AVAILABLE',\n UNAVAILABLE = 'UNAVAILABLE',\n}\n\ntype UnknownRecord = Record<string, unknown>;\n\nconst OPENAPI_HTTP_METHODS: ReadonlySet<string> = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']);\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction routeForSection(section: OpenApiSection): ApplicationConsumerDocumentationRoute {\n switch (section) {\n case OpenApiSection.API_REFERENCE:\n return ApplicationConsumerDocumentationRoute.API_REFERENCE;\n case OpenApiSection.APPLICATION_ADMINISTRATION_API_REFERENCE:\n return ApplicationConsumerDocumentationRoute.APPLICATION_ADMINISTRATION_API_REFERENCE;\n default: {\n const exhaustiveSection: never = section;\n throw new Error(`Unsupported API-reference section: ${String(exhaustiveSection)}`);\n }\n }\n}\n\nfunction resourceName(resourceRef: string): string {\n const name = resourceRef.match(/^technical-documentation:resource\\/([^/]+)$/)?.[1];\n if (name === undefined) throw new Error(`API-reference resource identity is not a canonical resource ref: '${resourceRef}'`);\n return name;\n}\n\nfunction familyName(operationFamilyRef: string): string {\n const name = operationFamilyRef.match(/^technical-documentation:resource\\/[^/]+\\/operation-family\\/([^/]+)$/)?.[1];\n if (name === undefined) throw new Error(`API-reference family identity is not canonical: '${operationFamilyRef}'`);\n return name;\n}\n\nfunction targetHref(section: OpenApiSection, target: ApiReferencePublicTarget): string {\n return applicationConsumerDocumentationTargetPath(routeForSection(section), target);\n}\n\n/** The root is an index entry too: a guide may cite it only when that section was generated. */\nfunction sectionRootHref(section: OpenApiSection): string {\n return applicationConsumerDocumentationTargetPath(routeForSection(section));\n}\n\nfunction identityKey(section: OpenApiSection, identity: ApiReferenceLinkIdentity): string {\n switch (identity.kind) {\n case ApiReferenceLinkIdentityKind.ROOT:\n return `${section}\\0${identity.kind}`;\n case ApiReferenceLinkIdentityKind.CATEGORY:\n return `${section}\\0${identity.kind}\\0${identity.categoryId}`;\n case ApiReferenceLinkIdentityKind.RESOURCE:\n return `${section}\\0${identity.kind}\\0${identity.resourceRef}`;\n case ApiReferenceLinkIdentityKind.OPERATION_FAMILY:\n return `${section}\\0${identity.kind}\\0${identity.operationFamilyRef}`;\n case ApiReferenceLinkIdentityKind.OPERATION_VARIANT:\n case ApiReferenceLinkIdentityKind.REQUEST:\n return `${section}\\0${identity.kind}\\0${identity.operationVariantRef}`;\n case ApiReferenceLinkIdentityKind.RESPONSE:\n return `${section}\\0${identity.kind}\\0${identity.operationVariantRef}\\0${identity.status}`;\n case ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA:\n return `${section}\\0${identity.kind}\\0${identity.schemaName}`;\n default: {\n const exhaustiveIdentity: never = identity;\n throw new Error(`Unsupported API-reference link identity: ${JSON.stringify(exhaustiveIdentity)}`);\n }\n }\n}\n\n/**\n * Creates links from the exact generated OpenAPI documents.\n *\n * This is intentionally a fail-closed projection. An HTTP operation without\n * the established source identity, a tag/operation resource mismatch, or a\n * duplicate semantic target means guide links could become ambiguous, so the\n * index is not emitted at all.\n */\nexport function createApiReferenceLinkIndex(sections: readonly OpenApiSectionOutput[]): ApiReferenceLinkIndex {\n const entries: ApiReferenceLinkIndexEntry[] = [];\n const seen = new Set<string>();\n const sectionSet = new Set<OpenApiSection>();\n const identityByHref = new Map<string, string>();\n const add = (section: OpenApiSection, identity: ApiReferenceLinkIdentity, href: string): void => {\n const key = identityKey(section, identity);\n if (seen.has(key)) throw new Error(`API-reference link identity is duplicated: ${key}`);\n const priorIdentity = identityByHref.get(href);\n if (priorIdentity !== undefined && priorIdentity !== key) {\n throw new Error(`API-reference public link '${href}' is ambiguous between ${priorIdentity} and ${key}`);\n }\n seen.add(key);\n identityByHref.set(href, key);\n entries.push({ section, identity, href });\n };\n\n for (const sectionOutput of sections) {\n if (sectionSet.has(sectionOutput.section)) throw new Error(`API-reference section is duplicated: ${sectionOutput.section}`);\n sectionSet.add(sectionOutput.section);\n const document = sectionOutput.document;\n if (!isRecord(document) || !isRecord(document.paths)) throw new Error(`API-reference ${sectionOutput.section} document has no OpenAPI paths object`);\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.ROOT }, sectionRootHref(sectionOutput.section));\n const tags = new Map<string, { resourceRef: string }>();\n const usedResourceRefs = new Set<string>();\n const categoryMetadataById = new Map<string, { label: string; description: string | null }>();\n if (!Array.isArray(document.tags)) throw new Error(`API-reference ${sectionOutput.section} document has no resource tags`);\n for (const tag of document.tags) {\n if (!isRecord(tag) || typeof tag.name !== 'string' || !isRecord(tag['x-wildo']) || typeof tag['x-wildo'].resourceRef !== 'string') {\n throw new Error(`API-reference ${sectionOutput.section} document has a malformed resource tag`);\n }\n if (tags.has(tag.name)) throw new Error(`API-reference ${sectionOutput.section} resource tag is duplicated: '${tag.name}'`);\n const category = tag['x-wildo'].category;\n if (category !== undefined && (!isRecord(category) || typeof category.id !== 'string' || typeof category.label !== 'string'\n || (category.description !== undefined && typeof category.description !== 'string'))) {\n throw new Error(`API-reference resource tag '${tag.name}' has malformed category metadata`);\n }\n const categoryId = isRecord(category) && typeof category.id === 'string' ? category.id : null;\n const categoryLabel = isRecord(category) && typeof category.label === 'string' ? category.label : null;\n const categoryDescription = isRecord(category) && typeof category.description === 'string' ? category.description : null;\n const tagResourceRef = tag['x-wildo'].resourceRef;\n if (resourceName(tagResourceRef) !== tag.name) throw new Error(`API-reference resource tag '${tag.name}' disagrees with its resource identity`);\n tags.set(tag.name, { resourceRef: tagResourceRef });\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: tagResourceRef }, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.RESOURCE,\n resourceName: tag.name,\n }));\n if (categoryId !== null) {\n if (categoryLabel === null) throw new Error(`API-reference resource tag '${tag.name}' has malformed category metadata`);\n const priorMetadata = categoryMetadataById.get(categoryId);\n if (priorMetadata !== undefined && (priorMetadata.label !== categoryLabel || priorMetadata.description !== categoryDescription)) {\n throw new Error(`API-reference category '${categoryId}' has inconsistent source metadata`);\n }\n categoryMetadataById.set(categoryId, { label: categoryLabel, description: categoryDescription });\n const categoryIdentity = { kind: ApiReferenceLinkIdentityKind.CATEGORY, categoryId } as const;\n const key = identityKey(sectionOutput.section, categoryIdentity);\n if (!seen.has(key)) add(sectionOutput.section, categoryIdentity, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.CATEGORY,\n categoryName: categoryId,\n }));\n }\n }\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n if (!isRecord(pathItem)) continue;\n for (const [method, operation] of Object.entries(pathItem)) {\n if (!OPENAPI_HTTP_METHODS.has(method)) continue;\n if (!isRecord(operation) || !isRecord(operation['x-wildo']) || typeof operation.operationId !== 'string') {\n throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has malformed identity metadata`);\n }\n const metadata = operation['x-wildo'];\n if (typeof metadata.resourceRef !== 'string' || typeof metadata.operationFamilyRef !== 'string' || typeof metadata.operationVariantRef !== 'string') {\n throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has incomplete identity metadata`);\n }\n if (metadata.path !== path || metadata.httpVerb !== method) throw new Error(`API-reference ${method.toUpperCase()} ${path} operation identity disagrees with its OpenAPI location`);\n const tag = tags.get(resourceName(metadata.resourceRef));\n if (tag === undefined || tag.resourceRef !== metadata.resourceRef) throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has no matching resource tag`);\n usedResourceRefs.add(metadata.resourceRef);\n const operationTarget = { kind: ApiReferenceTargetKind.OPERATION, operationId: operation.operationId } as const;\n const familyIdentity = { kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY, operationFamilyRef: metadata.operationFamilyRef } as const;\n if (!seen.has(identityKey(sectionOutput.section, familyIdentity))) {\n add(sectionOutput.section, familyIdentity, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.OPERATION_FAMILY,\n resourceName: resourceName(metadata.resourceRef),\n operationName: familyName(metadata.operationFamilyRef),\n }));\n }\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, operationTarget));\n if (isRecord(operation.requestBody)) {\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.REQUEST,\n operationId: operation.operationId,\n }));\n }\n if (isRecord(operation.responses)) {\n for (const status of Object.keys(operation.responses)) {\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESPONSE, operationVariantRef: metadata.operationVariantRef, status }, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.RESPONSE,\n operationId: operation.operationId,\n status,\n }));\n }\n }\n }\n }\n\n for (const [tagName, tag] of tags) {\n if (!usedResourceRefs.has(tag.resourceRef)) {\n throw new Error(`API-reference resource tag '${tagName}' has no rendered HTTP operation`);\n }\n }\n\n const componentSchemas = isRecord(document.components) && isRecord(document.components.schemas) ? document.components.schemas : {};\n for (const schemaName of Object.keys(componentSchemas)) {\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName }, targetHref(sectionOutput.section, {\n kind: ApiReferenceTargetKind.COMPONENT_SCHEMA,\n schemaName,\n }));\n }\n }\n return { schemaVersion: 1, entries: entries.sort((left, right) => identityKey(left.section, left.identity).localeCompare(identityKey(right.section, right.identity))) };\n}\n\n/** Resolves one semantic API target and fails loudly when a guide asks for unavailable documentation. */\nexport function resolveApiReferenceLink(index: ApiReferenceLinkIndex, section: OpenApiSection, identity: ApiReferenceLinkIdentity): string {\n const expectedKey = identityKey(section, identity);\n const entry = index.entries.find((candidate) => identityKey(candidate.section, candidate.identity) === expectedKey);\n if (entry === undefined) throw new Error(`API-reference link target is unavailable: ${expectedKey}`);\n return entry.href;\n}\n\nfunction technicalDocumentationTargetIdentity(target: TechnicalDocumentationApiReferenceTargetV1): {\n readonly section: OpenApiSection;\n readonly identity: ApiReferenceLinkIdentity;\n} {\n const section = target.section === TechnicalDocumentationApiReferenceSection.API_REFERENCE\n ? OpenApiSection.API_REFERENCE\n : OpenApiSection.APPLICATION_ADMINISTRATION_API_REFERENCE;\n switch (target.kind) {\n case TechnicalDocumentationApiReferenceTargetKind.ROOT:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.ROOT } };\n case TechnicalDocumentationApiReferenceTargetKind.CATEGORY:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.CATEGORY, categoryId: target.categoryId } };\n case TechnicalDocumentationApiReferenceTargetKind.RESOURCE:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: target.resourceRef } };\n case TechnicalDocumentationApiReferenceTargetKind.OPERATION_FAMILY:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY, operationFamilyRef: target.operationFamilyRef } };\n case TechnicalDocumentationApiReferenceTargetKind.OPERATION_VARIANT:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: target.operationVariantRef } };\n case TechnicalDocumentationApiReferenceTargetKind.REQUEST:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: target.operationVariantRef } };\n case TechnicalDocumentationApiReferenceTargetKind.RESPONSE:\n return {\n section,\n identity: {\n kind: ApiReferenceLinkIdentityKind.RESPONSE,\n operationVariantRef: target.operationVariantRef,\n status: target.status,\n },\n };\n case TechnicalDocumentationApiReferenceTargetKind.COMPONENT_SCHEMA:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName: target.schemaName } };\n default: {\n const exhaustiveTarget: never = target;\n throw new Error(`Unsupported technical-documentation API-reference target: ${JSON.stringify(exhaustiveTarget)}`);\n }\n }\n}\n\n/**\n * Answers whether a typed target exists in the generated OpenAPI index without\n * manufacturing a URL or turning normal optional-content selection into an\n * exception path. Included guide links must still use the strict resolver.\n */\nexport function getTechnicalDocumentationApiReferenceTargetAvailability(\n index: ApiReferenceLinkIndex,\n target: TechnicalDocumentationApiReferenceTargetV1,\n): TechnicalDocumentationApiReferenceTargetAvailability {\n const { section, identity } = technicalDocumentationTargetIdentity(target);\n const expectedKey = identityKey(section, identity);\n return index.entries.some((candidate) => identityKey(candidate.section, candidate.identity) === expectedKey)\n ? TechnicalDocumentationApiReferenceTargetAvailability.AVAILABLE\n : TechnicalDocumentationApiReferenceTargetAvailability.UNAVAILABLE;\n}\n\n/**\n * Resolves a portable guide target through the generated OpenAPI index.\n *\n * The technical-documentation contract owns the semantic target because guide\n * content cannot depend on the renderer package. This adapter is the only\n * place that translates that portable target into the OpenAPI identities used\n * to produce public consumer URLs.\n */\nexport function resolveTechnicalDocumentationApiReferenceLink(\n index: ApiReferenceLinkIndex,\n target: TechnicalDocumentationApiReferenceTargetV1,\n): string {\n const { section, identity } = technicalDocumentationTargetIdentity(target);\n return resolveApiReferenceLink(index, section, identity);\n}\n"]}
1
+ {"version":3,"file":"api-reference-link-index.js","sourceRoot":"","sources":["../../../src/openapi/api-reference-link-index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Semantic links into the generated API reference.\n *\n * This module projects a canonical OpenAPI document into a small index of\n * public paths. It does not describe or navigate API contracts itself: every\n * entry is derived from standard OpenAPI fields plus the strict `x-wildo`\n * source identities already present in the document. Guide generation can use\n * the index to link to exact API targets without hard-coding Docusaurus URLs\n * or duplicating operations, request DTOs, responses, or schemas.\n */\n\nimport { OpenApiSection, type OpenApiSectionOutput } from './openapi-generation-output.schemas';\nimport {\n TechnicalDocumentationApiReferenceSection,\n TechnicalDocumentationApiReferenceTargetKind,\n type TechnicalDocumentationApiReferenceTargetV1,\n} from '@wildo-ai/saas-specifications/technical-documentation';\nimport {\n ApiReferenceTargetKind,\n ApplicationConsumerDocumentationRoute,\n applicationConsumerDocumentationRoutePath,\n applicationConsumerDocumentationTargetPath,\n apiReferenceTargetFragment,\n type ApiReferencePublicTarget,\n} from './api-reference-targets';\nimport { apiReferencePageHref, buildApiReferencePagePlan, type ApiReferencePagePlan } from './api-reference-pages';\n\n/** The semantic source identity a guide may resolve to a consumer API URL. */\nexport enum ApiReferenceLinkIdentityKind {\n /** A generated section exists and its root page is a valid public destination. */\n ROOT = 'ROOT',\n CATEGORY = 'CATEGORY',\n RESOURCE = 'RESOURCE',\n OPERATION_FAMILY = 'OPERATION_FAMILY',\n OPERATION_VARIANT = 'OPERATION_VARIANT',\n REQUEST = 'REQUEST',\n RESPONSE = 'RESPONSE',\n COMPONENT_SCHEMA = 'COMPONENT_SCHEMA',\n}\n\nexport type ApiReferenceLinkIdentity =\n | { readonly kind: ApiReferenceLinkIdentityKind.ROOT }\n | { readonly kind: ApiReferenceLinkIdentityKind.CATEGORY; readonly categoryId: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.RESOURCE; readonly resourceRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY; readonly operationFamilyRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT; readonly operationVariantRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.REQUEST; readonly operationVariantRef: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.RESPONSE; readonly operationVariantRef: string; readonly status: string }\n | { readonly kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA; readonly schemaName: string };\n\n/** One resolved public URL. `section` keeps an identity unambiguous across both API references. */\nexport interface ApiReferenceLinkIndexEntry {\n readonly section: OpenApiSection;\n readonly identity: ApiReferenceLinkIdentity;\n readonly href: string;\n}\n\n/** JSON-safe result of projecting the selected OpenAPI documents. */\nexport interface ApiReferenceLinkIndex {\n readonly schemaVersion: 1;\n readonly entries: readonly ApiReferenceLinkIndexEntry[];\n}\n\n/**\n * Result of asking whether one semantic guide target exists in the exact\n * generated OpenAPI index. This is deliberately not a boolean: the named\n * vocabulary keeps availability decisions readable at guide-composition call\n * sites and leaves room for future source-owned states without overloading\n * `false`.\n */\nexport enum TechnicalDocumentationApiReferenceTargetAvailability {\n AVAILABLE = 'AVAILABLE',\n UNAVAILABLE = 'UNAVAILABLE',\n}\n\ntype UnknownRecord = Record<string, unknown>;\n\nconst OPENAPI_HTTP_METHODS: ReadonlySet<string> = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']);\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The consumer-documentation route that roots an API-reference section. */\nexport function apiReferenceRouteForSection(section: OpenApiSection): ApplicationConsumerDocumentationRoute {\n switch (section) {\n case OpenApiSection.API_REFERENCE:\n return ApplicationConsumerDocumentationRoute.API_REFERENCE;\n case OpenApiSection.APPLICATION_ADMINISTRATION_API_REFERENCE:\n return ApplicationConsumerDocumentationRoute.APPLICATION_ADMINISTRATION_API_REFERENCE;\n default: {\n const exhaustiveSection: never = section;\n throw new Error(`Unsupported API-reference section: ${String(exhaustiveSection)}`);\n }\n }\n}\n\nfunction resourceName(resourceRef: string): string {\n const name = resourceRef.match(/^technical-documentation:resource\\/([^/]+)$/)?.[1];\n if (name === undefined) throw new Error(`API-reference resource identity is not a canonical resource ref: '${resourceRef}'`);\n return name;\n}\n\nfunction familyName(operationFamilyRef: string): string {\n const name = operationFamilyRef.match(/^technical-documentation:resource\\/[^/]+\\/operation-family\\/([^/]+)$/)?.[1];\n if (name === undefined) throw new Error(`API-reference family identity is not canonical: '${operationFamilyRef}'`);\n return name;\n}\n\n/**\n * A target's public href. Each resource has its own page (#1623), so a resource-scoped target is\n * addressed on that page (`/api/tasks#operation-create-task`) and only a category stays on the\n * section root — the page plan that registers the routes decides, so a guide link and a route can\n * never disagree about where a target lives.\n */\nfunction targetHref(section: OpenApiSection, plan: ApiReferencePagePlan, target: ApiReferencePublicTarget): string {\n return apiReferencePageHref(applicationConsumerDocumentationRoutePath(apiReferenceRouteForSection(section)), apiReferenceTargetFragment(target), plan);\n}\n\n/** The root is an index entry too: a guide may cite it only when that section was generated. */\nfunction sectionRootHref(section: OpenApiSection): string {\n return applicationConsumerDocumentationTargetPath(apiReferenceRouteForSection(section));\n}\n\nfunction identityKey(section: OpenApiSection, identity: ApiReferenceLinkIdentity): string {\n switch (identity.kind) {\n case ApiReferenceLinkIdentityKind.ROOT:\n return `${section}\\0${identity.kind}`;\n case ApiReferenceLinkIdentityKind.CATEGORY:\n return `${section}\\0${identity.kind}\\0${identity.categoryId}`;\n case ApiReferenceLinkIdentityKind.RESOURCE:\n return `${section}\\0${identity.kind}\\0${identity.resourceRef}`;\n case ApiReferenceLinkIdentityKind.OPERATION_FAMILY:\n return `${section}\\0${identity.kind}\\0${identity.operationFamilyRef}`;\n case ApiReferenceLinkIdentityKind.OPERATION_VARIANT:\n case ApiReferenceLinkIdentityKind.REQUEST:\n return `${section}\\0${identity.kind}\\0${identity.operationVariantRef}`;\n case ApiReferenceLinkIdentityKind.RESPONSE:\n return `${section}\\0${identity.kind}\\0${identity.operationVariantRef}\\0${identity.status}`;\n case ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA:\n return `${section}\\0${identity.kind}\\0${identity.schemaName}`;\n default: {\n const exhaustiveIdentity: never = identity;\n throw new Error(`Unsupported API-reference link identity: ${JSON.stringify(exhaustiveIdentity)}`);\n }\n }\n}\n\n/**\n * Creates links from the exact generated OpenAPI documents.\n *\n * This is intentionally a fail-closed projection. An HTTP operation without\n * the established source identity, a tag/operation resource mismatch, or a\n * duplicate semantic target means guide links could become ambiguous, so the\n * index is not emitted at all.\n */\nexport function createApiReferenceLinkIndex(sections: readonly OpenApiSectionOutput[]): ApiReferenceLinkIndex {\n const entries: ApiReferenceLinkIndexEntry[] = [];\n const seen = new Set<string>();\n const sectionSet = new Set<OpenApiSection>();\n const identityByHref = new Map<string, string>();\n const add = (section: OpenApiSection, identity: ApiReferenceLinkIdentity, href: string): void => {\n const key = identityKey(section, identity);\n if (seen.has(key)) throw new Error(`API-reference link identity is duplicated: ${key}`);\n const priorIdentity = identityByHref.get(href);\n if (priorIdentity !== undefined && priorIdentity !== key) {\n throw new Error(`API-reference public link '${href}' is ambiguous between ${priorIdentity} and ${key}`);\n }\n seen.add(key);\n identityByHref.set(href, key);\n entries.push({ section, identity, href });\n };\n\n for (const sectionOutput of sections) {\n if (sectionSet.has(sectionOutput.section)) throw new Error(`API-reference section is duplicated: ${sectionOutput.section}`);\n sectionSet.add(sectionOutput.section);\n const document = sectionOutput.document;\n if (!isRecord(document) || !isRecord(document.paths)) throw new Error(`API-reference ${sectionOutput.section} document has no OpenAPI paths object`);\n const pagePlan = buildApiReferencePagePlan(document);\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.ROOT }, sectionRootHref(sectionOutput.section));\n const tags = new Map<string, { resourceRef: string }>();\n const usedResourceRefs = new Set<string>();\n const categoryMetadataById = new Map<string, { label: string; description: string | null }>();\n if (!Array.isArray(document.tags)) throw new Error(`API-reference ${sectionOutput.section} document has no resource tags`);\n for (const tag of document.tags) {\n if (!isRecord(tag) || typeof tag.name !== 'string' || !isRecord(tag['x-wildo']) || typeof tag['x-wildo'].resourceRef !== 'string') {\n throw new Error(`API-reference ${sectionOutput.section} document has a malformed resource tag`);\n }\n if (tags.has(tag.name)) throw new Error(`API-reference ${sectionOutput.section} resource tag is duplicated: '${tag.name}'`);\n const category = tag['x-wildo'].category;\n if (category !== undefined && (!isRecord(category) || typeof category.id !== 'string' || typeof category.label !== 'string'\n || (category.description !== undefined && typeof category.description !== 'string'))) {\n throw new Error(`API-reference resource tag '${tag.name}' has malformed category metadata`);\n }\n const categoryId = isRecord(category) && typeof category.id === 'string' ? category.id : null;\n const categoryLabel = isRecord(category) && typeof category.label === 'string' ? category.label : null;\n const categoryDescription = isRecord(category) && typeof category.description === 'string' ? category.description : null;\n const tagResourceRef = tag['x-wildo'].resourceRef;\n if (resourceName(tagResourceRef) !== tag.name) throw new Error(`API-reference resource tag '${tag.name}' disagrees with its resource identity`);\n tags.set(tag.name, { resourceRef: tagResourceRef });\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: tagResourceRef }, targetHref(sectionOutput.section, pagePlan, {\n kind: ApiReferenceTargetKind.RESOURCE,\n resourceName: tag.name,\n }));\n if (categoryId !== null) {\n if (categoryLabel === null) throw new Error(`API-reference resource tag '${tag.name}' has malformed category metadata`);\n const priorMetadata = categoryMetadataById.get(categoryId);\n if (priorMetadata !== undefined && (priorMetadata.label !== categoryLabel || priorMetadata.description !== categoryDescription)) {\n throw new Error(`API-reference category '${categoryId}' has inconsistent source metadata`);\n }\n categoryMetadataById.set(categoryId, { label: categoryLabel, description: categoryDescription });\n const categoryIdentity = { kind: ApiReferenceLinkIdentityKind.CATEGORY, categoryId } as const;\n const key = identityKey(sectionOutput.section, categoryIdentity);\n if (!seen.has(key)) add(sectionOutput.section, categoryIdentity, targetHref(sectionOutput.section, pagePlan, {\n kind: ApiReferenceTargetKind.CATEGORY,\n categoryName: categoryId,\n }));\n }\n }\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n if (!isRecord(pathItem)) continue;\n for (const [method, operation] of Object.entries(pathItem)) {\n if (!OPENAPI_HTTP_METHODS.has(method)) continue;\n if (!isRecord(operation) || !isRecord(operation['x-wildo']) || typeof operation.operationId !== 'string') {\n throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has malformed identity metadata`);\n }\n const metadata = operation['x-wildo'];\n if (typeof metadata.resourceRef !== 'string' || typeof metadata.operationFamilyRef !== 'string' || typeof metadata.operationVariantRef !== 'string') {\n throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has incomplete identity metadata`);\n }\n if (metadata.path !== path || metadata.httpVerb !== method) throw new Error(`API-reference ${method.toUpperCase()} ${path} operation identity disagrees with its OpenAPI location`);\n const tag = tags.get(resourceName(metadata.resourceRef));\n if (tag === undefined || tag.resourceRef !== metadata.resourceRef) throw new Error(`API-reference ${method.toUpperCase()} ${path} operation has no matching resource tag`);\n usedResourceRefs.add(metadata.resourceRef);\n const operationTarget = { kind: ApiReferenceTargetKind.OPERATION, operationId: operation.operationId } as const;\n const familyIdentity = { kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY, operationFamilyRef: metadata.operationFamilyRef } as const;\n if (!seen.has(identityKey(sectionOutput.section, familyIdentity))) {\n add(sectionOutput.section, familyIdentity, targetHref(sectionOutput.section, pagePlan, {\n kind: ApiReferenceTargetKind.OPERATION_FAMILY,\n resourceName: resourceName(metadata.resourceRef),\n operationName: familyName(metadata.operationFamilyRef),\n }));\n }\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, pagePlan, operationTarget));\n if (isRecord(operation.requestBody)) {\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: metadata.operationVariantRef }, targetHref(sectionOutput.section, pagePlan, {\n kind: ApiReferenceTargetKind.REQUEST,\n operationId: operation.operationId,\n }));\n }\n if (isRecord(operation.responses)) {\n for (const status of Object.keys(operation.responses)) {\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.RESPONSE, operationVariantRef: metadata.operationVariantRef, status }, targetHref(sectionOutput.section, pagePlan, {\n kind: ApiReferenceTargetKind.RESPONSE,\n operationId: operation.operationId,\n status,\n }));\n }\n }\n }\n }\n\n for (const [tagName, tag] of tags) {\n if (!usedResourceRefs.has(tag.resourceRef)) {\n throw new Error(`API-reference resource tag '${tagName}' has no rendered HTTP operation`);\n }\n }\n\n const componentSchemas = isRecord(document.components) && isRecord(document.components.schemas) ? document.components.schemas : {};\n for (const schemaName of Object.keys(componentSchemas)) {\n const target = { kind: ApiReferenceTargetKind.COMPONENT_SCHEMA, schemaName } as const;\n // A schema no operation reaches is rendered on no page, so it is not offered as a target at all\n // — a guide asking for it gets UNAVAILABLE rather than a link to nothing.\n if (pagePlan.pageSlugByFragment[apiReferenceTargetFragment(target)] === undefined) continue;\n add(sectionOutput.section, { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName }, targetHref(sectionOutput.section, pagePlan, target));\n }\n }\n return { schemaVersion: 1, entries: entries.sort((left, right) => identityKey(left.section, left.identity).localeCompare(identityKey(right.section, right.identity))) };\n}\n\n/** Resolves one semantic API target and fails loudly when a guide asks for unavailable documentation. */\nexport function resolveApiReferenceLink(index: ApiReferenceLinkIndex, section: OpenApiSection, identity: ApiReferenceLinkIdentity): string {\n const expectedKey = identityKey(section, identity);\n const entry = index.entries.find((candidate) => identityKey(candidate.section, candidate.identity) === expectedKey);\n if (entry === undefined) throw new Error(`API-reference link target is unavailable: ${expectedKey}`);\n return entry.href;\n}\n\nfunction technicalDocumentationTargetIdentity(target: TechnicalDocumentationApiReferenceTargetV1): {\n readonly section: OpenApiSection;\n readonly identity: ApiReferenceLinkIdentity;\n} {\n const section = target.section === TechnicalDocumentationApiReferenceSection.API_REFERENCE\n ? OpenApiSection.API_REFERENCE\n : OpenApiSection.APPLICATION_ADMINISTRATION_API_REFERENCE;\n switch (target.kind) {\n case TechnicalDocumentationApiReferenceTargetKind.ROOT:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.ROOT } };\n case TechnicalDocumentationApiReferenceTargetKind.CATEGORY:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.CATEGORY, categoryId: target.categoryId } };\n case TechnicalDocumentationApiReferenceTargetKind.RESOURCE:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.RESOURCE, resourceRef: target.resourceRef } };\n case TechnicalDocumentationApiReferenceTargetKind.OPERATION_FAMILY:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.OPERATION_FAMILY, operationFamilyRef: target.operationFamilyRef } };\n case TechnicalDocumentationApiReferenceTargetKind.OPERATION_VARIANT:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.OPERATION_VARIANT, operationVariantRef: target.operationVariantRef } };\n case TechnicalDocumentationApiReferenceTargetKind.REQUEST:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.REQUEST, operationVariantRef: target.operationVariantRef } };\n case TechnicalDocumentationApiReferenceTargetKind.RESPONSE:\n return {\n section,\n identity: {\n kind: ApiReferenceLinkIdentityKind.RESPONSE,\n operationVariantRef: target.operationVariantRef,\n status: target.status,\n },\n };\n case TechnicalDocumentationApiReferenceTargetKind.COMPONENT_SCHEMA:\n return { section, identity: { kind: ApiReferenceLinkIdentityKind.COMPONENT_SCHEMA, schemaName: target.schemaName } };\n default: {\n const exhaustiveTarget: never = target;\n throw new Error(`Unsupported technical-documentation API-reference target: ${JSON.stringify(exhaustiveTarget)}`);\n }\n }\n}\n\n/**\n * Answers whether a typed target exists in the generated OpenAPI index without\n * manufacturing a URL or turning normal optional-content selection into an\n * exception path. Included guide links must still use the strict resolver.\n */\nexport function getTechnicalDocumentationApiReferenceTargetAvailability(\n index: ApiReferenceLinkIndex,\n target: TechnicalDocumentationApiReferenceTargetV1,\n): TechnicalDocumentationApiReferenceTargetAvailability {\n const { section, identity } = technicalDocumentationTargetIdentity(target);\n const expectedKey = identityKey(section, identity);\n return index.entries.some((candidate) => identityKey(candidate.section, candidate.identity) === expectedKey)\n ? TechnicalDocumentationApiReferenceTargetAvailability.AVAILABLE\n : TechnicalDocumentationApiReferenceTargetAvailability.UNAVAILABLE;\n}\n\n/**\n * Resolves a portable guide target through the generated OpenAPI index.\n *\n * The technical-documentation contract owns the semantic target because guide\n * content cannot depend on the renderer package. This adapter is the only\n * place that translates that portable target into the OpenAPI identities used\n * to produce public consumer URLs.\n */\nexport function resolveTechnicalDocumentationApiReferenceLink(\n index: ApiReferenceLinkIndex,\n target: TechnicalDocumentationApiReferenceTargetV1,\n): string {\n const { section, identity } = technicalDocumentationTargetIdentity(target);\n return resolveApiReferenceLink(index, section, identity);\n}\n"]}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * A page per resource for the API reference, instead of one client-rendered route (#1623).
3
+ *
4
+ * The reference was one route that downloaded and parsed the whole published document on every
5
+ * visit — 9,650,190 bytes for Wonder Todos, measured 2026-09-25 — and addressed every resource,
6
+ * operation and response by `#fragment` state on a ~10,000 px page. Nothing had a page of its own, so
7
+ * nothing had static HTML: not for a reader without JavaScript, not for print, not for the site's
8
+ * search index.
9
+ *
10
+ * This module splits one verified OpenAPI document into what a statically built portal serves:
11
+ *
12
+ * - one PAGE per resource (`/api/<slug>`), carrying that resource's operations and ONLY the
13
+ * components they reach, so a page is complete on its own;
14
+ * - one light INDEX document for the section root: every tag, and every operation reduced to its
15
+ * identity and access, which is all the category grid and the in-page search read;
16
+ * - the map from every public fragment to the page it now lives on, so a link written for the
17
+ * single-page reference (`/api#operation-…`) still reaches its target, and so the link index
18
+ * builds guide links from the same answer.
19
+ *
20
+ * It is pure and imports nothing browser- or Node-specific, so the build plugin that registers the
21
+ * routes and the publication step that writes guide links compute the same plan.
22
+ */
23
+ type JsonRecord = Record<string, unknown>;
24
+ /** One resource's page: its slug, its resource name, and the self-sufficient document it renders. */
25
+ export interface ApiReferenceResourcePage {
26
+ readonly slug: string;
27
+ readonly resourceName: string;
28
+ readonly document: JsonRecord;
29
+ }
30
+ export interface ApiReferencePagePlan {
31
+ /** The section root's document: every tag, and every operation reduced to identity and access. */
32
+ readonly indexDocument: JsonRecord;
33
+ readonly pages: readonly ApiReferenceResourcePage[];
34
+ /** Every public fragment that lives on a resource page, with that page's slug. */
35
+ readonly pageSlugByFragment: Readonly<Record<string, string>>;
36
+ }
37
+ /** Split one verified OpenAPI document into resource pages, an index, and the fragment → page map. */
38
+ export declare function buildApiReferencePagePlan(document: unknown): ApiReferencePagePlan;
39
+ /**
40
+ * The page slug of `fragment`, reading a request or response fragment as its operation's
41
+ * (`operation-x--response-200` lives wherever `operation-x` does). That lets a landing page carry the
42
+ * map WITHOUT the request and response anchors, which were most of its bytes (572 KB of the 1.6 MB
43
+ * Wonder Todos index, measured 2026-09-25): see `withoutOperationSubFragments`.
44
+ */
45
+ export declare function apiReferencePageSlugForFragment(fragment: string, pageSlugByFragment: Readonly<Record<string, string>>): string | undefined;
46
+ /** The fragment map without request and response anchors, which `apiReferencePageSlugForFragment` derives. */
47
+ export declare function withoutOperationSubFragments(pageSlugByFragment: Readonly<Record<string, string>>): Readonly<Record<string, string>>;
48
+ /**
49
+ * The href of a public fragment in a section whose resources have pages: the resource page when the
50
+ * fragment lives on one (`/api/tasks#operation-create-task`), the section root otherwise (a category
51
+ * lives on the index). A resource's own fragment is its page, with no fragment.
52
+ */
53
+ export declare function apiReferencePageHref(sectionRootPath: string, fragment: string, plan: Pick<ApiReferencePagePlan, 'pageSlugByFragment'>): string;
54
+ export {};
55
+ //# sourceMappingURL=api-reference-pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-reference-pages.d.ts","sourceRoot":"","sources":["../../../src/openapi/api-reference-pages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAS1C,qGAAqG;AACrG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACpD,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/D;AAsFD,sGAAsG;AACtG,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,OAAO,GAAG,oBAAoB,CAiFjF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS,CAE1I;AAED,8GAA8G;AAC9G,wBAAgB,4BAA4B,CAAC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAEnI;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,GAAG,MAAM,CAI9I"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * A page per resource for the API reference, instead of one client-rendered route (#1623).
3
+ *
4
+ * The reference was one route that downloaded and parsed the whole published document on every
5
+ * visit — 9,650,190 bytes for Wonder Todos, measured 2026-09-25 — and addressed every resource,
6
+ * operation and response by `#fragment` state on a ~10,000 px page. Nothing had a page of its own, so
7
+ * nothing had static HTML: not for a reader without JavaScript, not for print, not for the site's
8
+ * search index.
9
+ *
10
+ * This module splits one verified OpenAPI document into what a statically built portal serves:
11
+ *
12
+ * - one PAGE per resource (`/api/<slug>`), carrying that resource's operations and ONLY the
13
+ * components they reach, so a page is complete on its own;
14
+ * - one light INDEX document for the section root: every tag, and every operation reduced to its
15
+ * identity and access, which is all the category grid and the in-page search read;
16
+ * - the map from every public fragment to the page it now lives on, so a link written for the
17
+ * single-page reference (`/api#operation-…`) still reaches its target, and so the link index
18
+ * builds guide links from the same answer.
19
+ *
20
+ * It is pure and imports nothing browser- or Node-specific, so the build plugin that registers the
21
+ * routes and the publication step that writes guide links compute the same plan.
22
+ */
23
+ import { ApiReferenceTargetKind, apiReferenceResourcePageSlug, apiReferenceTargetFragment, } from './api-reference-targets.js';
24
+ const HTTP_METHODS = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']);
25
+ /** Path segments the section roots already use; a resource page may never shadow one. */
26
+ const RESERVED_PAGE_SLUGS = new Set(['application-administration']);
27
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
28
+ function resourceNameOf(operation) {
29
+ const metadata = operation['x-wildo'];
30
+ const resourceRef = isRecord(metadata) && typeof metadata.resourceRef === 'string' ? metadata.resourceRef : '';
31
+ const name = resourceRef.match(/^technical-documentation:resource\/([^/]+)$/)?.[1];
32
+ if (name === undefined)
33
+ throw new Error(`API-reference page plan: operation '${String(operation.operationId)}' has no canonical resource identity`);
34
+ return name;
35
+ }
36
+ function familyNameOf(operation) {
37
+ const metadata = operation['x-wildo'];
38
+ const familyRef = isRecord(metadata) && typeof metadata.operationFamilyRef === 'string' ? metadata.operationFamilyRef : '';
39
+ const name = familyRef.match(/\/operation-family\/([^/]+)$/)?.[1];
40
+ if (name === undefined)
41
+ throw new Error(`API-reference page plan: operation '${String(operation.operationId)}' has no canonical family identity`);
42
+ return name;
43
+ }
44
+ /** Every `#/components/<kind>/<name>` reference in `node`, recursively. */
45
+ function collectReferences(node, into) {
46
+ if (Array.isArray(node)) {
47
+ for (const entry of node)
48
+ collectReferences(entry, into);
49
+ return;
50
+ }
51
+ if (!isRecord(node))
52
+ return;
53
+ if (typeof node.$ref === 'string' && node.$ref.startsWith('#/components/'))
54
+ into.add(node.$ref);
55
+ for (const value of Object.values(node))
56
+ collectReferences(value, into);
57
+ }
58
+ /**
59
+ * The components a set of operations reaches, closed transitively: a schema that references another
60
+ * schema brings it along, and a shared response brings the schema its body names.
61
+ */
62
+ function componentClosure(paths, components) {
63
+ const componentSchemas = isRecord(components.schemas) ? components.schemas : {};
64
+ const componentResponses = isRecord(components.responses) ? components.responses : {};
65
+ const pending = new Set();
66
+ collectReferences(paths, pending);
67
+ const schemas = {};
68
+ const responses = {};
69
+ const visited = new Set();
70
+ while (pending.size > 0) {
71
+ const [reference] = pending;
72
+ pending.delete(reference);
73
+ if (visited.has(reference))
74
+ continue;
75
+ visited.add(reference);
76
+ const [, kind, name] = reference.match(/^#\/components\/([^/]+)\/(.+)$/) ?? [];
77
+ const target = kind === 'schemas' ? componentSchemas[name] : kind === 'responses' ? componentResponses[name] : undefined;
78
+ if (target === undefined)
79
+ continue;
80
+ if (kind === 'schemas')
81
+ schemas[name] = target;
82
+ else
83
+ responses[name] = target;
84
+ const more = new Set();
85
+ collectReferences(target, more);
86
+ for (const next of more)
87
+ if (!visited.has(next))
88
+ pending.add(next);
89
+ }
90
+ return { schemas, responses };
91
+ }
92
+ /**
93
+ * An operation as the index needs it: identity, summary, method, path and access — the fields the
94
+ * category grid and the in-page search read. Parameters, bodies and responses stay on the page, and
95
+ * so does the role prose (the index shows role LABELS), which is most of an operation's weight.
96
+ */
97
+ function indexOperation(operation) {
98
+ const metadata = isRecord(operation['x-wildo']) ? operation['x-wildo'] : {};
99
+ const access = isRecord(metadata.access) ? metadata.access : {};
100
+ const roleRequirements = Array.isArray(access.roleRequirements)
101
+ ? access.roleRequirements.map((requirement) => (isRecord(requirement) ? { role: requirement.role, label: requirement.label } : requirement))
102
+ : [];
103
+ return {
104
+ operationId: operation.operationId,
105
+ ...(operation.summary === undefined ? {} : { summary: operation.summary }),
106
+ ...(operation.tags === undefined ? {} : { tags: operation.tags }),
107
+ ...(operation.security === undefined ? {} : { security: operation.security }),
108
+ 'x-wildo': {
109
+ resourceRef: metadata.resourceRef,
110
+ operationFamilyRef: metadata.operationFamilyRef,
111
+ operationVariantRef: metadata.operationVariantRef,
112
+ path: metadata.path,
113
+ httpVerb: metadata.httpVerb,
114
+ ...(metadata.aliasOfPath === undefined ? {} : { aliasOfPath: metadata.aliasOfPath }),
115
+ access: { authenticationMode: access.authenticationMode, authenticationSummary: access.authenticationSummary, roleRequirements },
116
+ },
117
+ };
118
+ }
119
+ /** Split one verified OpenAPI document into resource pages, an index, and the fragment → page map. */
120
+ export function buildApiReferencePagePlan(document) {
121
+ if (!isRecord(document) || !isRecord(document.paths))
122
+ throw new Error('API-reference page plan: document has no OpenAPI paths object');
123
+ const components = isRecord(document.components) ? document.components : {};
124
+ const operationsByResource = new Map();
125
+ for (const [path, pathItem] of Object.entries(document.paths)) {
126
+ if (!isRecord(pathItem))
127
+ continue;
128
+ for (const [method, operation] of Object.entries(pathItem)) {
129
+ if (!HTTP_METHODS.has(method) || !isRecord(operation))
130
+ continue;
131
+ const resourceName = resourceNameOf(operation);
132
+ operationsByResource.set(resourceName, [...(operationsByResource.get(resourceName) ?? []), { path, method, operation }]);
133
+ }
134
+ }
135
+ const pageSlugByFragment = {};
136
+ const claim = (fragment, slug) => {
137
+ const owner = pageSlugByFragment[fragment];
138
+ if (owner !== undefined && owner !== slug)
139
+ throw new Error(`API-reference page plan: fragment '${fragment}' belongs to two pages ('${owner}', '${slug}')`);
140
+ pageSlugByFragment[fragment] = slug;
141
+ };
142
+ const slugByResource = new Map();
143
+ const pages = [];
144
+ const indexPaths = {};
145
+ for (const resourceName of [...operationsByResource.keys()].sort((left, right) => left.localeCompare(right))) {
146
+ const slug = apiReferenceResourcePageSlug(resourceName);
147
+ if (RESERVED_PAGE_SLUGS.has(slug))
148
+ throw new Error(`API-reference page plan: resource '${resourceName}' would shadow the reserved route '${slug}'`);
149
+ const clash = [...slugByResource.entries()].find(([, existing]) => existing === slug);
150
+ if (clash !== undefined)
151
+ throw new Error(`API-reference page plan: resources '${clash[0]}' and '${resourceName}' share the page '${slug}'`);
152
+ slugByResource.set(resourceName, slug);
153
+ const paths = {};
154
+ claim(apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.RESOURCE, resourceName }), slug);
155
+ for (const { path, method, operation } of operationsByResource.get(resourceName)) {
156
+ paths[path] = { ...(paths[path] ?? {}), [method]: operation };
157
+ indexPaths[path] = { ...(indexPaths[path] ?? {}), [method]: indexOperation(operation) };
158
+ const operationId = String(operation.operationId);
159
+ claim(apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.OPERATION_FAMILY, resourceName, operationName: familyNameOf(operation) }), slug);
160
+ claim(apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.OPERATION, operationId }), slug);
161
+ if (isRecord(operation.requestBody))
162
+ claim(apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.REQUEST, operationId }), slug);
163
+ for (const status of Object.keys(isRecord(operation.responses) ? operation.responses : {})) {
164
+ claim(apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.RESPONSE, operationId, status }), slug);
165
+ }
166
+ }
167
+ const closure = componentClosure(paths, components);
168
+ // A reusable schema lives on the first page (by slug) that reaches it; later pages link to it there.
169
+ for (const schemaName of Object.keys(closure.schemas)) {
170
+ const fragment = apiReferenceTargetFragment({ kind: ApiReferenceTargetKind.COMPONENT_SCHEMA, schemaName });
171
+ if (pageSlugByFragment[fragment] === undefined)
172
+ pageSlugByFragment[fragment] = slug;
173
+ }
174
+ pages.push({
175
+ slug,
176
+ resourceName,
177
+ document: {
178
+ openapi: document.openapi,
179
+ ...(isRecord(document.info) ? { info: { title: document.info.title, version: document.info.version } } : {}),
180
+ ...(document.servers === undefined ? {} : { servers: document.servers }),
181
+ // Every tag, so a relationship to another resource is labelled by that resource's own name.
182
+ ...(document.tags === undefined ? {} : { tags: document.tags }),
183
+ paths,
184
+ components: {
185
+ schemas: closure.schemas,
186
+ ...(Object.keys(closure.responses).length > 0 ? { responses: closure.responses } : {}),
187
+ ...(components.securitySchemes === undefined ? {} : { securitySchemes: components.securitySchemes }),
188
+ },
189
+ },
190
+ });
191
+ }
192
+ return {
193
+ indexDocument: {
194
+ openapi: document.openapi,
195
+ ...(document.info === undefined ? {} : { info: document.info }),
196
+ ...(document.servers === undefined ? {} : { servers: document.servers }),
197
+ ...(document.tags === undefined ? {} : { tags: document.tags }),
198
+ paths: indexPaths,
199
+ components: components.securitySchemes === undefined ? {} : { securitySchemes: components.securitySchemes },
200
+ },
201
+ pages,
202
+ pageSlugByFragment,
203
+ };
204
+ }
205
+ /**
206
+ * The page slug of `fragment`, reading a request or response fragment as its operation's
207
+ * (`operation-x--response-200` lives wherever `operation-x` does). That lets a landing page carry the
208
+ * map WITHOUT the request and response anchors, which were most of its bytes (572 KB of the 1.6 MB
209
+ * Wonder Todos index, measured 2026-09-25): see `withoutOperationSubFragments`.
210
+ */
211
+ export function apiReferencePageSlugForFragment(fragment, pageSlugByFragment) {
212
+ return pageSlugByFragment[fragment] ?? pageSlugByFragment[fragment.replace(/--(request|response-[a-z0-9-]+)$/, '')];
213
+ }
214
+ /** The fragment map without request and response anchors, which `apiReferencePageSlugForFragment` derives. */
215
+ export function withoutOperationSubFragments(pageSlugByFragment) {
216
+ return Object.fromEntries(Object.entries(pageSlugByFragment).filter(([fragment]) => !/^operation-.+--(request|response-[a-z0-9-]+)$/.test(fragment)));
217
+ }
218
+ /**
219
+ * The href of a public fragment in a section whose resources have pages: the resource page when the
220
+ * fragment lives on one (`/api/tasks#operation-create-task`), the section root otherwise (a category
221
+ * lives on the index). A resource's own fragment is its page, with no fragment.
222
+ */
223
+ export function apiReferencePageHref(sectionRootPath, fragment, plan) {
224
+ const slug = apiReferencePageSlugForFragment(fragment, plan.pageSlugByFragment);
225
+ if (slug === undefined)
226
+ return `${sectionRootPath}#${fragment}`;
227
+ return fragment === `resource-${slug}` ? `${sectionRootPath}/${slug}` : `${sectionRootPath}/${slug}#${fragment}`;
228
+ }
229
+ //# sourceMappingURL=api-reference-pages.js.map