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

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 (85) hide show
  1. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts +37 -0
  2. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
  3. package/dist/esm/companion/application-documentation/application-connection-documentation.js +46 -5
  4. package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -1
  5. package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts +101 -0
  6. package/dist/esm/companion/application-documentation/application-documentation-chapters.d.ts.map +1 -0
  7. package/dist/esm/companion/application-documentation/application-documentation-chapters.js +205 -0
  8. package/dist/esm/companion/application-documentation/application-documentation-chapters.js.map +1 -0
  9. package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.js +3 -0
  10. package/dist/esm/companion/application-documentation/application-organization-unit-resource-documentation.js.map +1 -1
  11. package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts +34 -0
  12. package/dist/esm/companion/application-documentation/docs-api-origin-substitution.d.ts.map +1 -0
  13. package/dist/esm/companion/application-documentation/docs-api-origin-substitution.js +45 -0
  14. package/dist/esm/companion/application-documentation/docs-api-origin-substitution.js.map +1 -0
  15. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts +24 -10
  16. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
  17. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js +25 -15
  18. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js.map +1 -1
  19. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts +11 -3
  20. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
  21. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js +9 -2
  22. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js.map +1 -1
  23. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.d.ts.map +1 -1
  24. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js +10 -4
  25. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js.map +1 -1
  26. package/dist/esm/companion/index.d.ts +2 -0
  27. package/dist/esm/companion/index.d.ts.map +1 -1
  28. package/dist/esm/companion/index.js +2 -0
  29. package/dist/esm/companion/index.js.map +1 -1
  30. package/dist/esm/companion/openapi-generator.d.ts +8 -4
  31. package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
  32. package/dist/esm/companion/openapi-generator.js +43 -17
  33. package/dist/esm/companion/openapi-generator.js.map +1 -1
  34. package/dist/esm/companion/operation-projection.schemas.d.ts +21 -1
  35. package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
  36. package/dist/esm/companion/operation-projection.schemas.js +11 -0
  37. package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
  38. package/dist/esm/companion/publish-result.types.d.ts +37 -4
  39. package/dist/esm/companion/publish-result.types.d.ts.map +1 -1
  40. package/dist/esm/companion/publish-result.types.js.map +1 -1
  41. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
  42. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js +8 -0
  43. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js.map +1 -1
  44. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
  45. package/dist/esm/companion/rendering/technical-documentation-render-model.js +26 -10
  46. package/dist/esm/companion/rendering/technical-documentation-render-model.js.map +1 -1
  47. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +18 -15
  48. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
  49. package/dist/esm/content/application-consumer-documentation-content.techdoc.js +169 -61
  50. package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
  51. package/dist/esm/runtime/DocsAuthContext.d.ts +2 -2
  52. package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
  53. package/dist/esm/runtime/DocsAuthContext.js +8 -4
  54. package/dist/esm/runtime/DocsAuthContext.js.map +1 -1
  55. package/dist/esm/runtime/DocsFrontendProviders.d.ts +16 -0
  56. package/dist/esm/runtime/DocsFrontendProviders.d.ts.map +1 -0
  57. package/dist/esm/runtime/DocsFrontendProviders.js +26 -0
  58. package/dist/esm/runtime/DocsFrontendProviders.js.map +1 -0
  59. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts +1 -2
  60. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
  61. package/dist/esm/runtime/frontend-provider-registry.techdoc.js.map +1 -1
  62. package/dist/esm/runtime/index.d.ts +2 -0
  63. package/dist/esm/runtime/index.d.ts.map +1 -1
  64. package/dist/esm/runtime/index.js +2 -0
  65. package/dist/esm/runtime/index.js.map +1 -1
  66. package/dist/esm/runtime/openapi-reference-model.d.ts +5 -0
  67. package/dist/esm/runtime/openapi-reference-model.d.ts.map +1 -1
  68. package/dist/esm/runtime/openapi-reference-model.js +5 -0
  69. package/dist/esm/runtime/openapi-reference-model.js.map +1 -1
  70. package/dist/esm/runtime/openapi-reference-view.js +1 -1
  71. package/dist/esm/runtime/openapi-reference-view.js.map +1 -1
  72. package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts +1 -0
  73. package/dist/esm/runtime/use-docs-frontend-provider-registry.d.ts.map +1 -1
  74. package/dist/esm/runtime/use-docs-frontend-provider-registry.js +10 -2
  75. package/dist/esm/runtime/use-docs-frontend-provider-registry.js.map +1 -1
  76. package/dist/esm/runtime/use-docs-provider-scripts.d.ts +30 -0
  77. package/dist/esm/runtime/use-docs-provider-scripts.d.ts.map +1 -0
  78. package/dist/esm/runtime/use-docs-provider-scripts.js +40 -0
  79. package/dist/esm/runtime/use-docs-provider-scripts.js.map +1 -0
  80. package/dist/tsconfig.build.tsbuildinfo +1 -1
  81. package/package.json +8 -24
  82. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts +0 -0
  83. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts.map +0 -0
  84. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js +0 -0
  85. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js.map +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"application-organization-unit-resource-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-organization-unit-resource-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n} from '@wildo-ai/saas-specifications/technical-documentation';\n\nimport type { ResourceTag } from '../operation-projection.schemas';\n\nexport const APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF =\n 'source:companion-projection:organization-unit-aware-resources' as const;\n/** Advances when this projection's shape changes; it is the fact's version wherever provenance cites it. */\nexport const APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_VERSION = 1;\n\n/** Exact Markdown fact composed into the organization-unit task pages. */\nexport interface ApplicationOrganizationUnitResourcesDocumentationFact {\n readonly sourceRef: typeof APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF;\n readonly markdown: string;\n readonly sourceVersion: number;\n}\n\n/**\n * Consumer-safe view of one application resource that explicitly opts into\n * organization-unit narrowing. The internal field holding the unit identity is\n * deliberately absent: administrators need to know which business information\n * is narrowed, not how its persistence schema implements that decision.\n */\nexport interface ApplicationOrganizationUnitResourceDocumentation {\n readonly resourceIdentifier: string;\n readonly label: string;\n readonly purpose: string;\n}\n\n/**\n * Project the exact startup declaration into a small consumer-safe fact list.\n *\n * The declaration is the only authority for inclusion. A unit-shaped URL, a\n * relationship to organization units, or a similarly named field is not\n * evidence that runtime authorization narrows the resource. Every included\n * resource must also have specification-owned purpose prose; publication fails\n * rather than exposing a raw identifier with no explanation.\n */\nexport function projectApplicationOrganizationUnitResourceDocumentation(\n organizationUnitNarrowing: Readonly<Partial<Record<string, { readonly unitFieldName: string }>>> | undefined,\n resourceTags: readonly ResourceTag[],\n): readonly ApplicationOrganizationUnitResourceDocumentation[] {\n const tagsByIdentifier = new Map<string, ResourceTag>();\n for (const tag of resourceTags) {\n if (tagsByIdentifier.has(tag.name)) {\n throw new Error(`application organization-unit resource projector: duplicate resource tag '${tag.name}'`);\n }\n tagsByIdentifier.set(tag.name, tag);\n }\n\n return Object.freeze(Object.entries(organizationUnitNarrowing ?? {})\n .filter((entry): entry is [string, { readonly unitFieldName: string }] => entry[1] !== undefined)\n .map(([resourceIdentifier, declaration]) => {\n if (declaration.unitFieldName.trim().length === 0) {\n throw new Error(`application organization-unit resource projector: '${resourceIdentifier}' has an empty narrowing field declaration`);\n }\n const tag = tagsByIdentifier.get(resourceIdentifier);\n if (tag?.description === undefined || tag.description.trim().length === 0) {\n throw new Error(\n `application organization-unit resource projector: narrowed resource '${resourceIdentifier}' has no specification-owned purpose`,\n );\n }\n return Object.freeze({\n resourceIdentifier,\n label: resourceDisplayLabel(resourceIdentifier),\n purpose: tag.description.trim(),\n });\n })\n .sort((left, right) => left.label.localeCompare(right.label, 'en-US') || left.resourceIdentifier.localeCompare(right.resourceIdentifier, 'en-US')));\n}\n\n/** Materialize the application-specific list inserted into unit-access guides. */\nexport function createApplicationOrganizationUnitResourcesDocumentationFact(\n resources: readonly ApplicationOrganizationUnitResourceDocumentation[],\n): ApplicationOrganizationUnitResourcesDocumentationFact {\n if (new Set(resources.map((resource) => resource.resourceIdentifier)).size !== resources.length) {\n throw new Error('technical documentation received duplicate organization-unit-aware resources');\n }\n const canonicalResources = [...resources]\n .sort((left, right) => left.label.localeCompare(right.label, 'en-US') || left.resourceIdentifier.localeCompare(right.resourceIdentifier, 'en-US'));\n const markdown = canonicalResources.length === 0\n ? '**This application does not currently declare any business resource as organization-unit-aware.** A unit assignment therefore grants no additional access until the application publishes such a resource.'\n : `This application currently applies organization-unit access to:\\n\\n${canonicalResources\n .map((resource) => `- **${markdownText(resource.label)}** — ${markdownText(resource.purpose)}`)\n .join('\\n')}\\n\\nOnly the resources listed here use unit assignments. Other application information continues to follow its organization-wide operation rules.`;\n\n return Object.freeze({\n sourceRef: APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF,\n markdown,\n sourceVersion: APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_VERSION,\n });\n}\n\n/** Match the native API-reference fallback without changing resource identity. */\nfunction resourceDisplayLabel(identifier: string): string {\n return identifier\n .replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replaceAll(/[-_]+/g, ' ')\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => (/^[A-Z0-9]+$/u.test(word) ? word : `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`))\n .join(' ');\n}\n\nfunction markdownText(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim().replaceAll('\\\\', '\\\\\\\\').replaceAll(/([`*_[\\]<>#|])/g, '\\\\$1');\n}\n"]}
1
+ {"version":3,"file":"application-organization-unit-resource-documentation.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/application-organization-unit-resource-documentation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n} from '@wildo-ai/saas-specifications/technical-documentation';\n\nimport type { ResourceTag } from '../operation-projection.schemas';\n\nexport const APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF =\n 'source:companion-projection:organization-unit-aware-resources' as const;\n/** Advances when this projection's shape changes; it is the fact's version wherever provenance cites it. */\nexport const APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_VERSION = 1;\n\n/** Exact Markdown fact composed into the organization-unit task pages. */\nexport interface ApplicationOrganizationUnitResourcesDocumentationFact {\n readonly sourceRef: typeof APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF;\n readonly markdown: string;\n readonly sourceVersion: number;\n}\n\n/**\n * Consumer-safe view of one application resource that explicitly opts into\n * organization-unit narrowing. The internal field holding the unit identity is\n * deliberately absent: administrators need to know which business information\n * is narrowed, not how its persistence schema implements that decision.\n */\nexport interface ApplicationOrganizationUnitResourceDocumentation {\n readonly resourceIdentifier: string;\n readonly label: string;\n readonly purpose: string;\n}\n\n/**\n * Project the exact startup declaration into a small consumer-safe fact list.\n *\n * The declaration is the only authority for inclusion. A unit-shaped URL, a\n * relationship to organization units, or a similarly named field is not\n * evidence that runtime authorization narrows the resource. Every included\n * resource must also have specification-owned purpose prose; publication fails\n * rather than exposing a raw identifier with no explanation.\n */\nexport function projectApplicationOrganizationUnitResourceDocumentation(\n organizationUnitNarrowing: Readonly<Partial<Record<string, { readonly unitFieldName: string }>>> | undefined,\n resourceTags: readonly ResourceTag[],\n): readonly ApplicationOrganizationUnitResourceDocumentation[] {\n const tagsByIdentifier = new Map<string, ResourceTag>();\n for (const tag of resourceTags) {\n if (tagsByIdentifier.has(tag.name)) {\n throw new Error(`application organization-unit resource projector: duplicate resource tag '${tag.name}'`);\n }\n tagsByIdentifier.set(tag.name, tag);\n }\n\n return Object.freeze(Object.entries(organizationUnitNarrowing ?? {})\n .filter((entry): entry is [string, { readonly unitFieldName: string }] => entry[1] !== undefined)\n .map(([resourceIdentifier, declaration]) => {\n if (declaration.unitFieldName.trim().length === 0) {\n throw new Error(`application organization-unit resource projector: '${resourceIdentifier}' has an empty narrowing field declaration`);\n }\n const tag = tagsByIdentifier.get(resourceIdentifier);\n if (tag?.description === undefined || tag.description.trim().length === 0) {\n throw new Error(\n `application organization-unit resource projector: narrowed resource '${resourceIdentifier}' has no specification-owned purpose`,\n );\n }\n return Object.freeze({\n resourceIdentifier,\n label: resourceDisplayLabel(resourceIdentifier),\n purpose: tag.description.trim(),\n });\n })\n .sort((left, right) => left.label.localeCompare(right.label, 'en-US') || left.resourceIdentifier.localeCompare(right.resourceIdentifier, 'en-US')));\n}\n\n/** Materialize the application-specific list inserted into unit-access guides. */\nexport function createApplicationOrganizationUnitResourcesDocumentationFact(\n resources: readonly ApplicationOrganizationUnitResourceDocumentation[],\n): ApplicationOrganizationUnitResourcesDocumentationFact {\n if (new Set(resources.map((resource) => resource.resourceIdentifier)).size !== resources.length) {\n throw new Error('technical documentation received duplicate organization-unit-aware resources');\n }\n const canonicalResources = [...resources]\n .sort((left, right) => left.label.localeCompare(right.label, 'en-US') || left.resourceIdentifier.localeCompare(right.resourceIdentifier, 'en-US'));\n const markdown = canonicalResources.length === 0\n ? '**This application does not currently declare any business resource as organization-unit-aware.** A unit assignment therefore grants no additional access until the application publishes such a resource.'\n : `This application currently applies organization-unit access to:\\n\\n${canonicalResources\n .map((resource) => `- **${markdownText(resource.label)}** — ${markdownText(resource.purpose)}`)\n .join('\\n')}\\n\\nOnly the resources listed here use unit assignments. Other application information continues to follow its organization-wide operation rules.`;\n\n return Object.freeze({\n sourceRef: APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_REF,\n markdown,\n sourceVersion: APPLICATION_ORGANIZATION_UNIT_RESOURCES_DOCUMENTATION_SOURCE_VERSION,\n });\n}\n\n/** Match the native API-reference fallback without changing resource identity. */\n// Generated API-reference prose, as in `openapi-reference-model.ts`. The technical-doc lane has no\n// label tree and is not translated.\nfunction resourceDisplayLabel(identifier: string): string {\n // invented-display-text: generated API-reference prose.\n return identifier\n .replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replaceAll(/[-_]+/g, ' ')\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => (/^[A-Z0-9]+$/u.test(word) ? word : `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`))\n .join(' ');\n}\n\nfunction markdownText(value: string): string {\n return value.replaceAll(/\\s+/g, ' ').trim().replaceAll('\\\\', '\\\\\\\\').replaceAll(/([`*_[\\]<>#|])/g, '\\\\$1');\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Replace the build-time API-origin token in generated documentation (#1203).
3
+ *
4
+ * Generation writes {@link DOCS_API_ORIGIN_TOKEN} wherever the application's primary origin belongs,
5
+ * so the committed artifacts are environment-INDEPENDENT. This is the other half: the image build
6
+ * knows which environment it is for, and puts that origin in.
7
+ *
8
+ * ## Why a build step and not a runtime read
9
+ *
10
+ * The docs site already receives `WILDO_DOCS_API_BASE_URL` through Docusaurus `customFields`, and an
11
+ * MDX component could read it. The static OpenAPI documents cannot — they are served as files and
12
+ * have no runtime — and they carry the `servers` an API client is configured from, which is one of
13
+ * the surfaces that shipped a developer's `localhost`. One substitution over the generated tree
14
+ * covers both, which is why the issue's option (1) was the only one that covered every surface.
15
+ *
16
+ * ## The absent case is NOT the token
17
+ *
18
+ * With no origin supplied, the text falls back to the same stand-in an application that publishes no
19
+ * base URL already gets. A published page must never show a raw token: that is strictly worse than
20
+ * the `localhost` this replaces, because a reader can at least recognise an origin as wrong.
21
+ */
22
+ export declare function substituteDocsApiOrigin(text: string, apiBaseUrl: string | undefined): string;
23
+ /**
24
+ * The origin as it belongs in documentation: no trailing slash, and no `/api/v1` suffix.
25
+ *
26
+ * `WILDO_DOCS_API_BASE_URL` is authored for the docs RUNTIME's auth client, which accepts either
27
+ * form — `docs-auth-client.ts` strips the API root itself for exactly that reason. Documentation
28
+ * interpolates the ORIGIN and appends its own paths, so a value carrying the API root would produce
29
+ * `…/api/v1/api/v1/scim/v2`.
30
+ */
31
+ export declare function normalizeDocsApiOrigin(apiBaseUrl: string | undefined): string;
32
+ /** Whether a rendered tree still carries the token — what a build step asserts before publishing. */
33
+ export declare function containsUnsubstitutedDocsApiOrigin(text: string): boolean;
34
+ //# sourceMappingURL=docs-api-origin-substitution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-api-origin-substitution.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/docs-api-origin-substitution.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG5F;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI7E;AAED,qGAAqG;AACrG,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExE"}
@@ -0,0 +1,45 @@
1
+ import { DOCS_API_ORIGIN_TOKEN, UNPUBLISHED_BASE_URL_STAND_IN } from './application-connection-documentation.js';
2
+ /**
3
+ * Replace the build-time API-origin token in generated documentation (#1203).
4
+ *
5
+ * Generation writes {@link DOCS_API_ORIGIN_TOKEN} wherever the application's primary origin belongs,
6
+ * so the committed artifacts are environment-INDEPENDENT. This is the other half: the image build
7
+ * knows which environment it is for, and puts that origin in.
8
+ *
9
+ * ## Why a build step and not a runtime read
10
+ *
11
+ * The docs site already receives `WILDO_DOCS_API_BASE_URL` through Docusaurus `customFields`, and an
12
+ * MDX component could read it. The static OpenAPI documents cannot — they are served as files and
13
+ * have no runtime — and they carry the `servers` an API client is configured from, which is one of
14
+ * the surfaces that shipped a developer's `localhost`. One substitution over the generated tree
15
+ * covers both, which is why the issue's option (1) was the only one that covered every surface.
16
+ *
17
+ * ## The absent case is NOT the token
18
+ *
19
+ * With no origin supplied, the text falls back to the same stand-in an application that publishes no
20
+ * base URL already gets. A published page must never show a raw token: that is strictly worse than
21
+ * the `localhost` this replaces, because a reader can at least recognise an origin as wrong.
22
+ */
23
+ export function substituteDocsApiOrigin(text, apiBaseUrl) {
24
+ const origin = normalizeDocsApiOrigin(apiBaseUrl);
25
+ return text.split(DOCS_API_ORIGIN_TOKEN).join(origin);
26
+ }
27
+ /**
28
+ * The origin as it belongs in documentation: no trailing slash, and no `/api/v1` suffix.
29
+ *
30
+ * `WILDO_DOCS_API_BASE_URL` is authored for the docs RUNTIME's auth client, which accepts either
31
+ * form — `docs-auth-client.ts` strips the API root itself for exactly that reason. Documentation
32
+ * interpolates the ORIGIN and appends its own paths, so a value carrying the API root would produce
33
+ * `…/api/v1/api/v1/scim/v2`.
34
+ */
35
+ export function normalizeDocsApiOrigin(apiBaseUrl) {
36
+ const trimmed = (apiBaseUrl ?? '').trim();
37
+ if (trimmed.length === 0)
38
+ return UNPUBLISHED_BASE_URL_STAND_IN;
39
+ return trimmed.replace(/\/+$/, '').replace(/\/api\/v1$/, '');
40
+ }
41
+ /** Whether a rendered tree still carries the token — what a build step asserts before publishing. */
42
+ export function containsUnsubstitutedDocsApiOrigin(text) {
43
+ return text.includes(DOCS_API_ORIGIN_TOKEN);
44
+ }
45
+ //# sourceMappingURL=docs-api-origin-substitution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-api-origin-substitution.js","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/docs-api-origin-substitution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAC;AAE9G;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,UAA8B;IAClF,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA8B;IACnE,MAAM,OAAO,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,6BAA6B,CAAC;IAC/D,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,kCAAkC,CAAC,IAAY;IAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;AAC9C,CAAC","sourcesContent":["import { DOCS_API_ORIGIN_TOKEN, UNPUBLISHED_BASE_URL_STAND_IN } from './application-connection-documentation';\n\n/**\n * Replace the build-time API-origin token in generated documentation (#1203).\n *\n * Generation writes {@link DOCS_API_ORIGIN_TOKEN} wherever the application's primary origin belongs,\n * so the committed artifacts are environment-INDEPENDENT. This is the other half: the image build\n * knows which environment it is for, and puts that origin in.\n *\n * ## Why a build step and not a runtime read\n *\n * The docs site already receives `WILDO_DOCS_API_BASE_URL` through Docusaurus `customFields`, and an\n * MDX component could read it. The static OpenAPI documents cannot — they are served as files and\n * have no runtime — and they carry the `servers` an API client is configured from, which is one of\n * the surfaces that shipped a developer's `localhost`. One substitution over the generated tree\n * covers both, which is why the issue's option (1) was the only one that covered every surface.\n *\n * ## The absent case is NOT the token\n *\n * With no origin supplied, the text falls back to the same stand-in an application that publishes no\n * base URL already gets. A published page must never show a raw token: that is strictly worse than\n * the `localhost` this replaces, because a reader can at least recognise an origin as wrong.\n */\nexport function substituteDocsApiOrigin(text: string, apiBaseUrl: string | undefined): string {\n const origin = normalizeDocsApiOrigin(apiBaseUrl);\n return text.split(DOCS_API_ORIGIN_TOKEN).join(origin);\n}\n\n/**\n * The origin as it belongs in documentation: no trailing slash, and no `/api/v1` suffix.\n *\n * `WILDO_DOCS_API_BASE_URL` is authored for the docs RUNTIME's auth client, which accepts either\n * form — `docs-auth-client.ts` strips the API root itself for exactly that reason. Documentation\n * interpolates the ORIGIN and appends its own paths, so a value carrying the API root would produce\n * `…/api/v1/api/v1/scim/v2`.\n */\nexport function normalizeDocsApiOrigin(apiBaseUrl: string | undefined): string {\n const trimmed = (apiBaseUrl ?? '').trim();\n if (trimmed.length === 0) return UNPUBLISHED_BASE_URL_STAND_IN;\n return trimmed.replace(/\\/+$/, '').replace(/\\/api\\/v1$/, '');\n}\n\n/** Whether a rendered tree still carries the token — what a build step asserts before publishing. */\nexport function containsUnsubstitutedDocsApiOrigin(text: string): boolean {\n return text.includes(DOCS_API_ORIGIN_TOKEN);\n}\n"]}
@@ -78,20 +78,34 @@ export declare const APPLICATION_DOMAIN_RESOURCE_PAGE_UNIT_REF_PREFIX = "technic
78
78
  * silent gap, because a kind nobody authors looks exactly like a kind nobody needed (#474). RUNBOOK
79
79
  * now has one. CHANGE does not, and the reason is structural rather than editorial:
80
80
  *
81
- * A CHANGE unit is a record of what changed in ONE application, so only that application could
82
- * author it — and an application-authored unit cannot be routed. `pathForUnit` admits engine-
83
- * namespaced slugs and the reserved `unit/manages/` namespace, and refuses everything else with
84
- * "has no consumer navigation category". Application material reaches the site only as an ENGINE
85
- * unit carrying application-projected facts, never as an application-authored page. So the engine
86
- * cannot write a changelog it has no knowledge of, and the party that could has no door.
81
+ * A CHANGE unit is a record of what changed in ONE application, so only that application can
82
+ * author it. Until #874 that party had no door: an application-authored unit could not be routed.
83
+ * It now can — a chapter the application's documentation plan declares, authored in its
84
+ * specifications package and routed under `guides/` (`application-documentation-chapters.ts`) —
85
+ * so a CHANGE page has a producer, and it is the application.
87
86
  *
88
- * The member is therefore kept rather than retired: what is missing is a route for
89
- * application-authored units, not the concept. When that route exists, this entry is removed in the
90
- * same change — and `technical-documentation-engine-content-bundle.test.ts` fails until it is,
91
- * because the partition below is asserted total over the enum.
87
+ * The entry STAYS in this map, because this map describes the ENGINE catalogue and the partition
88
+ * test below is total over it: the engine still authors no CHANGE unit, and must not — it has no
89
+ * knowledge of what any one application changed. The reason text is what moved, from "no door" to
90
+ * "the door belongs to the application".
92
91
  */
93
92
  export declare const ENGINE_CONTENT_UNIT_KINDS_WITHOUT_PRODUCER: Readonly<Partial<Record<TechnicalDocumentationUnitKind, string>>>;
94
93
  export declare const ENGINE_CONTENT_UNIT_DEFINITIONS: Readonly<Record<string, EngineContentUnitDefinition>>;
94
+ /**
95
+ * The one Markdown-to-unit parser, shared by every tier that turns authored prose into a unit: the
96
+ * engine's own pages, and the chapters an application authors (#874). One parser means one rule for
97
+ * what a title, a summary and a section ARE — a second copy would let an application's guide and an
98
+ * engine page split the same text differently, and the difference would surface as a portal whose
99
+ * two halves summarize themselves by two conventions.
100
+ */
101
+ export declare function parseTechnicalDocumentationUnitMarkdown(markdown: string, unitRef: string): {
102
+ readonly title: string;
103
+ readonly summary: string;
104
+ readonly sections: readonly {
105
+ readonly heading: string;
106
+ readonly bodyMarkdown: string;
107
+ }[];
108
+ };
95
109
  /**
96
110
  * The facts only the application knows, which the companion measures and passes in.
97
111
  *
@@ -1 +1 @@
1
- {"version":3,"file":"technical-documentation-engine-content-bundle.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/technical-documentation-engine-content-bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"technical-documentation-engine-content-bundle.d.ts","sourceRoot":"","sources":["../../../../../src/companion/application-documentation/technical-documentation-engine-content-bundle.ts"],"names":[],"mappings":"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"}
@@ -174,21 +174,20 @@ const GENERATED_RESOURCE_UNIT_DEFINITION = Object.freeze({
174
174
  * silent gap, because a kind nobody authors looks exactly like a kind nobody needed (#474). RUNBOOK
175
175
  * now has one. CHANGE does not, and the reason is structural rather than editorial:
176
176
  *
177
- * A CHANGE unit is a record of what changed in ONE application, so only that application could
178
- * author it — and an application-authored unit cannot be routed. `pathForUnit` admits engine-
179
- * namespaced slugs and the reserved `unit/manages/` namespace, and refuses everything else with
180
- * "has no consumer navigation category". Application material reaches the site only as an ENGINE
181
- * unit carrying application-projected facts, never as an application-authored page. So the engine
182
- * cannot write a changelog it has no knowledge of, and the party that could has no door.
177
+ * A CHANGE unit is a record of what changed in ONE application, so only that application can
178
+ * author it. Until #874 that party had no door: an application-authored unit could not be routed.
179
+ * It now can — a chapter the application's documentation plan declares, authored in its
180
+ * specifications package and routed under `guides/` (`application-documentation-chapters.ts`) —
181
+ * so a CHANGE page has a producer, and it is the application.
183
182
  *
184
- * The member is therefore kept rather than retired: what is missing is a route for
185
- * application-authored units, not the concept. When that route exists, this entry is removed in the
186
- * same change — and `technical-documentation-engine-content-bundle.test.ts` fails until it is,
187
- * because the partition below is asserted total over the enum.
183
+ * The entry STAYS in this map, because this map describes the ENGINE catalogue and the partition
184
+ * test below is total over it: the engine still authors no CHANGE unit, and must not — it has no
185
+ * knowledge of what any one application changed. The reason text is what moved, from "no door" to
186
+ * "the door belongs to the application".
188
187
  */
189
188
  export const ENGINE_CONTENT_UNIT_KINDS_WITHOUT_PRODUCER = {
190
- [TechnicalDocumentationUnitKind.CHANGE]: 'A change record belongs to one application, and an application-authored unit has no route — `pathForUnit` '
191
- + 'admits only engine-namespaced slugs and the reserved `unit/manages/` namespace. Blocked on routing, not on authoring.',
189
+ [TechnicalDocumentationUnitKind.CHANGE]: 'A change record belongs to one application, so the engine cannot author it. Its producer is the application: '
190
+ + 'a CHANGE chapter in the documentation plan, authored in the specifications package and routed under `guides/` (#874).',
192
191
  };
193
192
  export const ENGINE_CONTENT_UNIT_DEFINITIONS = Object.freeze({
194
193
  'technical-documentation:unit/application-orientation': {
@@ -1568,6 +1567,16 @@ export const ENGINE_CONTENT_UNIT_DEFINITIONS = Object.freeze({
1568
1567
  ],
1569
1568
  },
1570
1569
  });
1570
+ /**
1571
+ * The one Markdown-to-unit parser, shared by every tier that turns authored prose into a unit: the
1572
+ * engine's own pages, and the chapters an application authors (#874). One parser means one rule for
1573
+ * what a title, a summary and a section ARE — a second copy would let an application's guide and an
1574
+ * engine page split the same text differently, and the difference would surface as a portal whose
1575
+ * two halves summarize themselves by two conventions.
1576
+ */
1577
+ export function parseTechnicalDocumentationUnitMarkdown(markdown, unitRef) {
1578
+ return parseEngineMarkdown(markdown, unitRef);
1579
+ }
1571
1580
  function parseEngineMarkdown(markdown, unitRef) {
1572
1581
  const lines = markdown.trim().split('\n');
1573
1582
  const titleLine = lines.shift();
@@ -1948,9 +1957,10 @@ export function projectEngineApplicationConsumerContentBundle(bundle, engineSpec
1948
1957
  *
1949
1958
  * So these units are projected whole, from the same domain fact the overview page uses. They are
1950
1959
  * still ENGINE units, and deliberately: the engine owns the page's shape, its sections and its
1951
- * words, while the application supplies only the subject. That is what keeps `pathForUnit`'s
1952
- * refusal of application-owned units intact — nothing here asks it to route a unit an
1953
- * application named.
1960
+ * words, while the application supplies only the subject. The pages whose WORDS an application
1961
+ * owns are its authored chapters, which enter through their own reserved namespace
1962
+ * (`application-documentation-chapters.ts`, #874) — not through here — so `pathForUnit` still
1963
+ * refuses any unit whose ref an application chose freely.
1954
1964
  */
1955
1965
  const generatedResourceUnits = (applicationFacts.domain?.resourcePages ?? []).map((page) => {
1956
1966
  const unitRef = applicationDomainResourcePageUnitRef(page.resourceIdentifier);